I have a quick question. How do I get the image generated by a JComponent.paint or paintComponent?
I have a JComponent which I use as a 'workspace' and where I have overwritten the paintComponent method to my own. The thing is that my workspace JComponent also has children which has their own paintComponent methods.
So when Swing renders my workspace component, it renders the workspace graphics and then its childrens'.
However, I want to get the image my workspace component generates (which includes the workspace graphics and the children's graphics).
How do I do that?
I tried to call the paintComponent/paint-method myself by using my own Graphics, but i just returned a black image. Here is what i tried;
public void paintComponent(Graphics g) {
if (bufferedImage != null) {
g.drawImage(bufferedImage, 0, 0, this);
}
else {
g.setColor(Color.WHITE);
g.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
}
}
public BufferedImage getImage() {
BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = hello.getGraphics();
paintComponent( g );
return hello;
}
Any thoughts or comments are welcome! :)
Do not call paintComponent() or paint() from the outside. Instead, let your image be created within those (overwritten) methods. Then you can be sure that your image will actually contain the painted content of the component.
Here is an example application. The ImagePanel will actually grab the graphics contents of the component every time it is painted, which might be a bit wasteful, so you may want to adjust the frequency with which this is done.
Like Martijn said, your image was probably black because the component wasn't even painted/displayed yet. You could add a ComponentListener to be notified when it is displayed. Your "solution" with getSubimage has nothing to do with the actual problem. I recommend you remove it.
Changing the new BufferedImage to TYPE_INT_RGB solves this for me. I can't give an explanation though - just a Swing mystery.
Seems like the problem was due to how the BufferedImage was created. When using:
Instead it worked. I also had to change switch from paintComponent to paint to render the children.
Problem solved, but if anyone knows. Why did my:
Always render a black image? Offtopic, but could be interesting to know :)
If you call getImage too early, your component will not have been displayed yet and will still have a 0 width and height. Have you made sure you're calling it at a sufficient late time? Try printing the component's size to stdout and see what its dimensions are.