Abstracted 'dispatch(Runnable)' so that all updates to the SystemTray
occur on the dispatch thread. This will resolve any race condition issues when creating, then (before it's actually created) trying to modify a menu entry.
This commit is contained in:
parent
077aca538c
commit
6fdbe8ac83
|
@ -41,6 +41,9 @@ import java.net.URL;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -430,6 +433,11 @@ class SystemTray {
|
||||||
SystemTray() {
|
SystemTray() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Necessary to guarantee all updates occur on the dispatch thread
|
||||||
|
*/
|
||||||
|
protected abstract
|
||||||
|
void dispatch(Runnable runnable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be wrapped in a synchronized block for object visibility
|
* Must be wrapped in a synchronized block for object visibility
|
||||||
|
@ -593,16 +601,37 @@ class SystemTray {
|
||||||
* @param newMenuText the new menu text (this will replace the original menu text)
|
* @param newMenuText the new menu text (this will replace the original menu text)
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
void updateMenuEntry_Text(String origMenuText, String newMenuText) {
|
void updateMenuEntry_Text(final String origMenuText, final String newMenuText) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry == null) {
|
dispatch(new Runnable() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
@Override
|
||||||
}
|
public
|
||||||
else {
|
void run() {
|
||||||
menuEntry.setText(newMenuText);
|
synchronized (menuEntries) {
|
||||||
|
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menuEntry.setText(newMenuText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,16 +642,37 @@ class SystemTray {
|
||||||
* @param imagePath the new path for the image to use or null to delete the image
|
* @param imagePath the new path for the image to use or null to delete the image
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
void updateMenuEntry_Image(String origMenuText, String imagePath) {
|
void updateMenuEntry_Image(final String origMenuText, final String imagePath) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry == null) {
|
dispatch(new Runnable() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
@Override
|
||||||
}
|
public
|
||||||
else {
|
void run() {
|
||||||
menuEntry.setImage(imagePath);
|
synchronized (menuEntries) {
|
||||||
|
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menuEntry.setImage(imagePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,16 +683,38 @@ class SystemTray {
|
||||||
* @param imageUrl the new URL for the image to use or null to delete the image
|
* @param imageUrl the new URL for the image to use or null to delete the image
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
void updateMenuEntry_Image(String origMenuText, URL imageUrl) {
|
void updateMenuEntry_Image(final String origMenuText, final URL imageUrl) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry == null) {
|
dispatch(new Runnable() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
@Override
|
||||||
}
|
public
|
||||||
else {
|
void run() {
|
||||||
menuEntry.setImage(imageUrl);
|
synchronized (menuEntries) {
|
||||||
|
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menuEntry.setImage(imageUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,16 +725,37 @@ class SystemTray {
|
||||||
* @param imageStream the InputStream of the image to use or null to delete the image
|
* @param imageStream the InputStream of the image to use or null to delete the image
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
void updateMenuEntry_Image(String origMenuText, String cacheName, InputStream imageStream) {
|
void updateMenuEntry_Image(final String origMenuText, final String cacheName, final InputStream imageStream) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry == null) {
|
dispatch(new Runnable() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
@Override
|
||||||
}
|
public
|
||||||
else {
|
void run() {
|
||||||
menuEntry.setImage(cacheName, imageStream);
|
synchronized (menuEntries) {
|
||||||
|
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menuEntry.setImage(cacheName, imageStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,18 +768,39 @@ class SystemTray {
|
||||||
* @param origMenuText the original menu text
|
* @param origMenuText the original menu text
|
||||||
* @param imageStream the new path for the image to use or null to delete the image
|
* @param imageStream the new path for the image to use or null to delete the image
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public final
|
public final
|
||||||
void updateMenuEntry_Image(String origMenuText, InputStream imageStream) {
|
void updateMenuEntry_Image(final String origMenuText, final InputStream imageStream) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry == null) {
|
dispatch(new Runnable() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
@SuppressWarnings("deprecation")
|
||||||
}
|
@Override
|
||||||
else {
|
public
|
||||||
menuEntry.setImage(imageStream);
|
void run() {
|
||||||
|
synchronized (menuEntries) {
|
||||||
|
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menuEntry.setImage(imageStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,16 +811,37 @@ class SystemTray {
|
||||||
* @param newCallback the new callback (this will replace the original callback)
|
* @param newCallback the new callback (this will replace the original callback)
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
void updateMenuEntry_Callback(String origMenuText, SystemTrayMenuAction newCallback) {
|
void updateMenuEntry_Callback(final String origMenuText, final SystemTrayMenuAction newCallback) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry != null) {
|
dispatch(new Runnable() {
|
||||||
menuEntry.setCallback(newCallback);
|
@Override
|
||||||
}
|
public
|
||||||
else {
|
void run() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
synchronized (menuEntries) {
|
||||||
|
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menuEntry.setCallback(newCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,17 +854,38 @@ class SystemTray {
|
||||||
* @param newCallback the new callback (this will replace the original callback)
|
* @param newCallback the new callback (this will replace the original callback)
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
void updateMenuEntry(String origMenuText, String newMenuText, SystemTrayMenuAction newCallback) {
|
void updateMenuEntry(final String origMenuText, final String newMenuText, final SystemTrayMenuAction newCallback) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry == null) {
|
dispatch(new Runnable() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
@Override
|
||||||
}
|
public
|
||||||
else {
|
void run() {
|
||||||
menuEntry.setText(newMenuText);
|
synchronized (menuEntries) {
|
||||||
menuEntry.setCallback(newCallback);
|
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menuEntry.setText(newMenuText);
|
||||||
|
menuEntry.setCallback(newCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,20 +903,42 @@ class SystemTray {
|
||||||
|
|
||||||
final String label = menuEntry.getText();
|
final String label = menuEntry.getText();
|
||||||
|
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
for (Iterator<MenuEntry> iterator = menuEntries.iterator(); iterator.hasNext(); ) {
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
final MenuEntry entry = iterator.next();
|
final AtomicBoolean hasValue = new AtomicBoolean(false);
|
||||||
if (entry.getText()
|
|
||||||
.equals(label)) {
|
|
||||||
iterator.remove();
|
|
||||||
|
|
||||||
// this will also reset the menu
|
dispatch(new Runnable() {
|
||||||
menuEntry.remove();
|
@Override
|
||||||
return;
|
public
|
||||||
|
void run() {
|
||||||
|
synchronized (menuEntries) {
|
||||||
|
for (Iterator<MenuEntry> iterator = menuEntries.iterator(); iterator.hasNext(); ) {
|
||||||
|
final MenuEntry entry = iterator.next();
|
||||||
|
if (entry.getText()
|
||||||
|
.equals(label)) {
|
||||||
|
iterator.remove();
|
||||||
|
|
||||||
|
// this will also reset the menu
|
||||||
|
menuEntry.remove();
|
||||||
|
hasValue.set(true);
|
||||||
|
countDownLatch.countDown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("Menu entry '" + label + "'not found in list while trying to remove it.");
|
||||||
}
|
}
|
||||||
throw new NullPointerException("Menu entry '" + label + "'not found in list while trying to remove it.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -771,15 +949,42 @@ class SystemTray {
|
||||||
*/
|
*/
|
||||||
public final
|
public final
|
||||||
void removeMenuEntry(final String menuText) {
|
void removeMenuEntry(final String menuText) {
|
||||||
synchronized (menuEntries) {
|
// have to wait for the value
|
||||||
MenuEntry menuEntry = getMenuEntry(menuText);
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
if (menuEntry == null) {
|
dispatch(new Runnable() {
|
||||||
throw new NullPointerException("No menu entry exists for string '" + menuText + "'");
|
@Override
|
||||||
}
|
public
|
||||||
else {
|
void run() {
|
||||||
removeMenuEntry(menuEntry);
|
dispatch(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
void run() {
|
||||||
|
synchronized (menuEntries) {
|
||||||
|
MenuEntry menuEntry = getMenuEntry(menuText);
|
||||||
|
|
||||||
|
if (menuEntry == null) {
|
||||||
|
hasValue.set(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
removeMenuEntry(menuEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
countDownLatch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
final boolean await = countDownLatch.await(2, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + menuText + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,7 @@ class AppIndicatorTray extends GtkTypeSystemTray {
|
||||||
AppIndicatorTray() {
|
AppIndicatorTray() {
|
||||||
GtkSupport.startGui();
|
GtkSupport.startGui();
|
||||||
|
|
||||||
GtkSupport.dispatch(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
@ -57,7 +57,7 @@ class AppIndicatorTray extends GtkTypeSystemTray {
|
||||||
public
|
public
|
||||||
void shutdown() {
|
void shutdown() {
|
||||||
if (!shuttingDown.getAndSet(true)) {
|
if (!shuttingDown.getAndSet(true)) {
|
||||||
GtkSupport.dispatch(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
@ -77,7 +77,7 @@ class AppIndicatorTray extends GtkTypeSystemTray {
|
||||||
@Override
|
@Override
|
||||||
protected
|
protected
|
||||||
void setIcon_(final String iconPath) {
|
void setIcon_(final String iconPath) {
|
||||||
GtkSupport.dispatch(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
|
|
@ -48,7 +48,7 @@ class GtkSystemTray extends GtkTypeSystemTray {
|
||||||
super();
|
super();
|
||||||
GtkSupport.startGui();
|
GtkSupport.startGui();
|
||||||
|
|
||||||
GtkSupport.dispatch(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
@ -78,7 +78,7 @@ class GtkSystemTray extends GtkTypeSystemTray {
|
||||||
public
|
public
|
||||||
void shutdown() {
|
void shutdown() {
|
||||||
if (!shuttingDown.getAndSet(true)) {
|
if (!shuttingDown.getAndSet(true)) {
|
||||||
GtkSupport.dispatch(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
@ -99,7 +99,7 @@ class GtkSystemTray extends GtkTypeSystemTray {
|
||||||
@Override
|
@Override
|
||||||
protected
|
protected
|
||||||
void setIcon_(final String iconPath) {
|
void setIcon_(final String iconPath) {
|
||||||
GtkSupport.dispatch(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
|
|
@ -47,6 +47,11 @@ class GtkTypeSystemTray extends SystemTray {
|
||||||
private volatile Pointer connectionStatusItem;
|
private volatile Pointer connectionStatusItem;
|
||||||
private volatile String statusText = null;
|
private volatile String statusText = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected
|
||||||
|
void dispatch(final Runnable runnable) {
|
||||||
|
GtkSupport.dispatch(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
|
@ -221,7 +226,7 @@ class GtkTypeSystemTray extends SystemTray {
|
||||||
* Called inside the gdk_threads block
|
* Called inside the gdk_threads block
|
||||||
*/
|
*/
|
||||||
protected
|
protected
|
||||||
void onMenuAdded(final Pointer menu) {};
|
void onMenuAdded(final Pointer menu) {}
|
||||||
|
|
||||||
protected
|
protected
|
||||||
Pointer getMenu() {
|
Pointer getMenu() {
|
||||||
|
|
|
@ -98,12 +98,17 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
|
||||||
return this.statusText;
|
return this.statusText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected
|
||||||
|
void dispatch(Runnable runnable) {
|
||||||
|
SwingUtil.invokeLater(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void setStatus(final String statusText) {
|
void setStatus(final String statusText) {
|
||||||
this.statusText = statusText;
|
this.statusText = statusText;
|
||||||
|
|
||||||
SwingUtil.invokeLater(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
@ -131,7 +136,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
|
||||||
@Override
|
@Override
|
||||||
protected
|
protected
|
||||||
void setIcon_(final String iconPath) {
|
void setIcon_(final String iconPath) {
|
||||||
SwingUtil.invokeLater(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
@ -145,7 +150,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
|
||||||
Image trayImage = new ImageIcon(iconPath).getImage()
|
Image trayImage = new ImageIcon(iconPath).getImage()
|
||||||
.getScaledInstance(TRAY_SIZE, TRAY_SIZE, Image.SCALE_SMOOTH);
|
.getScaledInstance(TRAY_SIZE, TRAY_SIZE, Image.SCALE_SMOOTH);
|
||||||
trayImage.flush();
|
trayImage.flush();
|
||||||
trayIcon = new TrayIcon(trayImage);;
|
trayIcon = new TrayIcon(trayImage);
|
||||||
|
|
||||||
// appindicators don't support this, so we cater to the lowest common denominator
|
// appindicators don't support this, so we cater to the lowest common denominator
|
||||||
// trayIcon.setToolTip(SwingSystemTray.this.appName);
|
// trayIcon.setToolTip(SwingSystemTray.this.appName);
|
||||||
|
@ -215,7 +220,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
|
||||||
throw new NullPointerException("Menu text cannot be null");
|
throw new NullPointerException("Menu text cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
SwingUtil.invokeLater(new Runnable() {
|
dispatch(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user