(disclamer: woops.. this doesn't seem to work for AWT )-:
I can't believe no one has suggested SwingUtilities.paintComponent
or CellRendererPane.paintComponent
which are made for this very purpose. From the documentation of the former:
Paints a component to the specified Graphics
. This method is primarily useful to render Components that don't exist as part of the visible containment hierarchy, but are used for rendering.
Here is an example method that paints a non-visible component onto an image:
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class ComponentPainter {
public static BufferedImage paintComponent(Component c) {
// Set it to it's preferred size. (optional)
c.setSize(c.getPreferredSize());
layoutComponent(c);
BufferedImage img = new BufferedImage(c.getWidth(), c.getHeight(),
BufferedImage.TYPE_INT_RGB);
CellRendererPane crp = new CellRendererPane();
crp.add(c);
crp.paintComponent(img.createGraphics(), c, crp, c.getBounds());
return img;
}
// from the example of user489041
public static void layoutComponent(Component c) {
synchronized (c.getTreeLock()) {
c.doLayout();
if (c instanceof Container)
for (Component child : ((Container) c).getComponents())
layoutComponent(child);
}
}
}
Here is a snippet of code that tests the above class:
JPanel p = new JPanel();
p.add(new JButton("Button 1"));
p.add(new JButton("Button 2"));
p.add(new JCheckBox("A checkbox"));
JPanel inner = new JPanel();
inner.setBorder(BorderFactory.createTitledBorder("A border"));
inner.add(new JLabel("Some label"));
p.add(inner);
BufferedImage img = ComponentPainter.paintComponent(p);
ImageIO.write(img, "png", new File("test.png"));
And here is the resulting image:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…