Removed checked expections (now they are unchecked). Added better detection of JavaFX.

This commit is contained in:
nathan 2016-02-14 17:49:02 +01:00
parent 5db79ed563
commit 3507869c35
10 changed files with 236 additions and 149 deletions

View File

@ -1,6 +1,7 @@
package dorkbox.systemTray;
import dorkbox.util.LocationResolver;
import dorkbox.util.OS;
import java.io.File;
import java.io.FileOutputStream;
@ -10,7 +11,6 @@ import java.io.OutputStream;
import java.math.BigInteger;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
@ -26,8 +26,7 @@ class ImageUtil {
private static final File TEMP_DIR = new File(System.getProperty("java.io.tmpdir"));
protected static final Charset UTF_8 = Charset.forName("UTF-8");
static MessageDigest digest;
private static MessageDigest digest;
private static final Map<String, String> resourceToFilePath = new HashMap<String, String>();
private static final long runtimeRandom = new SecureRandom().nextLong();
@ -37,7 +36,7 @@ class ImageUtil {
* swing version loads as an image (which can be stream or path, we use path)
*/
public static synchronized
String iconPath(String fileName) throws IOException {
String iconPath(String fileName) {
// if we already have this fileName, reuse it
final String cachedFile = resourceToFilePath.get(fileName);
if (cachedFile != null) {
@ -66,7 +65,7 @@ class ImageUtil {
* swing version loads as an image (which can be stream or path, we use path)
*/
public static synchronized
String iconPath(final URL fileResource) throws IOException {
String iconPath(final URL fileResource) {
// if we already have this fileName, reuse it
final String cachedFile = resourceToFilePath.get(fileResource.getPath());
if (cachedFile != null) {
@ -84,7 +83,7 @@ class ImageUtil {
* swing version loads as an image (which can be stream or path, we use path)
*/
public static synchronized
String iconPath(final String cacheName, final InputStream fileStream) throws IOException {
String iconPath(final String cacheName, final InputStream fileStream) {
// if we already have this fileName, reuse it
final String cachedFile = resourceToFilePath.get(cacheName);
if (cachedFile != null) {
@ -104,7 +103,7 @@ class ImageUtil {
*/
@Deprecated
public static synchronized
String iconPathNoCache(final InputStream fileStream) throws IOException {
String iconPathNoCache(final InputStream fileStream) {
return makeFileViaStream(Long.toString(System.currentTimeMillis()), fileStream);
}
@ -114,12 +113,19 @@ class ImageUtil {
* @return the full path of the resource copied to disk, or null if invalid
*/
private static
String makeFileViaUrl(final URL resourceUrl) throws IOException {
String makeFileViaUrl(final URL resourceUrl) {
if (resourceUrl == null) {
throw new IOException("resourceUrl is null");
throw new RuntimeException("resourceUrl is null");
}
InputStream inStream = resourceUrl.openStream();
InputStream inStream;
try {
inStream = resourceUrl.openStream();
} catch (IOException e) {
String message = "Unable to open icon at '" + resourceUrl + "'";
SystemTray.logger.error(message, e);
throw new RuntimeException(message, e);
}
// suck it out of a URL/Resource (with debugging if necessary)
String cacheName = resourceUrl.getPath();
@ -133,16 +139,16 @@ class ImageUtil {
* @return the full path of the resource copied to disk, or null if invalid
*/
private static
String makeFileViaStream(final String cacheName, final InputStream resourceStream) throws IOException {
String makeFileViaStream(final String cacheName, final InputStream resourceStream) {
if (cacheName == null) {
throw new IOException("cacheName is null");
throw new RuntimeException("cacheName is null");
}
if (resourceStream == null) {
throw new IOException("resourceStream is null");
throw new RuntimeException("resourceStream is null");
}
// figure out the fileName
byte[] bytes = cacheName.getBytes(UTF_8);
byte[] bytes = cacheName.getBytes(OS.UTF_8);
File newFile;
// can be wimpy, only one at a time
@ -175,7 +181,7 @@ class ImageUtil {
// Send up exception
String message = "Unable to copy icon '" + cacheName + "' to temporary location: '" + newFile.getAbsolutePath() + "'";
SystemTray.logger.error(message, e);
throw new IOException(message);
throw new RuntimeException(message, e);
} finally {
try {
resourceStream.close();

View File

@ -16,7 +16,6 @@
package dorkbox.systemTray;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@ -42,14 +41,14 @@ interface MenuEntry {
*
* @param imagePath the full path of the image to use or null
*/
void setImage(String imagePath) throws IOException;
void setImage(String imagePath);
/**
* Specifies the new image to set for a menu entry, NULL to delete the image
*
* @param imageUrl the URL of the image to use or null
*/
void setImage(URL imageUrl) throws IOException;
void setImage(URL imageUrl);
/**
* Specifies the new image to set for a menu entry, NULL to delete the image
@ -57,7 +56,7 @@ interface MenuEntry {
* @param cacheName the name to use for lookup in the cache for the imageStream
* @param imageStream the InputStream of the image to use
*/
void setImage(String cacheName, InputStream imageStream) throws IOException;
void setImage(String cacheName, InputStream imageStream);
/**
* Specifies the new image to set for a menu entry, NULL to delete the image
@ -68,7 +67,7 @@ interface MenuEntry {
* @param imageStream the InputStream of the image to use
*/
@Deprecated
void setImage(InputStream imageStream) throws IOException;
void setImage(InputStream imageStream);
/**
* Sets a callback for a menu entry. This is the action that occurs when one clicks the menu entry

View File

@ -245,16 +245,16 @@ class SystemTray {
try {
ImageUtil.init();
if (AppIndicator.IS_VERSION_3 && GtkSupport.isGtk2) {
if (OS.isLinux() && GtkSupport.isGtk2 && AppIndicator.IS_VERSION_3) {
// NOTE:
// ALSO WHAT VERSION OF GTK to use? appindiactor1 -> GTk2, appindicator3 -> GTK3.
// appindicator3 doesn't support menu icons via GTK2. AT THIS POINT, we DO NOT have GTK3
try {
trayType = GtkSystemTray.class;
logger.warn("AppIndicator3 detected with GTK2 only, falling back to GTK2 system tray type. " +
logger.warn("AppIndicator3 detected with GTK2, falling back to GTK2 system tray type. " +
"Please install libappindicator1 OR GTK3, for example: 'sudo apt-get install libappindicator1'");
} catch (Throwable ignored) {
logger.error("AppIndicator3 detected with GTK2 only and unable to fallback to using GTK2 system tray type." +
logger.error("AppIndicator3 detected with GTK2 and unable to fallback to using GTK2 system tray type." +
"AppIndicator3 requires GTK3 to be fully functional, and while this will work -- the menu icons WILL " +
"NOT be visible." +
" Please install libappindicator1 OR GTK3, for example: 'sudo apt-get install libappindicator1'");
@ -272,30 +272,51 @@ class SystemTray {
systemTray = systemTray_;
// Necessary because javaFX **ALSO** runs a gtk main loop, and when it stops (if we don't stop first), we become unresponsive.
// If javaFX is present, but not used, this does nothing.
// com.sun.javafx.tk.Toolkit.getToolkit()
// .addShutdownHook(new Runnable() {
// @Override
// public
// void run() {
// systemTray.shutdown();
// }
// });
try {
Class<?> clazz = Class.forName("com.sun.javafx.tk.Toolkit");
Method method = clazz.getMethod("getToolkit");
Object o = method.invoke(null);
Method runnable = o.getClass()
.getMethod("addShutdownHook", Runnable.class);
runnable.invoke(o, new Runnable() {
@Override
public
void run() {
systemTray.shutdown();
// we ONLY need this on linux for compatibility with JavaFX... (windows/mac don't use gtk)
if (OS.isLinux()) {
boolean isJavaFxLoaded = false;
try {
// First check if JavaFX is loaded - if it's NOT LOADED, then we only proceed if JAVAFX_COMPATIBILITY_MODE is enabled.
// this is important, because if JavaFX is not being used, calling getToolkit() will initialize it...
java.lang.reflect.Method m = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class);
m.setAccessible(true);
ClassLoader cl = ClassLoader.getSystemClassLoader();
isJavaFxLoaded = null != m.invoke(cl, "com.sun.javafx.tk.Toolkit");
} catch (Throwable ignored) {
}
if (isJavaFxLoaded || GtkSupport.JAVAFX_COMPATIBILITY_MODE) {
// com.sun.javafx.tk.Toolkit.getToolkit()
// .addShutdownHook(new Runnable() {
// @Override
// public
// void run() {
// systemTray.shutdown();
// }
// });
try {
Class<?> clazz = Class.forName("com.sun.javafx.tk.Toolkit");
Method method = clazz.getMethod("getToolkit");
Object o = method.invoke(null);
Method runnable = o.getClass()
.getMethod("addShutdownHook", Runnable.class);
runnable.invoke(o, new Runnable() {
@Override
public
void run() {
systemTray.shutdown();
}
});
} catch (Throwable ignored) {
logger.error("Unable to insert shutdown hook into JavaFX. Please create an issue with your OS and Java " +
"configuration so we may further investigate this issue.");
}
});
} catch (Throwable ignored) {
}
}
}
}
@ -366,7 +387,7 @@ class SystemTray {
* @param imagePath the path of the icon to use
*/
public
void setIcon(String imagePath) throws IOException {
void setIcon(String imagePath) {
final String fullPath = ImageUtil.iconPath(imagePath);
setIcon_(fullPath);
}
@ -380,7 +401,7 @@ class SystemTray {
* @param imageUrl the URL of the icon to use
*/
public
void setIcon(URL imageUrl) throws IOException {
void setIcon(URL imageUrl) {
final String fullPath = ImageUtil.iconPath(imageUrl);
setIcon_(fullPath);
}
@ -395,7 +416,7 @@ class SystemTray {
* @param imageStream the InputStream of the icon to use
*/
public
void setIcon(String cacheName, InputStream imageStream) throws IOException {
void setIcon(String cacheName, InputStream imageStream) {
final String fullPath = ImageUtil.iconPath(cacheName, imageStream);
setIcon_(fullPath);
}
@ -413,7 +434,7 @@ class SystemTray {
*/
@Deprecated
public
void setIcon(InputStream imageStream) throws IOException {
void setIcon(InputStream imageStream) {
final String fullPath = ImageUtil.iconPathNoCache(imageStream);
setIcon_(fullPath);
}
@ -427,12 +448,7 @@ class SystemTray {
*/
public final
void addMenuEntry(String menuText, SystemTrayMenuAction callback) {
try {
addMenuEntry(menuText, (String) null, callback);
} catch (IOException e) {
// should never happen
e.printStackTrace();
}
addMenuEntry(menuText, (String) null, callback);
}
@ -444,7 +460,7 @@ class SystemTray {
* @param callback callback that will be executed when this menu entry is clicked
*/
public abstract
void addMenuEntry(String menuText, String imagePath, SystemTrayMenuAction callback) throws IOException;
void addMenuEntry(String menuText, String imagePath, SystemTrayMenuAction callback);
/**
* Adds a menu entry to the tray icon with text + image
@ -454,7 +470,7 @@ class SystemTray {
* @param callback callback that will be executed when this menu entry is clicked
*/
public abstract
void addMenuEntry(String menuText, URL imageUrl, SystemTrayMenuAction callback) throws IOException;
void addMenuEntry(String menuText, URL imageUrl, SystemTrayMenuAction callback);
/**
* Adds a menu entry to the tray icon with text + image
@ -465,7 +481,7 @@ class SystemTray {
* @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) throws IOException;
void addMenuEntry(String menuText, String cacheName, InputStream imageStream, SystemTrayMenuAction callback);
/**
* Adds a menu entry to the tray icon with text + image
@ -479,7 +495,7 @@ class SystemTray {
*/
@Deprecated
public abstract
void addMenuEntry(String menuText, InputStream imageStream, SystemTrayMenuAction callback) throws IOException;
void addMenuEntry(String menuText, InputStream imageStream, SystemTrayMenuAction callback);
/**
@ -509,7 +525,7 @@ class SystemTray {
* @param imagePath the new path for the image to use or null to delete the image
*/
public final
void updateMenuEntry_Image(String origMenuText, String imagePath) throws IOException {
void updateMenuEntry_Image(String origMenuText, String imagePath) {
synchronized (menuEntries) {
MenuEntry menuEntry = getMenuEntry(origMenuText);
@ -529,7 +545,7 @@ class SystemTray {
* @param imageUrl the new URL for the image to use or null to delete the image
*/
public final
void updateMenuEntry_Image(String origMenuText, URL imageUrl) throws IOException {
void updateMenuEntry_Image(String origMenuText, URL imageUrl) {
synchronized (menuEntries) {
MenuEntry menuEntry = getMenuEntry(origMenuText);
@ -549,7 +565,7 @@ class SystemTray {
* @param imageStream the InputStream of the image to use or null to delete the image
*/
public final
void updateMenuEntry_Image(String origMenuText, String cacheName, InputStream imageStream) throws IOException {
void updateMenuEntry_Image(String origMenuText, String cacheName, InputStream imageStream) {
synchronized (menuEntries) {
MenuEntry menuEntry = getMenuEntry(origMenuText);
@ -573,7 +589,7 @@ class SystemTray {
*/
@Deprecated
public final
void updateMenuEntry_Image(String origMenuText, InputStream imageStream) throws IOException {
void updateMenuEntry_Image(String origMenuText, InputStream imageStream) {
synchronized (menuEntries) {
MenuEntry menuEntry = getMenuEntry(origMenuText);

View File

@ -25,7 +25,6 @@ import dorkbox.util.jna.linux.Gobject.GCallback;
import dorkbox.util.jna.linux.Gtk;
import dorkbox.util.jna.linux.GtkSupport;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@ -33,7 +32,9 @@ class GtkMenuEntry implements MenuEntry {
private static final Gtk gtk = Gtk.INSTANCE;
private static final Gobject gobject = Gobject.INSTANCE;
@SuppressWarnings("FieldCanBeLocal")
private final GCallback gtkCallback;
final Pointer menuItem;
private final Pointer parentMenu;
final GtkTypeSystemTray systemTray;
@ -52,7 +53,7 @@ class GtkMenuEntry implements MenuEntry {
this.callback = callback;
this.systemTray = systemTray;
// have to watch out! These can get garbage collected!
// have to watch out! This can get garbage collected (so it MUST be a field)!
gtkCallback = new Gobject.GCallback() {
@Override
public
@ -140,7 +141,7 @@ class GtkMenuEntry implements MenuEntry {
@Override
public
void setImage(final String imagePath) throws IOException {
void setImage(final String imagePath) {
if (imagePath == null) {
setImage_(null);
}
@ -151,7 +152,7 @@ class GtkMenuEntry implements MenuEntry {
@Override
public
void setImage(final URL imageUrl) throws IOException {
void setImage(final URL imageUrl) {
if (imageUrl == null) {
setImage_(null);
}
@ -162,7 +163,7 @@ class GtkMenuEntry implements MenuEntry {
@Override
public
void setImage(final String cacheName, final InputStream imageStream) throws IOException {
void setImage(final String cacheName, final InputStream imageStream) {
if (imageStream == null) {
setImage_(null);
}
@ -174,7 +175,7 @@ class GtkMenuEntry implements MenuEntry {
@Override
@Deprecated
public
void setImage(final InputStream imageStream) throws IOException {
void setImage(final InputStream imageStream) {
if (imageStream == null) {
setImage_(null);
}

View File

@ -25,7 +25,6 @@ import dorkbox.util.jna.linux.Gobject;
import dorkbox.util.jna.linux.Gtk;
import dorkbox.util.jna.linux.GtkSupport;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.ExecutorService;
@ -226,7 +225,7 @@ class GtkTypeSystemTray extends SystemTray {
@Override
public
void addMenuEntry(String menuText, final String imagePath, final SystemTrayMenuAction callback) throws IOException {
void addMenuEntry(String menuText, final String imagePath, final SystemTrayMenuAction callback) {
if (imagePath == null) {
addMenuEntry_(menuText, null, callback);
}
@ -237,7 +236,7 @@ class GtkTypeSystemTray extends SystemTray {
@Override
public
void addMenuEntry(final String menuText, final URL imageUrl, final SystemTrayMenuAction callback) throws IOException {
void addMenuEntry(final String menuText, final URL imageUrl, final SystemTrayMenuAction callback) {
if (imageUrl == null) {
addMenuEntry_(menuText, null, callback);
}
@ -248,8 +247,7 @@ class GtkTypeSystemTray extends SystemTray {
@Override
public
void addMenuEntry(final String menuText, final String cacheName, final InputStream imageStream, final SystemTrayMenuAction callback)
throws IOException {
void addMenuEntry(final String menuText, final String cacheName, final InputStream imageStream, final SystemTrayMenuAction callback) {
if (imageStream == null) {
addMenuEntry_(menuText, null, callback);
}
@ -261,7 +259,7 @@ class GtkTypeSystemTray extends SystemTray {
@Override
@Deprecated
public
void addMenuEntry(final String menuText, final InputStream imageStream, final SystemTrayMenuAction callback) throws IOException {
void addMenuEntry(final String menuText, final InputStream imageStream, final SystemTrayMenuAction callback) {
if (imageStream == null) {
addMenuEntry_(menuText, null, callback);
}

View File

@ -26,7 +26,6 @@ import javax.swing.ImageIcon;
import javax.swing.JMenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@ -111,7 +110,7 @@ class SwingMenuEntry implements MenuEntry {
@Override
public
void setImage(final String imagePath) throws IOException {
void setImage(final String imagePath) {
if (imagePath == null) {
setImage_(null);
}
@ -122,7 +121,7 @@ class SwingMenuEntry implements MenuEntry {
@Override
public
void setImage(final URL imageUrl) throws IOException {
void setImage(final URL imageUrl) {
if (imageUrl == null) {
setImage_(null);
}
@ -133,7 +132,7 @@ class SwingMenuEntry implements MenuEntry {
@Override
public
void setImage(final String cacheName, final InputStream imageStream) throws IOException {
void setImage(final String cacheName, final InputStream imageStream) {
if (imageStream == null) {
setImage_(null);
}
@ -145,7 +144,7 @@ class SwingMenuEntry implements MenuEntry {
@Override
@Deprecated
public
void setImage(final InputStream imageStream) throws IOException {
void setImage(final InputStream imageStream) {
if (imageStream == null) {
setImage_(null);
}

View File

@ -33,7 +33,6 @@ import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
@ -230,7 +229,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
@Override
public
void addMenuEntry(String menuText, final String imagePath, final SystemTrayMenuAction callback) throws IOException {
void addMenuEntry(String menuText, final String imagePath, final SystemTrayMenuAction callback) {
if (imagePath == null) {
addMenuEntry_(menuText, null, callback);
}
@ -241,7 +240,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
@Override
public
void addMenuEntry(final String menuText, final URL imageUrl, final SystemTrayMenuAction callback) throws IOException {
void addMenuEntry(final String menuText, final URL imageUrl, final SystemTrayMenuAction callback) {
if (imageUrl == null) {
addMenuEntry_(menuText, null, callback);
}
@ -252,8 +251,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
@Override
public
void addMenuEntry(final String menuText, final String cacheName, final InputStream imageStream, final SystemTrayMenuAction callback)
throws IOException {
void addMenuEntry(final String menuText, final String cacheName, final InputStream imageStream, final SystemTrayMenuAction callback) {
if (imageStream == null) {
addMenuEntry_(menuText, null, callback);
}
@ -265,7 +263,7 @@ class SwingSystemTray extends dorkbox.systemTray.SystemTray {
@Override
@Deprecated
public
void addMenuEntry(final String menuText, final InputStream imageStream, final SystemTrayMenuAction callback) throws IOException {
void addMenuEntry(final String menuText, final InputStream imageStream, final SystemTrayMenuAction callback) {
if (imageStream == null) {
addMenuEntry_(menuText, null, callback);
}

View File

@ -21,7 +21,6 @@ import dorkbox.systemTray.SystemTray;
import dorkbox.systemTray.SystemTrayMenuAction;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
@ -57,12 +56,7 @@ class TestTray {
throw new RuntimeException("Unable to load SystemTray!");
}
try {
this.systemTray.setIcon(LT_GRAY_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
this.systemTray.setIcon(LT_GRAY_MAIL);
systemTray.setStatus("No Mail");
callbackGreen = new SystemTrayMenuAction() {
@ -70,21 +64,9 @@ class TestTray {
public
void onClick(final SystemTray systemTray, final MenuEntry menuEntry) {
systemTray.setStatus("Some Mail!");
try {
systemTray.setIcon(GREEN_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
systemTray.setIcon(GREEN_MAIL);
menuEntry.setCallback(callbackGray);
try {
menuEntry.setImage(BLACK_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
menuEntry.setImage(BLACK_MAIL);
menuEntry.setText("Delete Mail");
// systemTray.removeMenuEntry(menuEntry);
}
@ -95,12 +77,7 @@ class TestTray {
public
void onClick(final SystemTray systemTray, final MenuEntry menuEntry) {
systemTray.setStatus(null);
try {
systemTray.setIcon(BLACK_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
systemTray.setIcon(BLACK_MAIL);
menuEntry.setCallback(null);
// systemTray.setStatus("Mail Empty");
systemTray.removeMenuEntry(menuEntry);
@ -108,11 +85,7 @@ class TestTray {
}
};
try {
this.systemTray.addMenuEntry("Green Mail", GREEN_MAIL, callbackGreen);
} catch (IOException e) {
e.printStackTrace();
}
this.systemTray.addMenuEntry("Green Mail", GREEN_MAIL, callbackGreen);
systemTray.addMenuEntry("Quit", new SystemTrayMenuAction() {
@Override

View File

@ -29,7 +29,6 @@ import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
/**
@ -90,11 +89,7 @@ class TestTrayJavaFX extends Application {
throw new RuntimeException("Unable to load SystemTray!");
}
try {
this.systemTray.setIcon(LT_GRAY_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
this.systemTray.setIcon(LT_GRAY_MAIL);
systemTray.setStatus("No Mail");
@ -103,21 +98,9 @@ class TestTrayJavaFX extends Application {
public
void onClick(final SystemTray systemTray, final MenuEntry menuEntry) {
systemTray.setStatus("Some Mail!");
try {
systemTray.setIcon(GREEN_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
systemTray.setIcon(GREEN_MAIL);
menuEntry.setCallback(callbackGray);
try {
menuEntry.setImage(BLACK_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
menuEntry.setImage(BLACK_MAIL);
menuEntry.setText("Delete Mail");
// systemTray.removeMenuEntry(menuEntry);
}
@ -128,12 +111,7 @@ class TestTrayJavaFX extends Application {
public
void onClick(final SystemTray systemTray, final MenuEntry menuEntry) {
systemTray.setStatus(null);
try {
systemTray.setIcon(BLACK_MAIL);
} catch (IOException e) {
e.printStackTrace();
}
systemTray.setIcon(BLACK_MAIL);
menuEntry.setCallback(null);
// systemTray.setStatus("Mail Empty");
systemTray.removeMenuEntry(menuEntry);
@ -141,11 +119,7 @@ class TestTrayJavaFX extends Application {
}
};
try {
this.systemTray.addMenuEntry("Green Mail", GREEN_MAIL, callbackGreen);
} catch (IOException e) {
e.printStackTrace();
}
this.systemTray.addMenuEntry("Green Mail", GREEN_MAIL, callbackGreen);
systemTray.addMenuEntry("Quit", new SystemTrayMenuAction() {
@Override

View File

@ -0,0 +1,123 @@
/*
* Copyright 2015 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;
import dorkbox.systemTray.MenuEntry;
import dorkbox.systemTray.SystemTray;
import dorkbox.systemTray.SystemTrayMenuAction;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import java.io.File;
import java.net.URL;
/**
* Icons from 'SJJB Icons', public domain/CC0 icon set
*
* Needs SWT to run
*/
public
class TestTraySwt {
// horribly hacky. ONLY FOR TESTING!
public static final URL BLACK_MAIL = TestTraySwt.class.getResource("mail.000000.24.png");
public static final URL GREEN_MAIL = TestTraySwt.class.getResource("mail.39AC39.24.png");
public static final URL LT_GRAY_MAIL = TestTraySwt.class.getResource("mail.999999.24.png");
public static
void main(String[] args) {
// ONLY if manually loading JNA jars.
//
// Not necessary if using the official JNA downloaded from https://github.com/twall/jna AND THAT JAR is on the classpath
//
System.load(new File("../../resources/Dependencies/jna/linux_64/libjna.so").getAbsolutePath()); //64bit linux library
new TestTraySwt();
}
private SystemTray systemTray;
private SystemTrayMenuAction callbackGreen;
private SystemTrayMenuAction callbackGray;
public
TestTraySwt() {
Display display = new Display ();
Shell shell = new Shell(display);
Text helloWorldTest = new Text(shell, SWT.NONE);
helloWorldTest.setText("Hello World SWT");
helloWorldTest.pack();
shell.pack();
shell.open ();
this.systemTray = SystemTray.getSystemTray();
if (systemTray == null) {
throw new RuntimeException("Unable to load SystemTray!");
}
this.systemTray.setIcon(LT_GRAY_MAIL);
systemTray.setStatus("No Mail");
callbackGreen = new SystemTrayMenuAction() {
@Override
public
void onClick(final SystemTray systemTray, final MenuEntry menuEntry) {
systemTray.setStatus("Some Mail!");
systemTray.setIcon(GREEN_MAIL);
menuEntry.setCallback(callbackGray);
menuEntry.setImage(BLACK_MAIL);
menuEntry.setText("Delete Mail");
// systemTray.removeMenuEntry(menuEntry);
}
};
callbackGray = new SystemTrayMenuAction() {
@Override
public
void onClick(final SystemTray systemTray, final MenuEntry menuEntry) {
systemTray.setStatus(null);
systemTray.setIcon(BLACK_MAIL);
menuEntry.setCallback(null);
// systemTray.setStatus("Mail Empty");
systemTray.removeMenuEntry(menuEntry);
System.err.println("POW");
}
};
this.systemTray.addMenuEntry("Green Mail", GREEN_MAIL, callbackGreen);
systemTray.addMenuEntry("Quit", new SystemTrayMenuAction() {
@Override
public
void onClick(final SystemTray systemTray, final MenuEntry menuEntry) {
systemTray.shutdown();
//System.exit(0); not necessary if all non-daemon threads have stopped.
}
});
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
}