2014-11-08 113 views
0

在保管箱中,托盘图标会动态更改。 当文件正在上传时,会显示同步图标。 当所有文件同步时,dropbox显示其他图标(最新状态图标)。如何动态更改JavaFX中的托盘图标图像,如保管箱托盘图标

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); 
} 
} 

回答

1

我觉得问题是在不同的图像大小,你改变第一个大小的第二个图标!

+0

我修改了一个源代码来使用缓冲图像。第一次和第二次呼叫具有相同的大小(16 * 16),但问题相同。我无法将蓝色托盘图标更改为灰色托盘图标 – 2014-11-08 17:20:32

+0

我已将gimp第二张图像的大小更改为16x16,因此图标可视化...我使用您以前的代码示例 – Mailkov 2014-11-09 15:10:56

+1

谢谢Mailkov。当我使用相同大小的图标时,它被可视化。但我仍然不知道,为什么它不使用bufferedImage改变颜色。无论如何,谢谢Mailkov – 2014-11-09 16:24:46