Java Swing:获取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演示了如何在类

如何获得JFrame的
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);
            }
        });
    }
}