Refactored out the "menu", on preparation for submenus
This commit is contained in:
parent
a26bfb3639
commit
ddcec4cb68
352
src/dorkbox/systemTray/Menu.java
Normal file
352
src/dorkbox/systemTray/Menu.java
Normal file
|
@ -0,0 +1,352 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2014 dorkbox, llc
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package dorkbox.systemTray;
|
||||||
|
|
||||||
|
import static dorkbox.systemTray.SystemTray.TIMEOUT;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import dorkbox.systemTray.util.ImageUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a cross-platform menu that is displayed by the tray-icon or as a sub-menu
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"WeakerAccess", "unused"})
|
||||||
|
public
|
||||||
|
class Menu {
|
||||||
|
protected final java.util.List<MenuEntry> menuEntries = new ArrayList<MenuEntry>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a spacer to the dropdown menu. When menu entries are removed, any menu spacer that ends up at the top/bottom of the drop-down
|
||||||
|
* menu, will also be removed. For example:
|
||||||
|
*
|
||||||
|
* Original Entry3 deleted Result
|
||||||
|
*
|
||||||
|
* <Status> <Status> <Status>
|
||||||
|
* Entry1 Entry1 Entry1
|
||||||
|
* Entry2 -> Entry2 -> Entry2
|
||||||
|
* <Spacer> (deleted)
|
||||||
|
* Entry3 (deleted)
|
||||||
|
*/
|
||||||
|
public
|
||||||
|
void addMenuSpacer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Will add a new menu entry, or update one if it already exists
|
||||||
|
*/
|
||||||
|
protected
|
||||||
|
void addMenuEntry_(final String menuText, final File imagePath, final SystemTrayMenuAction callback) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Necessary to guarantee all updates occur on the dispatch thread
|
||||||
|
*/
|
||||||
|
protected
|
||||||
|
void dispatch(Runnable runnable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the menu entry for a specified text
|
||||||
|
*
|
||||||
|
* @param menuText the menu entry text to use to find the menu entry. The first result found is returned
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
MenuEntry getMenuEntry(final String menuText) {
|
||||||
|
if (menuText == null || menuText.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be wrapped in a synchronized block for object visibility
|
||||||
|
synchronized (menuEntries) {
|
||||||
|
for (MenuEntry entry : menuEntries) {
|
||||||
|
String text = entry.getText();
|
||||||
|
|
||||||
|
// text can be null
|
||||||
|
if (menuText.equals(text)) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first menu entry, ignoring status and spacers
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
MenuEntry getFirstMenuEntry() {
|
||||||
|
return getMenuEntry(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last menu entry, ignoring status and spacers
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
MenuEntry getLastMenuEntry() {
|
||||||
|
// Must be wrapped in a synchronized block for object visibility
|
||||||
|
synchronized (menuEntries) {
|
||||||
|
if (!menuEntries.isEmpty()) {
|
||||||
|
MenuEntry menuEntry = null;
|
||||||
|
for (int i = 0, menuEntriesSize = menuEntries.size(); i < menuEntriesSize; i++) {
|
||||||
|
menuEntry = menuEntries.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(menuEntry instanceof MenuSpacer || menuEntry instanceof MenuStatus)) {
|
||||||
|
return menuEntry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the menu entry for a specified index (zero-index), ignoring status and spacers
|
||||||
|
*
|
||||||
|
* @param menuIndex the menu entry index to use to retrieve the menu entry.
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
MenuEntry getMenuEntry(final int menuIndex) {
|
||||||
|
if (menuIndex < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be wrapped in a synchronized block for object visibility
|
||||||
|
synchronized (menuEntries) {
|
||||||
|
if (!menuEntries.isEmpty()) {
|
||||||
|
int count = 0;
|
||||||
|
for (MenuEntry menuEntry : menuEntries) {
|
||||||
|
if (menuEntry instanceof MenuSpacer || menuEntry instanceof MenuStatus) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == menuIndex) {
|
||||||
|
return menuEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a menu entry to the tray icon with text (no image)
|
||||||
|
*
|
||||||
|
* @param menuText string of the text you want to appear
|
||||||
|
* @param callback callback that will be executed when this menu entry is clicked
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
void addMenuEntry(String menuText, SystemTrayMenuAction callback) {
|
||||||
|
addMenuEntry(menuText, (String) null, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a menu entry to the tray icon with text + image
|
||||||
|
*
|
||||||
|
* @param menuText string of the text you want to appear
|
||||||
|
* @param imagePath the image (full path required) to use. If null, no image will be used
|
||||||
|
* @param callback callback that will be executed when this menu entry is clicked
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
void addMenuEntry(String menuText, String imagePath, SystemTrayMenuAction callback) {
|
||||||
|
if (imagePath == null) {
|
||||||
|
addMenuEntry_(menuText, null, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath), callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a menu entry to the tray icon with text + image
|
||||||
|
*
|
||||||
|
* @param menuText string of the text you want to appear
|
||||||
|
* @param imageUrl the URL of the image to use. If null, no image will be used
|
||||||
|
* @param callback callback that will be executed when this menu entry is clicked
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
void addMenuEntry(String menuText, URL imageUrl, SystemTrayMenuAction callback) {
|
||||||
|
if (imageUrl == null) {
|
||||||
|
addMenuEntry_(menuText, null, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a menu entry to the tray icon with text + image
|
||||||
|
*
|
||||||
|
* @param menuText string of the text you want to appear
|
||||||
|
* @param cacheName @param cacheName the name to use for lookup in the cache for the imageStream
|
||||||
|
* @param imageStream the InputStream of the image to use. If null, no image will be used
|
||||||
|
* @param callback callback that will be executed when this menu entry is clicked
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
void addMenuEntry(String menuText, String cacheName, InputStream imageStream, SystemTrayMenuAction callback) {
|
||||||
|
if (imageStream == null) {
|
||||||
|
addMenuEntry_(menuText, null, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, cacheName, imageStream), callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a menu entry to the tray icon with text + image
|
||||||
|
*
|
||||||
|
* @param menuText string of the text you want to appear
|
||||||
|
* @param imageStream the InputStream of the image to use. If null, no image will be used
|
||||||
|
* @param callback callback that will be executed when this menu entry is clicked
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
void addMenuEntry(String menuText, InputStream imageStream, SystemTrayMenuAction callback) {
|
||||||
|
if (imageStream == null) {
|
||||||
|
addMenuEntry_(menuText, null, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream), callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This removes a menu entry from the dropdown menu.
|
||||||
|
*
|
||||||
|
* @param menuEntry This is the menu entry to remove
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
void removeMenuEntry(final MenuEntry menuEntry) {
|
||||||
|
if (menuEntry == null) {
|
||||||
|
throw new NullPointerException("No menu entry exists for menuEntry");
|
||||||
|
}
|
||||||
|
|
||||||
|
// have to wait for the value
|
||||||
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
dispatch(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public
|
||||||
|
void run() {
|
||||||
|
try {
|
||||||
|
synchronized (menuEntries) {
|
||||||
|
for (Iterator<MenuEntry> iterator = menuEntries.iterator(); iterator.hasNext(); ) {
|
||||||
|
final MenuEntry entry = iterator.next();
|
||||||
|
if (entry == menuEntry) {
|
||||||
|
iterator.remove();
|
||||||
|
|
||||||
|
// this will also reset the menu
|
||||||
|
menuEntry.remove();
|
||||||
|
hasValue.set(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now check to see if a spacer is at the top/bottom of the list (and remove it if so. This is a recursive function.
|
||||||
|
if (!menuEntries.isEmpty()) {
|
||||||
|
if (menuEntries.get(0) instanceof MenuSpacer) {
|
||||||
|
removeMenuEntry(menuEntries.get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now check to see if a spacer is at the top/bottom of the list (and remove it if so. This is a recursive function.
|
||||||
|
if (!menuEntries.isEmpty()) {
|
||||||
|
if (menuEntries.get(menuEntries.size()-1) instanceof MenuSpacer) {
|
||||||
|
removeMenuEntry(menuEntries.get(menuEntries.size()-1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
SystemTray.logger.error("Error removing menu entry from list.", e);
|
||||||
|
} finally {
|
||||||
|
countDownLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
||||||
|
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
||||||
|
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
SystemTray.logger.error("Error removing menu entry: {}", menuEntry.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("Menu entry '" + menuEntry.getText() + "'not found in list while trying to remove it.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This removes a menu entry (via the text label) from the dropdown menu.
|
||||||
|
*
|
||||||
|
* @param menuText This is the label for the menu entry to remove
|
||||||
|
*/
|
||||||
|
public final
|
||||||
|
void removeMenuEntry(final String menuText) {
|
||||||
|
// have to wait for the value
|
||||||
|
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
||||||
|
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
||||||
|
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
||||||
|
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
SystemTray.logger.error("Error removing menu entry: {}", menuText);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValue.get()) {
|
||||||
|
throw new NullPointerException("No menu entry exists for string '" + menuText + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,11 +24,6 @@ import java.io.FileReader;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -55,7 +50,7 @@ import dorkbox.util.process.ShellProcessBuilder;
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"unused", "Duplicates", "DanglingJavadoc", "WeakerAccess"})
|
@SuppressWarnings({"unused", "Duplicates", "DanglingJavadoc", "WeakerAccess"})
|
||||||
public abstract
|
public abstract
|
||||||
class SystemTray {
|
class SystemTray extends Menu {
|
||||||
public static final Logger logger = LoggerFactory.getLogger(SystemTray.class);
|
public static final Logger logger = LoggerFactory.getLogger(SystemTray.class);
|
||||||
|
|
||||||
public static final int TYPE_AUTO_DETECT = 0;
|
public static final int TYPE_AUTO_DETECT = 0;
|
||||||
|
@ -681,39 +676,11 @@ class SystemTray {
|
||||||
return systemTray;
|
return systemTray;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected final java.util.List<MenuEntry> menuEntries = new ArrayList<MenuEntry>();
|
|
||||||
|
|
||||||
protected
|
protected
|
||||||
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
|
|
||||||
*/
|
|
||||||
protected
|
|
||||||
MenuEntry getMenuEntry(final String menuText) {
|
|
||||||
if (menuText == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MenuEntry entry : menuEntries) {
|
|
||||||
String text = entry.getText();
|
|
||||||
|
|
||||||
// text can be null
|
|
||||||
if (menuText.equals(text)) {
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract
|
public abstract
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
@ -787,511 +754,5 @@ class SystemTray {
|
||||||
void setIcon(InputStream imageStream) {
|
void setIcon(InputStream imageStream) {
|
||||||
setIcon_(ImageUtils.resizeAndCache(ImageUtils.TRAY_SIZE, imageStream));
|
setIcon_(ImageUtils.resizeAndCache(ImageUtils.TRAY_SIZE, imageStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a menu entry to the tray icon with text (no image)
|
|
||||||
*
|
|
||||||
* @param menuText string of the text you want to appear
|
|
||||||
* @param callback callback that will be executed when this menu entry is clicked
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void addMenuEntry(String menuText, SystemTrayMenuAction callback) {
|
|
||||||
addMenuEntry(menuText, (String) null, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a menu entry to the tray icon with text + image
|
|
||||||
*
|
|
||||||
* @param menuText string of the text you want to appear
|
|
||||||
* @param imagePath the image (full path required) to use. If null, no image will be used
|
|
||||||
* @param callback callback that will be executed when this menu entry is clicked
|
|
||||||
*/
|
|
||||||
public abstract
|
|
||||||
void addMenuEntry(String menuText, String imagePath, SystemTrayMenuAction callback);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a menu entry to the tray icon with text + image
|
|
||||||
*
|
|
||||||
* @param menuText string of the text you want to appear
|
|
||||||
* @param imageUrl the URL of the image to use. If null, no image will be used
|
|
||||||
* @param callback callback that will be executed when this menu entry is clicked
|
|
||||||
*/
|
|
||||||
public abstract
|
|
||||||
void addMenuEntry(String menuText, URL imageUrl, SystemTrayMenuAction callback);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a menu entry to the tray icon with text + image
|
|
||||||
*
|
|
||||||
* @param menuText string of the text you want to appear
|
|
||||||
* @param cacheName @param cacheName the name to use for lookup in the cache for the imageStream
|
|
||||||
* @param imageStream the InputStream of the image to use. If null, no image will be used
|
|
||||||
* @param callback callback that will be executed when this menu entry is clicked
|
|
||||||
*/
|
|
||||||
public abstract
|
|
||||||
void addMenuEntry(String menuText, String cacheName, InputStream imageStream, SystemTrayMenuAction callback);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a menu entry to the tray icon with text + image
|
|
||||||
*
|
|
||||||
* @param menuText string of the text you want to appear
|
|
||||||
* @param imageStream the InputStream of the image to use. If null, no image will be used
|
|
||||||
* @param callback callback that will be executed when this menu entry is clicked
|
|
||||||
*/
|
|
||||||
public abstract
|
|
||||||
void addMenuEntry(String menuText, InputStream imageStream, SystemTrayMenuAction callback);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates (or changes) the menu entry's text.
|
|
||||||
*
|
|
||||||
* @param origMenuText the original menu text
|
|
||||||
* @param newMenuText the new menu text (this will replace the original menu text)
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void updateMenuEntry(final String origMenuText, final String newMenuText) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
|
||||||
|
|
||||||
if (menuEntry == null) {
|
|
||||||
hasValue.set(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuEntry.setText(newMenuText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error updating menu entry: {}, with text {}", origMenuText, newMenuText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates (or changes) the menu entry's image (as a String).
|
|
||||||
*
|
|
||||||
* @param origMenuText the original menu text
|
|
||||||
* @param imagePath the new path for the image to use or null to delete the image
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void updateMenuEntry_AsImage(final String origMenuText, final String imagePath) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
|
||||||
|
|
||||||
if (menuEntry == null) {
|
|
||||||
hasValue.set(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuEntry.setImage(imagePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error updating menu entry: {}, with image {}", origMenuText, imagePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates (or changes) the menu entry's text.
|
|
||||||
*
|
|
||||||
* @param origMenuText the original menu text
|
|
||||||
* @param imageUrl the new URL for the image to use or null to delete the image
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void updateMenuEntry(final String origMenuText, final URL imageUrl) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
|
||||||
|
|
||||||
if (menuEntry == null) {
|
|
||||||
hasValue.set(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuEntry.setImage(imageUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error updating menu entry: {}, with image URL {}", origMenuText, imageUrl.getPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates (or changes) the menu entry's text.
|
|
||||||
*
|
|
||||||
* @param cacheName the name to use for lookup in the cache for the imageStream
|
|
||||||
* @param imageStream the InputStream of the image to use or null to delete the image
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void updateMenuEntry(final String origMenuText, final String cacheName, final InputStream imageStream) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
|
||||||
|
|
||||||
if (menuEntry == null) {
|
|
||||||
hasValue.set(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuEntry.setImage(cacheName, imageStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error updating menu entry: {}, with image stream (named) {}", origMenuText, cacheName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates (or changes) the menu entry's text.
|
|
||||||
*
|
|
||||||
* @param origMenuText the original menu text
|
|
||||||
* @param imageStream the new path for the image to use or null to delete the image
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void updateMenuEntry(final String origMenuText, final InputStream imageStream) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
|
||||||
|
|
||||||
if (menuEntry == null) {
|
|
||||||
hasValue.set(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuEntry.setImage(imageStream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error updating menu entry: {}, with iamgeStream {}", origMenuText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates (or changes) the menu entry's callback.
|
|
||||||
*
|
|
||||||
* @param origMenuText the original menu text
|
|
||||||
* @param newCallback the new callback (this will replace the original callback)
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void updateMenuEntry(final String origMenuText, final SystemTrayMenuAction newCallback) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
|
||||||
|
|
||||||
if (menuEntry == null) {
|
|
||||||
hasValue.set(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuEntry.setCallback(newCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error updating menu entry: {}, with new callback", origMenuText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates (or changes) the menu entry's text and callback. This effectively replaces the menu entry with a new one.
|
|
||||||
*
|
|
||||||
* @param origMenuText the original menu text
|
|
||||||
* @param newMenuText the new menu text (this will replace the original menu text)
|
|
||||||
* @param newCallback the new callback (this will replace the original callback)
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void updateMenuEntry(final String origMenuText, final String newMenuText, final SystemTrayMenuAction newCallback) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
MenuEntry menuEntry = getMenuEntry(origMenuText);
|
|
||||||
|
|
||||||
if (menuEntry == null) {
|
|
||||||
hasValue.set(false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
menuEntry.setText(newMenuText);
|
|
||||||
menuEntry.setCallback(newCallback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error updating menu entry: {}, with text and callback {}", origMenuText, newMenuText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + origMenuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This removes a menu entry from the dropdown menu.
|
|
||||||
*
|
|
||||||
* @param menuEntry This is the menu entry to remove
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void removeMenuEntry(final MenuEntry menuEntry) {
|
|
||||||
if (menuEntry == null) {
|
|
||||||
throw new NullPointerException("No menu entry exists for menuEntry");
|
|
||||||
}
|
|
||||||
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
dispatch(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void run() {
|
|
||||||
try {
|
|
||||||
synchronized (menuEntries) {
|
|
||||||
for (Iterator<MenuEntry> iterator = menuEntries.iterator(); iterator.hasNext(); ) {
|
|
||||||
final MenuEntry entry = iterator.next();
|
|
||||||
if (entry == menuEntry) {
|
|
||||||
iterator.remove();
|
|
||||||
|
|
||||||
// this will also reset the menu
|
|
||||||
menuEntry.remove();
|
|
||||||
hasValue.set(true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// now check to see if a spacer is at the top/bottom of the list (and remove it if so. This is a recursive function.
|
|
||||||
if (!menuEntries.isEmpty()) {
|
|
||||||
if (menuEntries.get(0) instanceof MenuSpacer) {
|
|
||||||
removeMenuEntry(menuEntries.get(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// now check to see if a spacer is at the top/bottom of the list (and remove it if so. This is a recursive function.
|
|
||||||
if (!menuEntries.isEmpty()) {
|
|
||||||
if (menuEntries.get(menuEntries.size()-1) instanceof MenuSpacer) {
|
|
||||||
removeMenuEntry(menuEntries.get(menuEntries.size()-1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error("Error removing menu entry from list.", e);
|
|
||||||
} finally {
|
|
||||||
countDownLatch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error removing menu entry: {}", menuEntry.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("Menu entry '" + menuEntry.getText() + "'not found in list while trying to remove it.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This removes a menu entry (via the text label) from the dropdown menu.
|
|
||||||
*
|
|
||||||
* @param menuText This is the label for the menu entry to remove
|
|
||||||
*/
|
|
||||||
public final
|
|
||||||
void removeMenuEntry(final String menuText) {
|
|
||||||
// have to wait for the value
|
|
||||||
final CountDownLatch countDownLatch = new CountDownLatch(1);
|
|
||||||
final AtomicBoolean hasValue = new AtomicBoolean(true);
|
|
||||||
|
|
||||||
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 {
|
|
||||||
if (!countDownLatch.await(TIMEOUT, TimeUnit.SECONDS)) {
|
|
||||||
throw new RuntimeException("Event dispatch queue took longer than " + TIMEOUT + " seconds to complete. Please adjust " +
|
|
||||||
"`SystemTray.TIMEOUT` to a value which better suites your environment.");
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
logger.error("Error removing menu entry: {}", menuText);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasValue.get()) {
|
|
||||||
throw new NullPointerException("No menu entry exists for string '" + menuText + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a spacer to the dropdown menu. When menu entries are removed, any menu spacer that ends up at the top/bottom of the drop-down
|
|
||||||
* menu, will also be removed. For example:
|
|
||||||
*
|
|
||||||
* Original Entry3 deleted Result
|
|
||||||
*
|
|
||||||
* <Status> <Status> <Status>
|
|
||||||
* Entry1 Entry1 Entry1
|
|
||||||
* Entry2 -> Entry2 -> Entry2
|
|
||||||
* <Spacer> (deleted)
|
|
||||||
* Entry3 (deleted)
|
|
||||||
*/
|
|
||||||
public abstract
|
|
||||||
void addMenuSpacer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,8 +17,6 @@
|
||||||
package dorkbox.systemTray.linux;
|
package dorkbox.systemTray.linux;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
@ -28,7 +26,6 @@ import dorkbox.systemTray.SystemTray;
|
||||||
import dorkbox.systemTray.SystemTrayMenuAction;
|
import dorkbox.systemTray.SystemTrayMenuAction;
|
||||||
import dorkbox.systemTray.linux.jna.Gobject;
|
import dorkbox.systemTray.linux.jna.Gobject;
|
||||||
import dorkbox.systemTray.linux.jna.Gtk;
|
import dorkbox.systemTray.linux.jna.Gtk;
|
||||||
import dorkbox.systemTray.util.ImageUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Derived from
|
* Derived from
|
||||||
|
@ -222,7 +219,7 @@ class GtkTypeSystemTray extends SystemTray {
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private
|
protected
|
||||||
void addMenuEntry_(final String menuText, final File imagePath, final SystemTrayMenuAction callback) {
|
void addMenuEntry_(final String menuText, final File imagePath, final SystemTrayMenuAction callback) {
|
||||||
// some implementations of appindicator, do NOT like having a menu added, which has no menu items yet.
|
// some implementations of appindicator, do NOT like having a menu added, which has no menu items yet.
|
||||||
// see: https://bugs.launchpad.net/glipper/+bug/1203888
|
// see: https://bugs.launchpad.net/glipper/+bug/1203888
|
||||||
|
@ -251,48 +248,4 @@ class GtkTypeSystemTray extends SystemTray {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(String menuText, final String imagePath, final SystemTrayMenuAction callback) {
|
|
||||||
if (imagePath == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(final String menuText, final URL imageUrl, final SystemTrayMenuAction callback) {
|
|
||||||
if (imageUrl == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(final String menuText, final String cacheName, final InputStream imageStream, final SystemTrayMenuAction callback) {
|
|
||||||
if (imageStream == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, cacheName, imageStream), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(final String menuText, final InputStream imageStream, final SystemTrayMenuAction callback) {
|
|
||||||
if (imageStream == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,6 @@ import java.awt.TrayIcon;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
|
@ -265,7 +263,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
|
||||||
/**
|
/**
|
||||||
* Will add a new menu entry, or update one if it already exists
|
* Will add a new menu entry, or update one if it already exists
|
||||||
*/
|
*/
|
||||||
private
|
protected
|
||||||
void addMenuEntry_(final String menuText, final File imagePath, final SystemTrayMenuAction callback) {
|
void addMenuEntry_(final String menuText, final File imagePath, final SystemTrayMenuAction callback) {
|
||||||
if (menuText == null) {
|
if (menuText == null) {
|
||||||
throw new NullPointerException("Menu text cannot be null");
|
throw new NullPointerException("Menu text cannot be null");
|
||||||
|
@ -292,48 +290,4 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(String menuText, final String imagePath, final SystemTrayMenuAction callback) {
|
|
||||||
if (imagePath == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imagePath), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(final String menuText, final URL imageUrl, final SystemTrayMenuAction callback) {
|
|
||||||
if (imageUrl == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(final String menuText, final String cacheName, final InputStream imageStream, final SystemTrayMenuAction callback) {
|
|
||||||
if (imageStream == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, cacheName, imageStream), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public
|
|
||||||
void addMenuEntry(final String menuText, final InputStream imageStream, final SystemTrayMenuAction callback) {
|
|
||||||
if (imageStream == null) {
|
|
||||||
addMenuEntry_(menuText, null, callback);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageStream), callback);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user