我有一个简单的问题。如何获取JComponent.paint或paintComponent生成的图像?
我有一个JComponent,我将其用作'工作区',并且我已将paintComponent方法覆盖到我自己的方法中。问题是我的工作区JComponent也有子项,它们有自己的paintComponent方法。
因此,当Swing渲染我的工作区组件时,它会渲染工作区图形,然后渲染其子图形。
但是,我想获取工作区组件生成的图像(包括工作区图形和子图形)。
我该怎么做?
我尝试使用自己的Graphics自己调用paintComponent / paint-method,但我刚刚返回了一个黑色图像。这是我试过的;
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;
}
欢迎任何想法或意见! :)
答案 0 :(得分:3)
如果过早调用getImage,您的组件将不会显示,并且仍然具有0宽度和高度。你确定你在很晚的时候打电话吗?尝试将组件的大小打印到标准输出并查看其尺寸。
答案 1 :(得分:1)
似乎问题是由于BufferedImage的创建方式。使用时:
BufferedImage hello = bufferedImage.getSubimage(0,0, getWidth(), getHeight());
相反,它有效。我还必须将开关从paintComponent更改为paint来渲染子项。
问题解决了,但是如果有人知道的话。为什么我的:
BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
始终渲染黑色图像? Offtopic,但可能有趣的是知道:)
答案 2 :(得分:0)
不要从外部调用paintComponent()或paint()。相反,让您的图像在那些(覆盖的)方法中创建。然后,您可以确定您的图像实际上包含组件的绘制内容。
这是一个示例应用程序。 ImagePanel实际上会在每次绘制时抓取组件的图形内容,这可能有点浪费,因此您可能需要调整完成此操作的频率。
public class SomeApp extends JFrame {
private static class ImagePanel extends JPanel {
private BufferedImage currentImage;
public BufferedImage getCurrentImage() {
return currentImage;
}
@Override
public void paint(Graphics g) {
Rectangle tempBounds = g.getClipBounds();
currentImage = new BufferedImage(tempBounds.width, tempBounds.height, BufferedImage.TYPE_INT_ARGB);
super.paint(g);
super.paint(currentImage.getGraphics());
}
}
public SomeApp() {
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(800,600);
int matrixSize = 4;
setLayout(new BorderLayout());
add(new JLabel("Wonderful Application"), BorderLayout.NORTH);
final ImagePanel imgPanel = new ImagePanel();
imgPanel.setLayout(new GridLayout(matrixSize,matrixSize));
for(int i=1; i<=matrixSize*matrixSize; i++) {
imgPanel.add(new JButton("A Button" + i));
}
add(imgPanel, BorderLayout.CENTER);
final JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new AbstractAction("get image") {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(SomeApp.this, new ImageIcon(imgPanel.getCurrentImage()));
}
}));
add(buttonPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SomeApp().setVisible(true);
}
});
}
}
就像Martijn所说,你的图像可能是黑色的,因为该组件甚至还没有绘制/显示。您可以添加ComponentListener以在显示时收到通知。 getSubimage的“解决方案”与实际问题无关。我建议你将其删除。
答案 3 :(得分:0)
将新的BufferedImage更改为TYPE_INT_RGB可以解决这个问题。我不能给出解释 - 只是一个Swing之谜。
public BufferedImage getImage() {
BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = hello.getGraphics();
paintComponent( g );
return hello;
}