Java Swing:获取JFrame的图像
如何获得JFrame的Java Swing:获取JFrame的图像,java,image,swing,screenshot,jframe,Java,Image,Swing,Screenshot,Jframe,如何获得JFrame的java.awt.Image 我想获得JFrame的屏幕截图(供以后在我的应用程序中使用)。目前,这是通过使用机器人进行屏幕截图来完成的,其中指定了所涉及的JFrame的坐标和尺寸 但是,我相信有一种更好的方法:在默认情况下,Swing组件在将自己绘制到屏幕上之前,将自己作为图像渲染到双缓冲区中 有没有办法从组件获取这些图像?ComponentImageCapture.java 截屏 另见 上面显示的代码假定组件在渲染之前已在屏幕上实现 Rob Camick演示了如何在类
java.awt.Image
我想获得JFrame
的屏幕截图(供以后在我的应用程序中使用)。目前,这是通过使用机器人进行屏幕截图来完成的,其中指定了所涉及的JFrame
的坐标和尺寸
但是,我相信有一种更好的方法:在默认情况下,Swing组件在将自己绘制到屏幕上之前,将自己作为图像渲染到双缓冲区中
有没有办法从组件获取这些图像?ComponentImageCapture.java
截屏
另见
上面显示的代码假定组件在渲染之前已在屏幕上实现
Rob Camick演示了如何在类中绘制未实现的组件
另一个可能相关的线索是,特别是Darryl Burke的“一行修复”
LabelRenderTest.java
下面是第二个链接上显示的代码的更新版本
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class LabelRenderTest {
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
String title = "<html><body style='width: 200px; padding: 5px;'>"
+ "<h1>Do U C Me?</h1>"
+ "Here is a long string that will wrap. "
+ "The effect we want is a multi-line label.";
JFrame f = new JFrame("Label Render Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage image = new BufferedImage(
400,
300,
BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = image.createGraphics();
GradientPaint gp = new GradientPaint(
20f,
20f,
Color.red,
380f,
280f,
Color.orange);
imageGraphics.setPaint(gp);
imageGraphics.fillRect(0, 0, 400, 300);
JLabel textLabel = new JLabel(title);
textLabel.setSize(textLabel.getPreferredSize());
Dimension d = textLabel.getPreferredSize();
BufferedImage bi = new BufferedImage(
d.width,
d.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
g.setColor(new Color(255, 255, 255, 128));
g.fillRoundRect(
0,
0,
bi.getWidth(f),
bi.getHeight(f),
15,
10);
g.setColor(Color.black);
textLabel.paint(g);
Graphics g2 = image.getGraphics();
g2.drawImage(bi, 20, 20, f);
ImageIcon ii = new ImageIcon(image);
JLabel imageLabel = new JLabel(ii);
f.getContentPane().add(imageLabel);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}
import java.awt.*;
导入java.awt.image.buffereImage;
导入javax.swing.*;
公共类LabelRenderTest{
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
String title=“”
+“你喜欢我吗?”
+“这是一条可以缠绕的长字符串。”
+“我们想要的效果是多行标签。”;
JFrame f=新JFrame(“标签渲染测试”);
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BuffereImage=新的BuffereImage(
400,
300,
BuffereImage.TYPE_INT_RGB);
Graphics2D imageGraphics=image.createGraphics();
GradientPaint gp=新的GradientPaint(
20楼,
20楼,
颜色,红色,
380f,
280f,
颜色(橙色);
图像图形.setPaint(gp);
imageGraphics.fillRect(0,0,400,300);
JLabel textLabel=新的JLabel(标题);
textLabel.setSize(textLabel.getPreferredSize());
维度d=textLabel.getPreferredSize();
BuffereImage bi=新的BuffereImage(
d、 宽度,
d、 高度,
BuffereImage.TYPE_INT_ARGB);
Graphics g=bi.createGraphics();
g、 setColor(新颜色(255、255、255、128));
g、 fillRoundRect(
0,
0,
bi.getWidth(f),
bi.getHeight(f),
15,
10);
g、 设置颜色(颜色为黑色);
textLabel.paint(g);
Graphics g2=image.getGraphics();
g2.绘图图像(bi,20,20,f);
ImageIcon ii=新的ImageIcon(图像);
JLabel imageLabel=新的JLabel(ii);
f、 getContentPane().add(imageLabel);
f、 包装();
f、 setLocationByPlatform(真);
f、 setVisible(真);
}
});
}
}
截屏
+1@Andrew:谢谢你的回答,这肯定比使用机器人好。H/w
component.paint(image.getGraphics())代码>仍然涉及制作图像的副本
。我正在寻找一种直接从缓冲区获取图像的方法,如果确实可行的话。如果没有人回答这个问题,我就接受你的回答!只是好奇:为什么要使用p.validate?@kleopatra:我能想到的最好的解释(很久以前写过该代码)是,我的第一次尝试是在组件实现之前获取其图像。据我推断,那是行不通的。删除了那一行,增加了“另请参阅”部分来处理那个角落的案子。我有一个疑问。我试图删除label.setSize()
方法,但JLabel
上的文本没有出现?为什么会这样?(谢谢。+1)print或printAll代替paint会更有效,因为它们不是双缓冲是的Swing组件可以自己渲染,但JFrame不是Swing组件,因此如果您还想捕获标题栏,则需要使用Robot。当然,如果您使用:JFrame.setDefaultLookAndFeelDecorated(true);然后您应该能够渲染整个框架。对于未来的读者:JFrame是而且一直是swing组件。上述评论是错误的。
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class LabelRenderTest {
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
String title = "<html><body style='width: 200px; padding: 5px;'>"
+ "<h1>Do U C Me?</h1>"
+ "Here is a long string that will wrap. "
+ "The effect we want is a multi-line label.";
JFrame f = new JFrame("Label Render Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage image = new BufferedImage(
400,
300,
BufferedImage.TYPE_INT_RGB);
Graphics2D imageGraphics = image.createGraphics();
GradientPaint gp = new GradientPaint(
20f,
20f,
Color.red,
380f,
280f,
Color.orange);
imageGraphics.setPaint(gp);
imageGraphics.fillRect(0, 0, 400, 300);
JLabel textLabel = new JLabel(title);
textLabel.setSize(textLabel.getPreferredSize());
Dimension d = textLabel.getPreferredSize();
BufferedImage bi = new BufferedImage(
d.width,
d.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics();
g.setColor(new Color(255, 255, 255, 128));
g.fillRoundRect(
0,
0,
bi.getWidth(f),
bi.getHeight(f),
15,
10);
g.setColor(Color.black);
textLabel.paint(g);
Graphics g2 = image.getGraphics();
g2.drawImage(bi, 20, 20, f);
ImageIcon ii = new ImageIcon(image);
JLabel imageLabel = new JLabel(ii);
f.getContentPane().add(imageLabel);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}