3 import jalview.jbgui.GSplitFrame;
5 import java.awt.Component;
6 import java.awt.MouseInfo;
8 import java.awt.Rectangle;
9 import java.awt.event.ActionEvent;
10 import java.awt.event.ActionListener;
11 import java.awt.event.KeyAdapter;
12 import java.awt.event.KeyEvent;
13 import java.awt.event.KeyListener;
14 import java.util.Map.Entry;
16 import javax.swing.AbstractAction;
17 import javax.swing.JComponent;
18 import javax.swing.JMenuItem;
19 import javax.swing.KeyStroke;
20 import javax.swing.event.InternalFrameAdapter;
21 import javax.swing.event.InternalFrameEvent;
23 public class SplitFrame extends GSplitFrame
25 private static final long serialVersionUID = 1L;
27 public SplitFrame(JComponent top, JComponent bottom)
34 * Initialise this frame.
38 setSize(AlignFrame.DEFAULT_WIDTH, Desktop.instance.getHeight() - 20);
40 addCloseFrameListener();
49 * Add a listener to tidy up when the frame is closed.
51 protected void addCloseFrameListener()
53 addInternalFrameListener(new InternalFrameAdapter()
56 public void internalFrameClosed(InternalFrameEvent evt)
58 if (getTopComponent() instanceof AlignFrame)
60 ((AlignFrame) getTopComponent())
61 .closeMenuItem_actionPerformed(true);
63 if (getBottomComponent() instanceof AlignFrame)
65 ((AlignFrame) getBottomComponent())
66 .closeMenuItem_actionPerformed(true);
73 * Add a key listener that delegates to whichever split component the mouse is
74 * in (or does nothing if neither).
76 protected void addKeyListener()
78 // TODO Key Bindings rather than KeyListener are recommended for Swing
79 addKeyListener(new KeyAdapter() {
82 public void keyPressed(KeyEvent e)
84 Component c = getComponentAtMouse();
87 for (KeyListener kl : c.getKeyListeners())
95 public void keyReleased(KeyEvent e)
97 Component c = getComponentAtMouse();
100 for (KeyListener kl : c.getKeyListeners())
111 * Returns the split pane component the mouse is in, or null if neither.
115 protected Component getComponentAtMouse()
117 Point loc = MouseInfo.getPointerInfo().getLocation();
119 if (isIn(loc, getTopComponent())) {
120 return getTopComponent();
122 else if (isIn(loc, getBottomComponent()))
124 return getBottomComponent();
129 private boolean isIn(Point loc, JComponent comp)
131 Point p = comp.getLocationOnScreen();
132 Rectangle r = new Rectangle(p.x, p.y, comp.getWidth(), comp.getHeight());
133 return r.contains(loc);
137 * Set key bindings (recommended for Swing over key accelerators). For now,
138 * delegate to the corresponding key accelerator for the AlignFrame that the
139 * mouse is in. Hopefully can be simplified in future if AlignFrame is changed
140 * to use key bindings rather than accelerators.
142 private void addKeyBindings()
144 if (getTopComponent() instanceof AlignFrame)
146 for (Entry<KeyStroke, JMenuItem> acc : ((AlignFrame) getTopComponent())
147 .getAccelerators().entrySet())
150 final KeyStroke ks = acc.getKey();
151 this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, ks);
152 this.getActionMap().put(ks, new AbstractAction()
155 public void actionPerformed(ActionEvent e)
157 Component c = getComponentAtMouse();
158 if (c instanceof AlignFrame)
160 for (ActionListener a : ((AlignFrame) c).getAccelerators()
161 .get(ks).getActionListeners())
164 a.actionPerformed(null);
171 * Disable unwanted here
173 // X expand views - wrecks the split pane view
174 KeyStroke key_X = KeyStroke.getKeyStroke(KeyEvent.VK_X, 0, false);
175 disableAccelerator(key_X);
180 * Ugly hack for Proof of Concept that disables the key binding in this frame
181 * _and_ disables the bound menu item _and_ removes the key accelerator in the
186 protected void disableAccelerator(KeyStroke key)
188 disableAccelerator(key, getTopComponent());
189 disableAccelerator(key, getBottomComponent());
190 this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).remove(key);
194 * Disable the menu item for which this key is the accelerator, also removes
195 * its action listeners to prevent key accelerator working.
200 private void disableAccelerator(KeyStroke key, JComponent comp)
202 // HACKED ONLY FOR PROOF OF CONCEPT
203 // Proper solution might involve explicit 'configure menu' method on
205 // changing key listeners to key bindings in AlignFrame, or both
206 if (comp instanceof AlignFrame)
208 JMenuItem mi = ((AlignFrame) comp).getAccelerators().get(key);
211 mi.setEnabled(false);
212 for (ActionListener al : mi.getActionListeners())
214 mi.removeActionListener(al);