diff --git a/src/dorkbox/systemTray/ImageUtil.java b/src/dorkbox/systemTray/ImageUtil.java index bd4b31b..95c2f57 100644 --- a/src/dorkbox/systemTray/ImageUtil.java +++ b/src/dorkbox/systemTray/ImageUtil.java @@ -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 resourceToFilePath = new HashMap(); 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(); diff --git a/src/dorkbox/systemTray/MenuEntry.java b/src/dorkbox/systemTray/MenuEntry.java index 234c451..e51ba49 100644 --- a/src/dorkbox/systemTray/MenuEntry.java +++ b/src/dorkbox/systemTray/MenuEntry.java @@ -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 diff --git a/src/dorkbox/systemTray/SystemTray.java b/src/dorkbox/systemTray/SystemTray.java index 2795db7..df6fe52 100644 --- a/src/dorkbox/systemTray/SystemTray.java +++ b/src/dorkbox/systemTray/SystemTray.java @@ -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); diff --git a/src/dorkbox/systemTray/linux/GtkMenuEntry.java b/src/dorkbox/systemTray/linux/GtkMenuEntry.java index b594aa3..e282f8e 100644 --- a/src/dorkbox/systemTray/linux/GtkMenuEntry.java +++ b/src/dorkbox/systemTray/linux/GtkMenuEntry.java @@ -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); } diff --git a/src/dorkbox/systemTray/linux/GtkTypeSystemTray.java b/src/dorkbox/systemTray/linux/GtkTypeSystemTray.java index e0f8fe4..48ad03c 100644 --- a/src/dorkbox/systemTray/linux/GtkTypeSystemTray.java +++ b/src/dorkbox/systemTray/linux/GtkTypeSystemTray.java @@ -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); } diff --git a/src/dorkbox/systemTray/swing/SwingMenuEntry.java b/src/dorkbox/systemTray/swing/SwingMenuEntry.java index 006c1fa..f5d2fbc 100644 --- a/src/dorkbox/systemTray/swing/SwingMenuEntry.java +++ b/src/dorkbox/systemTray/swing/SwingMenuEntry.java @@ -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); } diff --git a/src/dorkbox/systemTray/swing/SwingSystemTray.java b/src/dorkbox/systemTray/swing/SwingSystemTray.java index d24c9c2..1274e4d 100644 --- a/src/dorkbox/systemTray/swing/SwingSystemTray.java +++ b/src/dorkbox/systemTray/swing/SwingSystemTray.java @@ -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); } diff --git a/test/dorkbox/TestTray.java b/test/dorkbox/TestTray.java index 5f3a514..184a1a5 100644 --- a/test/dorkbox/TestTray.java +++ b/test/dorkbox/TestTray.java @@ -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 diff --git a/test/dorkbox/TestTrayJavaFX.java b/test/dorkbox/TestTrayJavaFX.java index d5a6197..0e8b842 100644 --- a/test/dorkbox/TestTrayJavaFX.java +++ b/test/dorkbox/TestTrayJavaFX.java @@ -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 diff --git a/test/dorkbox/TestTraySwt.java b/test/dorkbox/TestTraySwt.java new file mode 100644 index 0000000..4798472 --- /dev/null +++ b/test/dorkbox/TestTraySwt.java @@ -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 (); + } +}