Java / JavaFX: Set Swing icon for JavaFX shortcut
I am trying to read a thumbnail (32x32px icon) from a file (.ico / .exe) and set it to a JavaFX shortcut.
My first try:
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;
}
After that I do this:
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));
I searched several sites and found this, but it gives me an exception:
java.lang.UnsupportedOperationException: unsupported class for loadPlatformImage
My second try:
URL url = file.toURI().toURL();
Image image = new Image(url.toString());
lblAppIconValue.setGraphic(new ImageView(image));
Also doesn't work ...
My question is, how do I set javax.swing.Icon to a JavaFX shortcut? Is it possible? If this is not possible, how can I read the thumbnail from the file and set it as an icon / graphic for a JavaFX shortcut?
Thank!
source to share
Never use methods impl_
: they are not part of the public API.
To convert an awt image to an FX image, the class SwingFXUtils
c javafx.embed.swing
has a method toFXImage(...)
that converts a BufferedImage
to JavaFX Image
. It's not clear if you have an image with an image BufferedImage
, so you need a few steps to make it work:
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);
This is a rather inefficient approach, as you first create an awt image from your file and then convert it to an FX image, possibly via an intermediate buffered image. If you have access to the source code for the class ShellFolder
, you can see how this implements the method getIcon()
and performs the same process. At some point it has to get InputStream
with the image data; once you have this, you can pass it to the constructor javafx.scene.image.Image
.
source to share
If you want to host an image in your JavaFX application, you have 2 main options:
-
Define it in your fxml file:
<ImageView> <Image url="icon.png"/> </ImageView>
-
Create
Label
in your controller: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
should be placed in the same package with the fxml file or your controller (otherwise you should change the name of the image in this example).
Update: Dynamically changes the image in the label (according to the image selected by the user).
FXML:
<Button fx:id="setImageButton"/>
<ImageView fx:id="image">
<Image url="defaultImage.png"/>
</ImageView>
Controller:
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
}
}
}
});
}
}
source to share