Netbeans matisse, custom button icon property error
Вопрос
I have created a custom JButton
where override the setIcon
.
public class TestButton extends JButton {
public TestButton() {
super();
}
@Override
public void setIcon(Icon icon) {
super.setIcon(icon);
imgToBufferedImg(Toolkit.getDefaultToolkit().createImage("test.png"));
}
}
And here is the imgToBufferedImg method.
public BufferedImage imgToBufferedImg(Image image) {
if (image == null) {
return null;
}
if (image instanceof BufferedImage) {
return ((BufferedImage) image);
} else {
BufferedImage bufferedImage = new BufferedImage(
image.getWidth(null),
image.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
Graphics g = bufferedImage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return bufferedImage;
}
}
I have added this component in Matisse, no problem, however, when i try to set the icon property of the button i get the error:
Failed to write the value to the property "icon"
The problem seems to come from the imgToBufferedImg since i can set the property if i remove the call to this method in setIcon
. What is wrong with my image conversion method?
EDIT:
The following test succeeded:
try {
imgToBufferedImg(ImageIO.read(new FileInputStream("test.png")));
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
Also i just figured out that the problem is caused by:
((ImageIcon) icon).getImage();
Running this code when the UI is ready (e.g using a SwingUtilities.invokeLater
) seems to work.
Решение
The problem might be in Toolkit#createImage()
. ImageIO.read()
might be better. Also, it looks like you're throwing away the result from imgToBufferedImg()
.
Другие советы
no reason why
create
BufferedImage
insideJButtons setIcon()
, there you would be to set (forJButton
)Icon
,ImageIcon
this
BufferedImage
(should beIcon
,ImageIcon
) is create after is added toJButton
but
method could be
BufferedImage to Icon, ImageIcon
whats wrong with
JButton#setIcon()
Thanks to the thrashed comment:
Toolkit "operations may be performed asynchronously." Your Image may be incomplete when you try to render it.
I was able to figure out what the problem was. Straight from the setIcon
method, i requested the image from the icon:
((ImageIcon) icon).getImage()
But this image is definitively incomplete. Putin my logic within the event dispatching thread did the trick.
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//requesting icon images here
}
}