diff options
Diffstat (limited to 'libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java')
| -rw-r--r-- | libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java index f5217be1ff6..3451224beeb 100644 --- a/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java +++ b/libjava/classpath/javax/swing/plaf/basic/BasicLookAndFeel.java @@ -38,15 +38,24 @@ exception statement from your version. */ package javax.swing.plaf.basic; +import java.awt.AWTEvent; import java.awt.Color; +import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; import java.awt.Font; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; import java.awt.event.ActionEvent; +import java.awt.event.MouseEvent; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.util.Enumeration; +import java.util.Iterator; import java.util.ResourceBundle; +import java.util.Set; +import java.util.WeakHashMap; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; @@ -57,8 +66,11 @@ import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.BorderFactory; +import javax.swing.JPopupMenu; import javax.swing.KeyStroke; import javax.swing.LookAndFeel; +import javax.swing.MenuSelectionManager; +import javax.swing.SwingUtilities; import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.border.BevelBorder; @@ -77,6 +89,96 @@ import javax.swing.plaf.InsetsUIResource; public abstract class BasicLookAndFeel extends LookAndFeel implements Serializable { + + /** + * Helps closing menu popups when the user clicks outside of any menu area. + * This is implemented as an AWTEventListener that listens on the event + * queue directly, grabs all mouse events from there and finds out of they + * are targetted at a menu/submenu/menubar or not. If not, + * the MenuSelectionManager is messaged to close the currently opened menus, + * if any. + * + * @author Roman Kennke (kennke@aicas.com) + */ + private class PopupHelper implements AWTEventListener + { + + /** + * Registered popups for autoclose. + */ + private WeakHashMap autoClosePopups = new WeakHashMap(); + + /** + * Receives an event from the event queue. + * + * @param event + */ + public void eventDispatched(AWTEvent event) + { + if (event instanceof MouseEvent) + { + MouseEvent mouseEvent = (MouseEvent) event; + if (mouseEvent.getID() == MouseEvent.MOUSE_PRESSED) + mousePressed(mouseEvent); + } + } + + /** + * Handles mouse pressed events from the event queue. + * + * @param ev the mouse pressed event + */ + private void mousePressed(MouseEvent ev) + { + // Autoclose all menus managed by the MenuSelectionManager. + MenuSelectionManager m = MenuSelectionManager.defaultManager(); + Component target = ev.getComponent(); + if (target instanceof Container) + target = ((Container) target).findComponentAt(ev.getPoint()); + if (! m.isComponentPartOfCurrentMenu(target)) + m.clearSelectedPath(); + + // Handle other registered popup instances, like ComboBox popups. + autoClosePopups(ev, target); + } + + /** + * Registers Popup and its content to be autoclosed when a mouseclick + * occurs outside of the popup. + * + * @param popup the popup to be autoclosed when clicked outside + */ + void registerForAutoClose(JPopupMenu popup) + { + autoClosePopups.put(popup, null); + } + + /** + * Automatically closes all popups that are not 'hit' by the mouse event. + * + * @param ev the mouse event + * @param target the target of the mouse event + */ + private void autoClosePopups(MouseEvent ev, Component target) + { + if (autoClosePopups.size() != 0) + { + Set popups = autoClosePopups.keySet(); + Iterator i = popups.iterator(); + while (i.hasNext()) + { + JPopupMenu popup = (JPopupMenu) i.next(); + if (!(target == popup + || SwingUtilities.isDescendingFrom(target, popup))) + { + popup.setVisible(false); + i.remove(); + } + } + } + } + } + /** * An action that can play an audio file. * @@ -137,6 +239,11 @@ public abstract class BasicLookAndFeel extends LookAndFeel static final long serialVersionUID = -6096995660290287879L; + /** + * Helps closing menu popups when user clicks outside of the menu area. + */ + private transient PopupHelper popupHelper; + private ActionMap audioActionMap; /** @@ -1023,6 +1130,8 @@ public abstract class BasicLookAndFeel extends LookAndFeel "SplitPane.dividerSize", new Integer(7), "SplitPane.highlight", new ColorUIResource(highLight), "SplitPane.shadow", new ColorUIResource(shadow), + "SplitPaneDivider.border", BasicBorders.getSplitPaneDividerBorder(), + "SplitPaneDivider.draggingColor", new ColorUIResource(Color.DARK_GRAY), "TabbedPane.ancestorInputMap", new UIDefaults.LazyInputMap(new Object[] { "ctrl PAGE_DOWN","navigatePageDown", "ctrl PAGE_UP", "navigatePageUp", @@ -1520,4 +1629,36 @@ public abstract class BasicLookAndFeel extends LookAndFeel } } + /** + * Initializes the Look and Feel. + */ + public void initialize() + { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + popupHelper = new PopupHelper(); + toolkit.addAWTEventListener(popupHelper, AWTEvent.MOUSE_EVENT_MASK); + } + + /** + * Uninitializes the Look and Feel. + */ + public void uninitialize() + { + Toolkit toolkit = Toolkit.getDefaultToolkit(); + toolkit.removeAWTEventListener(popupHelper); + popupHelper = null; + } + + /** + * Registers a JPopupMenu for autoclosing when a mouseclick occurs outside + * of the JPopupMenu. This must be called when the popup gets opened. The + * popup is unregistered from autoclosing as soon as it either got closed + * by this helper, or when it has been garbage collected. + * + * @param popup the popup menu to autoclose + */ + void registerForAutoClose(JPopupMenu popup) + { + popupHelper.registerForAutoClose(popup); + } } |

