From 133cb9f8f837a20c69637f9e77c07943b74de97e Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 4 Jul 2017 19:09:21 +0200 Subject: [PATCH] Fixed race condition between bind() and add(), where they could both add an entry. Now entries will only be added if they have not already been added. --- src/dorkbox/systemTray/Entry.java | 8 ++++++++ src/dorkbox/systemTray/Menu.java | 12 +++++------- src/dorkbox/systemTray/swingUI/SwingMenu.java | 6 ++++++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/dorkbox/systemTray/Entry.java b/src/dorkbox/systemTray/Entry.java index ffca87d..ce58250 100644 --- a/src/dorkbox/systemTray/Entry.java +++ b/src/dorkbox/systemTray/Entry.java @@ -56,6 +56,14 @@ class Entry { // END methods for hooking into the system tray, menu's, and entries. + /** + * @return true if this entry has a peer assigned to it. + */ + public final + boolean hasPeer() { + return peer != null; + } + /** * @return the parent menu (of this entry or menu) or null if we are the root menu */ diff --git a/src/dorkbox/systemTray/Menu.java b/src/dorkbox/systemTray/Menu.java index 82b7883..1a51edf 100644 --- a/src/dorkbox/systemTray/Menu.java +++ b/src/dorkbox/systemTray/Menu.java @@ -124,7 +124,6 @@ class Menu extends MenuItem { copy = new ArrayList(menuEntries); } - for (int i = 0, menuEntriesSize = copy.size(); i < menuEntriesSize; i++) { final Entry menuEntry = copy.get(i); peer.add(this, menuEntry, i); @@ -145,7 +144,6 @@ class Menu extends MenuItem { @SuppressWarnings("Duplicates") public final Menu add(final JMenu entry) { - Menu menu = new Menu(); menu.setEnabled(entry.isEnabled()); @@ -267,7 +265,7 @@ class Menu extends MenuItem { * Adds a menu entry, separator, or sub-menu to this menu. */ public - T add(final T entry, int index) { + T add(final T entry, int index) { synchronized (menuEntries) { // access on this object must be synchronized for object visibility if (index == -1) { @@ -279,10 +277,10 @@ class Menu extends MenuItem { } menuEntries.add(index, entry); } - } - if (peer != null) { - ((MenuPeer) peer).add(this, entry, index); + if (peer != null) { + ((MenuPeer) peer).add(this, entry, index); + } } return entry; @@ -351,7 +349,7 @@ class Menu extends MenuItem { } /** - * This removes a menu entry from the dropdown menu. + * This removes a menu entry from the menu. * * @param entry This is the menu entry to remove */ diff --git a/src/dorkbox/systemTray/swingUI/SwingMenu.java b/src/dorkbox/systemTray/swingUI/SwingMenu.java index c51e9aa..a234ec0 100644 --- a/src/dorkbox/systemTray/swingUI/SwingMenu.java +++ b/src/dorkbox/systemTray/swingUI/SwingMenu.java @@ -73,6 +73,12 @@ class SwingMenu implements MenuPeer { @Override public void run() { + // don't add this entry if it's already been added via another method. Because of threading via swing/gtk, entries can + // POSSIBLY get added twice. Once via add() and once via bind(). + if (entry.hasPeer()) { + return; + } + if (entry instanceof Menu) { SwingMenu swingMenu = new SwingMenu(SwingMenu.this, (Menu) entry); ((Menu) entry).bind(swingMenu, parentMenu, parentMenu.getSystemTray());