Question

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.

Was it helpful?

Solution

The problem might be in Toolkit#createImage(). ImageIO.read() might be better. Also, it looks like you're throwing away the result from imgToBufferedImg().

OTHER TIPS

no reason why

  • create BufferedImage inside JButtons setIcon(), there you would be to set (for JButton) Icon, ImageIcon

  • this BufferedImage (should be Icon, ImageIcon) is create after is added to JButton


but

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
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top