Make StatusTrayIcon work with JavaFX

* Remove Swing dependencies from StatusTrayIcon
* Pass a stage to the constructor
* Adjust focus change handler and reactivation
* Add IconUtil#loadAWTCompatible for BufferedImage loading
This commit is contained in:
Kai S. K. Engelbart 2020-07-20 12:57:34 +02:00
parent 3c81860f1c
commit 2740a1cb10
No known key found for this signature in database
GPG Key ID: 0A48559CA32CB48F
2 changed files with 33 additions and 23 deletions

View File

@ -1,9 +1,13 @@
package envoy.client.ui; package envoy.client.ui;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.logging.Level; import java.util.logging.Level;
import javax.imageio.ImageIO;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import envoy.client.data.Settings; import envoy.client.data.Settings;
@ -145,6 +149,23 @@ public class IconUtil {
return icons; return icons;
} }
/**
* Loads a buffered image from the resource folder which is compatible with AWT.
*
* @param path the path to the icon inside the resource folder
* @return the loaded image
* @since Envoy Client v0.2-beta
*/
public static BufferedImage loadAWTCompatible(String path) {
BufferedImage image = null;
try {
image = ImageIO.read(IconUtil.class.getResource(path));
} catch (IOException e) {
EnvoyLog.getLogger(IconUtil.class).log(Level.WARNING, String.format("Could not load image at path %s: ", path), e);
}
return image;
}
/** /**
* This method should be called if the display of an image depends upon the * This method should be called if the display of an image depends upon the
* currently active theme.<br> * currently active theme.<br>
@ -154,7 +175,7 @@ public class IconUtil {
* @return the theme specific folder * @return the theme specific folder
* @since Envoy Client v0.1-beta * @since Envoy Client v0.1-beta
*/ */
public static String themeSpecificSubFolder() { private static String themeSpecificSubFolder() {
return Settings.getInstance().isUsingDefaultTheme() ? Settings.getInstance().getCurrentTheme() + "/" : ""; return Settings.getInstance().isUsingDefaultTheme() ? Settings.getInstance().getCurrentTheme() + "/" : "";
} }
} }

View File

@ -2,15 +2,14 @@ package envoy.client.ui;
import java.awt.*; import java.awt.*;
import java.awt.TrayIcon.MessageType; import java.awt.TrayIcon.MessageType;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import javafx.application.Platform;
import java.util.logging.Level; import javafx.stage.Stage;
import envoy.client.event.MessageCreationEvent; import envoy.client.event.MessageCreationEvent;
import envoy.data.Message; import envoy.data.Message;
import envoy.event.EventBus; import envoy.event.EventBus;
import envoy.exception.EnvoyException; import envoy.exception.EnvoyException;
import envoy.util.EnvoyLog;
/** /**
* Project: <strong>envoy-client</strong><br> * Project: <strong>envoy-client</strong><br>
@ -39,18 +38,16 @@ public class StatusTrayIcon {
* Creates a {@link StatusTrayIcon} with the Envoy logo, a tool tip and a pop-up * Creates a {@link StatusTrayIcon} with the Envoy logo, a tool tip and a pop-up
* menu. * menu.
* *
* @param focusTarget the {@link Window} which focus determines if message * @param stage the stage which focus determines if message
* notifications are displayed * notifications are displayed
* @throws EnvoyException if the currently used OS does not support the System * @throws EnvoyException if the currently used OS does not support the System
* Tray API * Tray API
* @since Envoy Client v0.2-alpha * @since Envoy Client v0.2-beta
*/ */
public StatusTrayIcon(Window focusTarget) throws EnvoyException { public StatusTrayIcon(Stage stage) throws EnvoyException {
if (!SystemTray.isSupported()) throw new EnvoyException("The Envoy tray icon is not supported."); if (!SystemTray.isSupported()) throw new EnvoyException("The Envoy tray icon is not supported.");
final ClassLoader loader = Thread.currentThread().getContextClassLoader(); trayIcon = new TrayIcon(IconUtil.loadAWTCompatible("/icons/envoy_logo.png"), "Envoy");
final Image img = Toolkit.getDefaultToolkit().createImage(loader.getResource("envoy_logo.png"));
trayIcon = new TrayIcon(img, "Envoy Client");
trayIcon.setImageAutoSize(true); trayIcon.setImageAutoSize(true);
trayIcon.setToolTip("You are notified if you have unread messages."); trayIcon.setToolTip("You are notified if you have unread messages.");
@ -62,18 +59,11 @@ public class StatusTrayIcon {
trayIcon.setPopupMenu(popup); trayIcon.setPopupMenu(popup);
// Only display messages if the chat window is not focused // Only display messages if the stage is not focused
focusTarget.addWindowFocusListener(new WindowAdapter() { stage.focusedProperty().addListener((ov, onHidden, onShown) -> displayMessages = ov.getValue());
@Override
public void windowGainedFocus(WindowEvent e) { displayMessages = false; }
@Override
public void windowLostFocus(WindowEvent e) { displayMessages = true; }
});
// Show the window if the user clicks on the icon // Show the window if the user clicks on the icon
trayIcon.addActionListener(evt -> { focusTarget.setVisible(true); focusTarget.requestFocus(); }); trayIcon.addActionListener(evt -> Platform.runLater(() -> { stage.show(); stage.requestFocus(); }));
// Start processing message events // Start processing message events
// TODO: Handle other message types // TODO: Handle other message types
@ -93,7 +83,6 @@ public class StatusTrayIcon {
try { try {
SystemTray.getSystemTray().add(trayIcon); SystemTray.getSystemTray().add(trayIcon);
} catch (final AWTException e) { } catch (final AWTException e) {
EnvoyLog.getLogger(StatusTrayIcon.class).log(Level.INFO, "Could not display StatusTrayIcon: ", e);
throw new EnvoyException("Could not attach Envoy tray icon to system tray.", e); throw new EnvoyException("Could not attach Envoy tray icon to system tray.", e);
} }
} }