I'm trying to read a thumbnail (icon; 32x32px) from a file (.ico/.exe) and set it to a JavaFX label.
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'm doing 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've searched trough 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 not working ...
My question: How can I set a javax.swing.Icon to a JavaFX label? Is it possible? If it's not possible, how can I read a thumbnail from a file and set it as an icon/graphic for a JavaFX label?
Thanks!
Never use impl_
methods: these are not part of the public API.
To convert an awt Image to an FX Image, the SwingFXUtils
class in javafx.embed.swing
has a toFXImage(...)
method that converts a BufferedImage
to a JavaFX Image
. It's not clear whether the image you have from the icon is a BufferedImage
, so you'll need a couple of steps to make that 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 fairly inefficient approach, as you are first creating an awt image from your file, then converting it to an FX image, possibly via an intermediate buffered image. If you have access to the source code for the ShellFolder
class, you might see how that implements the getIcon()
method and follow the same process. At some point, it must get an InputStream
with the image data; once you have that you can pass it to the javafx.scene.image.Image
constructor.
If you want to place an image in your application on JavaFX you have 2 main options:
Define it in fxml:
<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 fxml-file or your controller (otherwise you should amend image name in that example).
Update: change image in label dynamically (in accordance with image selected by 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
}
}
}
});
}
}