Java / JavaFX:为JavaFX标签设置Swing图标

时间:2014-10-04 12:30:16

标签: java javafx icons label

我正在尝试从文件(.ico / .exe)中读取缩略图(图标; 32x32px)并将其设置为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标签的图标/图形?

谢谢!

2 个答案:

答案 0 :(得分: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构造函数。

答案 1 :(得分:0)

如果您想在JavaFX上的应用程序中放置图像,您有两个主要选项:

  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));
    
  3. icon.png应与fxml-file或您的控制器放在同一个包中(否则您应修改该示例中的图像名称)。

    更新:动态更改标签中的图片(根据用户选择的图片)。

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