2014-11-08 5 views
0

드롭 박스에서 트레이 아이콘이 동적으로 변경됩니다. 파일 업로드 중 동기화 아이콘이 표시됩니다. 모든 파일이 동기화되면 드롭 박스에 다른 아이콘 (최신 상태 아이콘)이 표시됩니다.Dropbox 트레이 아이콘처럼 JavaFX에서 트레이 아이콘 이미지를 동적으로 변경하는 방법

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

는 I은 일반적 trayIcon.setImage (청색 트레이 아이콘 표시) 작동 제 호에서

자바 FX를 사용하여 동일한 기능을 개발하려는. 두 번째 호출이 작동하지 않습니다 (회색 컬러 트레이 아이콘이 표시되지 않음). 빈 상자 만 표시합니다.

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) 문제는 동일합니다. 파란색 트레이 아이콘을 회색 컬러 트레이 아이콘으로 바꿀 수 없습니다 –

+0

김프로 두 번째 이미지 크기를 16x16으로 변경 했으므로 아이콘이 시각화되었습니다 ... 이전 코드 샘플을 사용합니다 – Mailkov

+1

Mailkov. 같은 크기의 아이콘을 사용하면 시각화됩니다. 하지만 난 아직도 모르겠다, 왜 그것은 bufferedImage를 사용하여 색상 변경 작업을하지 않습니다. 어쨌든, Mailkov 감사합니다. –

관련 문제