我如何在JavaFX中动态更改托盘图标图像(如保管箱托盘图标)

朱利安·李(Julian Lee)

在保管箱中,任务栏图标会动态更改。上传文件时,显示同步图标。当所有文件同步后,保管箱会显示其他图标(最新状态图标)。

https://mockupstogo.mybalsamiq.com/projects/icons/Dropbox

我想使用JavaFX开发相同的功能

首次调用时,trayIcon.setImage正常工作(显示蓝色任务栏图标)。但第二次通话不起作用(未显示灰色任务栏图标)。它只是显示一个空框。

是JavaFX错误吗?

package application;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TreeView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;


public class Main extends Application {
// one icon location is shared between the application tray icon and task bar icon.
// you could also use multiple icons to allow for clean display of tray icons on hi-dpi devices.
//private static final String iconImageLoc =
//  "http://icons.iconarchive.com/icons/scafer31000/bubble-circle-3/16/GameCenter-icon.png";

//private static final String iconImageLoc1 =
//  "http://icons.iconarchive.com/icons/icons-land/metro-halloween/96/Cauldron-icon.png";

// application stage is stored so that it can be shown and hidden based on system tray icon operations.
private Stage stage;

// a timer allowing the tray icon to provide a periodic notification event.
private Timer notificationTimer = new Timer();

// format used to display the current time in a tray icon notification.
private DateFormat timeFormat = SimpleDateFormat.getTimeInstance();


private TreeView<String> treeView;

// sets up the javafx application.
// a tray icon is setup for the icon, but the main stage remains invisible until the user
// interacts with the tray icon.
@Override public void start(final Stage stage) {
    // stores a reference to the stage.
    this.stage = stage;

    // instructs the javafx system not to exit implicitly when the last application window is shut.
    Platform.setImplicitExit(false);

    // sets up the tray icon (using awt code run on the swing thread).
    javax.swing.SwingUtilities.invokeLater(this::addAppToTray);

    // out stage will be translucent, so give it a transparent style.
    stage.initStyle(StageStyle.TRANSPARENT);

    // create the layout for the javafx stage.
    StackPane layout = new StackPane(createContent());
    layout.setStyle(
            "-fx-background-color: rgba(255, 255, 255, 0.5);"
    );
    layout.setPrefSize(300, 200);

    // this dummy app just hides itself when the app screen is clicked.
    // a real app might have some interactive UI and a separate icon which hides the app window.
    layout.setOnMouseClicked(event -> stage.hide());

    // a scene with a transparent fill is necessary to implement the translucent app window.
    Scene scene = new Scene(layout);
    scene.setFill(Color.TRANSPARENT);

    stage.setScene(scene);

}

/**
 * For this dummy app, the (JavaFX scenegraph) content, just says "hello, world".
 * A real app, might load an FXML or something like that.
 *
 * @return the main window application content.
 */
private Node createContent() {
    Label hello = new Label("hello, world");
    hello.setStyle("-fx-font-size: 40px; -fx-text-fill: forestgreen;");
    Label instructions = new Label("(click to hide)");
    instructions.setStyle("-fx-font-size: 12px; -fx-text-fill: orange;");

    VBox content = new VBox(10, hello, instructions);
    content.setAlignment(Pos.CENTER);

    return content;
}

/**
 * Sets up a system tray icon for the application.
 */
private void addAppToTray() {
    try {
        // ensure awt toolkit is initialized.
        java.awt.Toolkit.getDefaultToolkit();

        // app requires system tray support, just exit if there is no support.
        if (!java.awt.SystemTray.isSupported()) {
            System.out.println("No system tray support, application exiting.");
            Platform.exit();
        }

        // set up a system tray icon.
        java.awt.SystemTray tray = java.awt.SystemTray.getSystemTray();
/*            URL imageLoc = new URL(
                iconImageLoc
        );

        URL imageLoc1 = new URL(
                iconImageLoc1
        );
        java.awt.Image image = ImageIO.read(imageLoc);

        java.awt.Image image1 = ImageIO.read(imageLoc1);*/


        Dimension size = tray.getTrayIconSize();
        BufferedImage bi = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
        Graphics g = bi.getGraphics();

        g.setColor(java.awt.Color.BLUE);
        g.fillRect(0, 0, size.width, size.height);

        System.out.println(size.width);
        System.out.println(size.height);
        java.awt.TrayIcon trayIcon = new java.awt.TrayIcon(bi);


        // if the user double-clicks on the tray icon, show the main app stage.
        trayIcon.addActionListener(event -> Platform.runLater(this::showStage));

        // if the user selects the default menu item (which includes the app name), 
        // show the main app stage.
        java.awt.MenuItem openItem = new java.awt.MenuItem("hello, world");
        openItem.addActionListener(event -> Platform.runLater(this::showStage));

        // the convention for tray icons seems to be to set the default icon for opening
        // the application stage in a bold font.
        java.awt.Font defaultFont = java.awt.Font.decode(null);
        java.awt.Font boldFont = defaultFont.deriveFont(java.awt.Font.BOLD);
        openItem.setFont(boldFont);

        // to really exit the application, the user must go to the system tray icon
        // and select the exit option, this will shutdown JavaFX and remove the
        // tray icon (removing the tray icon will also shut down AWT).
        java.awt.MenuItem exitItem = new java.awt.MenuItem("Exit");
        exitItem.addActionListener(event -> {
            notificationTimer.cancel();
            Platform.exit();
            tray.remove(trayIcon);
        });

        // setup the popup menu for the application.
        final java.awt.PopupMenu popup = new java.awt.PopupMenu();
        popup.add(openItem);
        popup.addSeparator();
        popup.add(exitItem);
        trayIcon.setPopupMenu(popup);



        // create a timer which periodically displays a notification message.
        notificationTimer.schedule(
                new TimerTask() {
                    @Override
                    public void run() {

                        javax.swing.SwingUtilities.invokeLater(() ->
                            trayIcon.displayMessage(
                                    "hello",
                                    "The time is now " + timeFormat.format(new Date()),
                                    java.awt.TrayIcon.MessageType.INFO
                            )
                        );

                        System.out.println(size.width);
                        System.out.println(size.height);
                        BufferedImage bi = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
                        Graphics g = bi.getGraphics();

                        g.fillRect(0, 0, size.width, size.height);
                        g.setColor(java.awt.Color.GRAY);

                        trayIcon.setImage(bi);

                    }
                },
                5_000,
                60_000
        );

        // add the application tray icon to the system tray.
        tray.add(trayIcon);

        //trayIcon.setImage(image1);
    //} catch (java.awt.AWTException | IOException e) {
    } catch (java.awt.AWTException e) {
        System.out.println("Unable to init system tray");
        e.printStackTrace();
    }
}

/**
 * Shows the application stage and ensures that it is brought ot the front of all stages.
 */
private void showStage() {
    if (stage != null) {
        stage.show();
        stage.toFront();
    }
}

public static void main(String[] args) throws IOException, java.awt.AWTException {
    // Just launches the JavaFX application.
    // Due to way the application is coded, the application will remain running
    // until the user selects the Exit menu option from the tray icon.
    launch(args);
}
}
迈尔科夫

我认为问题出在不同的图像尺寸上,您将第一个图标的尺寸更改为第一个!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何更改Steam的托盘图标?

来自分类Dev

如何在系统任务栏中永久隐藏保管箱图标

来自分类Dev

如何在系统任务栏中永久隐藏保管箱图标

来自分类Dev

更改Skype托盘图标

来自分类Dev

更改Skype托盘图标

来自分类Dev

如何更改难看的铬/铬托盘图标

来自分类Dev

如何更改难看的铬/铬托盘图标

来自分类Dev

如何更改goldendict系统托盘图标?

来自分类Dev

我如何找出Windows 10托盘栏中的空白图标?

来自分类Dev

如何在 XFCE 的系统托盘中禁用 Chromium 图标?

来自分类Dev

如何停用左托盘图标?

来自分类Dev

我的图标托盘上的图标很奇怪

来自分类Dev

更改电子托盘图标的顺序

来自分类Dev

QSystemTrayIcon.setIcon 无法更改托盘图标

来自分类Dev

如何访问并启用更多图标在系统托盘中?

来自分类Dev

如何在Android Studio中添加图标图像按钮

来自分类Dev

如何在Windows 7中将图标从任务栏移动到系统托盘?

来自分类Dev

如何在Windows Server 2019(1809)中显示Windows Defender的托盘图标?

来自分类Dev

如何在系统顶部栏中显示 Wine System 托盘图标?( Ubuntu 18.04 )

来自分类Dev

ScreenCloud托盘图标消失

来自分类Dev

ScreenCloud托盘图标消失

来自分类Dev

如何正确更新托盘通知图标?

来自分类Dev

如何修复丢失的Dropbox托盘图标?

来自分类Dev

如何修复丢失的Dropbox托盘图标?

来自分类Dev

如何恢复消失的电池托盘图标指示?

来自分类Dev

从系统托盘中删除图标

来自分类Dev

Xfce中的系统托盘图标加倍

来自分类Dev

托盘中的 VLC 图标多次出现

来自分类Dev

如何使用启动脚本修复丢失的保管箱面板图标?

Related 相关文章

热门标签

归档