Component
有一个方法(正如你已经发现的)。该方法将在传递的图形上绘制自身。但是,在调用 paint 方法之前,我们必须预先配置图形。这就是我在 java.sun.com 中发现的关于AWT组件渲染的内容:paintAll(Graphics)
当 AWT 调用此方法时,图形对象参数已预先配置为在此特定组件上进行绘制的适当状态:
- 图形对象的颜色设置为组件的前景属性。
- 图形对象的字体设置为组件的 font 属性。
- Graphics 对象的平移设置为坐标 (0,0) 表示组件的左上角。
- Graphics 对象的剪辑矩形设置为需要重新绘制的组件区域。
所以,这是我们得到的方法:
public static BufferedImage componentToImage(Component component, Rectangle region)
{
BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = img.getGraphics();
g.setColor(component.getForeground());
g.setFont(component.getFont());
component.paintAll(g);
g.dispose();
if (region == null)
{
return img;
}
return img.getSubimage(region.x, region.y, region.width, region.height);
}
这也是比用于可见组件更好的方法。Robot
编辑:
很久以前,我使用了上面在这里发布的代码,它有效,但现在不行了。所以我进一步搜索。我有一个经过测试的工作方式。它很脏,但有效。它的想法是制作一个JDialog,把它放在屏幕边界之外的某个地方,将其设置为可见,然后在图形上绘制它。
代码如下:
public static BufferedImage componentToImageWithSwing(Component component, Rectangle region) {
BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = img.createGraphics();
// Real render
if (component.getPreferredSize().height == 0 && component.getPreferredSize().width == 0)
{
component.setPreferredSize(component.getSize());
}
JDialog f = new JDialog();
JPanel p = new JPanel();
p.add(component);
f.add(p);
f.pack();
f.setLocation(-f.getWidth() - 10, -f.getHeight() -10);
f.setVisible(true);
p.paintAll(g);
f.dispose();
// ---
g.dispose();
if (region == null) {
return img;
}
return img.getSubimage(region.x, region.y, region.width, region.height);
}
因此,这也适用于Windows和Mac。另一个答案是在虚拟屏幕上绘制它。但这并不需要它。