2014-10-04 3 views
3

Я пытаюсь прочитать миниатюру (значок 32x32px) из файла (.ico/.exe) и установить ее на ярлык JavaFX.Java/JavaFX: установить значок Swing для метки JavaFX

Моя первая попытка:

public Icon getLargeIcon(String exeFile) { 
    if (exeFile != null) { 
     File file = new File(exeFile); 
     try { 
      ShellFolder sf = ShellFolder.getShellFolder(file); 
      return new ImageIcon(sf.getIcon(true), sf.getFolderType()); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 
    return null; 
} 

После того, что я делаю это:

Icon largeIcon = getLargeIcon(file.getAbsolutePath()); 
    ImageIcon swingImageIcon = (ImageIcon) largeIcon; 
    java.awt.Image awtImage = swingImageIcon.getImage(); 
    Image fxImage = javafx.scene.image.Image.impl_fromPlatformImage(awtImage); 
    lblAppIconValue.setGraphic(new ImageView(fxImage)); 

Я искал корыто несколько сайтов, и нашел, что это, но это дает мне исключение: java.lang.UnsupportedOperationException: unsupported class for loadPlatformImage

Моя вторая попытка:

  URL url = file.toURI().toURL(); 
      Image image = new Image(url.toString()); 
      lblAppIconValue.setGraphic(new ImageView(image)); 

Также не работает ...

Мой вопрос: Как я могу установить javax.swing.Icon на метку JavaFX? Является ли это возможным? Если это невозможно, как я могу прочитать эскиз из файла и установить его как значок/графику для ярлыка JavaFX?

Спасибо!

ответ

5

Никогда не используйте impl_ методы: они не являются частью общественного API.

Для преобразования AWT изображения на FX Образ, SwingFXUtils класса javafx.embed.swing имеет toFXImage(...) метод, который преобразует BufferedImage в JavaFX Image. Пока не ясно, является ли изображение, которое вы имеете от иконы является BufferedImage, так что вам потребуется несколько шагов, чтобы сделать эту работу:

BufferedImage bImg ; 
if (awtImage instanceof BufferedImage) { 
    bImg = (BufferedImage) awtImage ; 
} else { 
    bImg = new BufferedImage(awtImage.getWidth(null), awtImage.getHeight(null), BufferedImage.TYPE_INT_ARGB); 
    Graphics2D graphics = bImg.createGraphics(); 
    graphics.drawImage(awtImage, 0, 0, null); 
    graphics.dispose(); 
} 
Image fxImage = SwingFXUtils.toFXImage(bImg, null); 

Это довольно неэффективный подход, так как вы первое создание AWT изображение из вашего файла, а затем преобразование его в FX-изображение, возможно, через промежуточное буферное изображение.Если у вас есть доступ к исходному коду для класса ShellFolder, вы можете увидеть, как это реализует метод getIcon() и выполните тот же процесс. В какой-то момент он должен получить InputStream с данными изображения; как только у вас есть, вы можете передать его в конструктор javafx.scene.image.Image.

+0

У меня есть ошибка на этой строке: graphics.drawImage (0, 0, awtImage); «Метод drawImage (Image, int, int, ImageObserver) в типе Graphics не применим для аргументов (int, int, Image)» – baris1892

+0

К сожалению, неправильно вспомнили параметры. Я исправил это сейчас. –

+0

Aaah, отлично работает, большое вам спасибо! – baris1892

0

Если вы хотите поместить изображение в приложении на JavaFX у вас есть 2 основных варианта:

  1. определить его в FXML:

    <ImageView> 
        <Image url="icon.png"/> 
    </ImageView> 
    
  2. Создать Label в контроллере:

    import javafx.scene.control.Label; 
    import javafx.scene.image.Image; 
    import javafx.scene.image.ImageView; 
    
    ... 
    
    Image image = new Image(getClass().getResourceAsStream("icon.png")); 
    Label label = new Label("Label"); 
    label.setGraphic(new ImageView(image)); 
    

icon.png следует разместить в одном пакете с файлом fxml или вашим контроллером (в противном случае вы должны изменить название изображения в этом примере).

Обновление: динамическое изменение изображения в ярлыке (в соответствии с выбранным пользователем изображением).

FXML:

<Button fx:id="setImageButton"/> 
    <ImageView fx:id="image"> 
     <Image url="defaultImage.png"/> 
    </ImageView> 

Контроллер:

 public class MainController implements Initializable { 
     public Parent root; 
     public Button setImageButton; 
     public ImageView image; 

     @Override 
     public void initialize(URL location, ResourceBundle resources) { 

      setImageButton.setOnAction(new EventHandler<ActionEvent>() { 
       @Override 
       public void handle(ActionEvent event) { 
        FileChooser fileChooser = new FileChooser(); 
        File file = fileChooser.showOpenDialog(root.getScene().getWindow()); 
        if (file != null) { 
         try { 
          BufferedImage bufferedImage = ImageIO.read(file); 
          Image picture = SwingFXUtils.toFXImage(bufferedImage, null); 
          image.setImage(picture); 
         } catch (IOException ex) { 
          // do something 
         } 
        } 
       } 
      }); 
     } 
    } 
+0

проблема заключается в том, что значок должен изменяться динамически, поскольку пользователь может выбрать exe-файл, например. «C: \ Program Files (x86) \ Google \ Chrome \ Application \ chrome.exe" – baris1892

+0

@ radon66, я обновил ответ. – diffycat

+0

спасибо, но он все еще не работает, я все время получаю исключение NullPointerException в строке «bufferedImage = ImageIO.read (файл)»; (file is not null!) – baris1892