diff --git a/src/dorkbox/systemTray/swing/AdjustedJMenu.java b/src/dorkbox/systemTray/swing/AdjustedJMenu.java index 74767e0..3c105d1 100644 --- a/src/dorkbox/systemTray/swing/AdjustedJMenu.java +++ b/src/dorkbox/systemTray/swing/AdjustedJMenu.java @@ -22,6 +22,13 @@ import javax.swing.JPopupMenu; import javax.swing.border.EmptyBorder; class AdjustedJMenu extends JMenu { + private final SwingSystemTrayMenuPopup mainPopup; + + public + AdjustedJMenu(final SwingSystemTrayMenuPopup mainPopup) { + this.mainPopup = mainPopup; + } + @Override public Insets getMargin() { @@ -37,4 +44,20 @@ class AdjustedJMenu extends JMenu { return margin; } + + @Override + public + void setPopupMenuVisible(final boolean visible) { + mainPopup.track(getPopupMenu(), visible); + + super.setPopupMenuVisible(visible); + } + + @Override + public + void removeNotify() { + // have to make sure that when we are removed, we remove ourself from the tracker + mainPopup.track(getPopupMenu(), false); + super.removeNotify(); + } } diff --git a/src/dorkbox/systemTray/swing/SwingMenu.java b/src/dorkbox/systemTray/swing/SwingMenu.java index 9b88568..be62bd2 100644 --- a/src/dorkbox/systemTray/swing/SwingMenu.java +++ b/src/dorkbox/systemTray/swing/SwingMenu.java @@ -56,7 +56,7 @@ class SwingMenu extends Menu implements MenuEntry { public void run() { if (parent != null) { - _native = new AdjustedJMenu(); + _native = new AdjustedJMenu((SwingSystemTrayMenuPopup)((SwingMenu) systemTray.getMenu())._native); ((SwingMenu) parent)._native.add(_native); } else { // when we are the system tray diff --git a/src/dorkbox/systemTray/swing/SwingSystemTray.java b/src/dorkbox/systemTray/swing/SwingSystemTray.java index a712f55..b12843b 100644 --- a/src/dorkbox/systemTray/swing/SwingSystemTray.java +++ b/src/dorkbox/systemTray/swing/SwingSystemTray.java @@ -54,9 +54,6 @@ class SwingSystemTray extends SwingMenu { SwingSystemTray(final dorkbox.systemTray.SystemTray systemTray) { super(systemTray, null); - // have to reassign our type... - _native = new SwingSystemTrayMenuPopup(); - ImageUtils.determineIconSize(dorkbox.systemTray.SystemTray.TYPE_SWING); SwingUtil.invokeAndWait(new Runnable() { diff --git a/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java b/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java index e35a9dc..5039f41 100644 --- a/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java +++ b/src/dorkbox/systemTray/swing/SwingSystemTrayMenuPopup.java @@ -20,6 +20,8 @@ import java.awt.MouseInfo; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; import javax.swing.JPopupMenu; import javax.swing.border.EmptyBorder; @@ -44,6 +46,8 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { protected volatile Point mouseClickLocation = null; + private final List trackedMenus = new ArrayList(4); + // protected boolean mouseStillOnMenu; // private JDialog hiddenDialog; @@ -53,10 +57,9 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { setFocusable(true); // setBorder(new BorderUIResource.EmptyBorderUIResource(0, 0, 0, 0)); // borderUI resource border type will get changed! setBorder(new EmptyBorder(1, 1, 1, 1)); + trackedMenus.add(this); this.timer = new DelayTimer("PopupMenuHider", true, new Runnable() { - - @Override public void run() { @@ -64,31 +67,41 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { @Override public void run() { - Point location = MouseInfo.getPointerInfo().getLocation(); - Point menuLocation = getLocationOnScreen(); - Dimension size = getSize(); + Point location = MouseInfo.getPointerInfo() + .getLocation(); - // is the mouse pointer still inside of the popup? - if (location.x >= menuLocation.x && location.x < menuLocation.x + size.width && - location.y >= menuLocation.y && location.y < menuLocation.y + size.height) { + // are we inside one of our tracked menus (the root menu is included) + synchronized (trackedMenus) { + for (JPopupMenu trackedMenu : trackedMenus) { + Point menuLocation = trackedMenu.getLocationOnScreen(); + Dimension size = trackedMenu.getSize(); - // restart the timer - SwingSystemTrayMenuPopup.this.timer.delay(POPUP_HIDE_DELAY); + if (location.x >= menuLocation.x && location.x < menuLocation.x + size.width && + location.y >= menuLocation.y && location.y < menuLocation.y + size.height + ) { + + // restart the timer + SwingSystemTrayMenuPopup.this.timer.delay(POPUP_HIDE_DELAY); + return; + } + } } + // has the mouse pointer moved > delta pixels from it's original location (when the tray icon was clicked)? - else if (mouseClickLocation != null && - location.x >= mouseClickLocation.x - MOVEMENT_DELTA && location.x < mouseClickLocation.x + MOVEMENT_DELTA && - location.y >= mouseClickLocation.y - MOVEMENT_DELTA && location.y < mouseClickLocation.y + MOVEMENT_DELTA) { + if (mouseClickLocation != null && + location.x >= mouseClickLocation.x - MOVEMENT_DELTA && location.x < mouseClickLocation.x + MOVEMENT_DELTA && + location.y >= mouseClickLocation.y - MOVEMENT_DELTA && location.y < mouseClickLocation.y + MOVEMENT_DELTA + ) { // restart the timer SwingSystemTrayMenuPopup.this.timer.delay(POPUP_HIDE_DELAY); + return; } - else { - // else, we hide it - setVisible(false); - } + + // else, we hide it + setVisible(false); } }); } @@ -138,4 +151,21 @@ class SwingSystemTrayMenuPopup extends JPopupMenu { // this.hiddenDialog.setVisible(makeVisible); super.setVisible(makeVisible); } + + + public + void track(final JPopupMenu menu, final boolean visible) { + if (visible) { + synchronized (trackedMenus) { + trackedMenus.add(menu); + } + } else { + synchronized (trackedMenus) { + trackedMenus.remove(menu); + } + } + + // restart the timer + SwingSystemTrayMenuPopup.this.timer.delay(POPUP_HIDE_DELAY); + } }