I am developing a JavaFX rich client that uses legacy resource providers. One such provided resource is a javax.swing.ImageIcon
. I have to paint that icon inside a details dialog that is rendered from a JavaFX .fxml file.
The way I found to work was to paint the ImageIcon
into a java.awt.image.BufferedImage
using the ImageIcon.paintIcon()
method with a java.awt.Graphics
from BufferedImage.createGraphics()
. From that BufferedImage
, javafx.embed.swing.SwingFXUtils.toFXImage()
gives a javafx.scene.image.WritableImage
that can be placed in the ImageView
of the .fxml.
Here is the code of the transforming method, based on some other solutions viewed here in StackOverflow:
private javafx.scene.image.Image atonIcon2ImageConverter(ImageIcon icon) {
BufferedImage bi = new BufferedImage(
icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
// paint the Icon to the BufferedImage.
icon.paintIcon(null, g, 0, 0);
g.dispose();
return SwingFXUtils.toFXImage(bi.getSubimage(0, 1, bi.getWidth(), bi.getHeight()-1), null);
}
Although this solution works, it appears to me quite convoluted and I would like some expert opinion on how it could be made more straightforward. With JavaFX being the successor of Swing, I see quite possible that there is a simpler way to place a Swing ImageIcon
inside a JavaFX .fxml file (the ImageIcon
is given, but the ImageView
can be challenged).
After playing around and mixing different comments and solutions, here is what I came out with for my real system implementation. It definitely is a very particular environment (the ImageIcon
has a Swing ToolkitImage
inside), so it might not be applicable to many:
private javafx.scene.image.Image atonIcon2ImageConverter(ImageIcon icon) {
BufferedImage bi = ((sun.awt.image.ToolkitImage)imageIcon.getImage()).getBufferedImage();
return SwingFXUtils.toFXImage(bi, null);
}
Have you tried:
ImageIcon imageIcon;
Image image = imageIcon.getImage();
BufferedImage bufferedImage = (BufferedImage) image;
or combinded
BufferedImage bufferedImage = (BufferedImage) imageIcon.getImage();
Whether this works or not depends on how the ImageIcons are constructed in your legacy code. Here is a working example. It also contains the commented out variant which does not work.
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class ImageIconTest {
public static void main(String[] args) throws IOException {
ImageIcon imageIcon = createImageIcon("/DukeCheers.png", "DukeCheers");
BufferedImage bufferedImage = (BufferedImage)imageIcon.getImage();
System.out.println("done");
}
private static ImageIcon createImageIcon(String path, String description) throws IOException {
java.net.URL imgURL = ImageIconTest.class.getResource(path);
if (imgURL != null) {
// This does not work.
// return new ImageIcon(imgURL, description);
// This works.
return new ImageIcon(ImageIO.read(imgURL), description);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
}