简体   繁体   English

无法拍摄JFrame Java Swing的屏幕截图

[英]Unable Take screenshot of JFrame Java Swing

I have tried to save the JFrame as an image using the following approach. 我尝试使用以下方法将JFrame保存为图像。

        try
        {
            BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
            this.paint(image.getGraphics());
            ImageIO.write(image,"png", new File("Test.png"));
        }
        catch(Exception exception)
        {
            //code
            System.out.print("Exception unable to write image");
        }

I am trying to save a screenshot as follows: 我正在尝试将屏幕截图保存如下: 在此处输入图片说明

I would like to have even the title in my screenshot 我甚至想在屏幕截图中显示标题

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DividedSquare {

public static void main(String[] args) {
    new DividedSquare();
}

public DividedSquare() {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            }

            JFrame frame = new JFrame("Testing");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new TestPane());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    });
}

public class TestPane extends JPanel {

    private TriangleShape baseTriangle;
    private Color[] colors;

    public TestPane() {
        colors = new Color[]{Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA};
    }

    @Override
    public void invalidate() {
        super.invalidate();

        baseTriangle = new TriangleShape(
                new Point(0, 0),
                new Point(getWidth(), 0),
                new Point(getWidth() / 2, getHeight() / 2));

    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();

        String text[] = new String[]{
            "123.123",
            "456.789",
            "012.315",
            "678.921"
        };

        FontMetrics fm = g2d.getFontMetrics();

        double angel = 0;
        for (int index = 0; index < 4; index++) {
            g2d.setColor(colors[index]);
            Path2D rotated = rotate(baseTriangle, angel);
            g2d.fill(rotated);
            Rectangle bounds = rotated.getBounds();
            int x = bounds.x + ((bounds.width - fm.stringWidth(text[0])) / 2);
            int y = bounds.y + (((bounds.height - fm.getHeight()) / 2) + fm.getAscent());
            g2d.setColor(Color.WHITE);
            g2d.drawString(text[index], x, y);
            angel += 90;
        }
        g2d.setColor(Color.BLACK);
        g2d.drawLine(0, 0, getWidth(), getHeight());
        g2d.drawLine(getWidth(), 0, 0, getHeight());
        g2d.dispose();


        try
        {
            BufferedImage image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
            frame.paint(image.getGraphics());
            ImageIO.write(image,"png", new File("Practice.png"));
        }
        catch(Exception exception)
        {
            //code
            System.out.print("Exception to write image");
        }


    }

    public Path2D rotate(TriangleShape shape, double angel) {

        Rectangle bounds = shape.getBounds();
        int x = bounds.width / 2;
        int y = bounds.width / 2;

        return new Path2D.Float(shape, AffineTransform.getRotateInstance(
                Math.toRadians(angel),
                x,
                y));

    }

}

public class TriangleShape extends Path2D.Double {

    public TriangleShape(Point2D... points) {
        moveTo(points[0].getX(), points[0].getY());
        lineTo(points[1].getX(), points[1].getY());
        lineTo(points[2].getX(), points[2].getY());
        closePath();
    }

}
}

But I the image does not get created. 但是我没有创建图像。 I am unable to understand why. 我不明白为什么。 I looked at this but am unable to understand how to incorporate it in my case. 我查看了此内容,但无法理解如何将其合并到我的案例中。

Edit 编辑

Based on comments, I tried using robot class but am unable to know where to call this function from. 根据评论,我尝试使用机械手类,但无法知道从何处调用此函数。 If I call this function from the paint() method, I am unable to get the colors and text. 如果我从paint()方法调用此函数,则无法获取颜色和文本。

    void screenshot()
    {
        try
        {

            Robot robot = new Robot();
            // Capture the screen shot of the area of the screen defined by the rectangle
            Point p = frame.getLocationOnScreen();
            System.out.print("point" + p);
            BufferedImage bi=robot.createScreenCapture(new Rectangle((int)p.getX(),(int)p.getY(),frame.getWidth(),frame.getHeight()));
            ImageIO.write(bi, "png", new File("imageTest.png"));

        }
        catch(Exception exception)
        {
            //code
            System.out.print("Exception to write image");
        }

    }

There are at least two ways you might achieve this... 至少有两种方法可以实现此目标...

You Could... 你可以...

Use Robot to capture a screen shot. 使用Robot捕获屏幕快照。 For example 举个例子

The problem with this is it takes a little effort to target the component you want to capture. 这样做的问题是,将精力集中在要捕获的组件上。 It also only captures a rectangular area, so if the component is transparent, Robot won't respect this... 它也只捕获一个矩形区域,因此,如果组件是透明的, Robot不会尊重这一点。

You Could... 你可以...

Use printAll to render the component to your own Graphics context, typically from a BufferedImage 使用printAll将组件呈现到您自己的Graphics上下文中,通常从BufferedImage呈现

printAll allows you to print a component, because the intention is not to print this to the screen, printAll disables double buffering, making it more efficient to use when you don't want to render the component to the screen, such printing it to a printer... printAll允许您打印组件,因为其目的不是将其打印到屏幕上, printAll禁用双重缓冲,从而在您不希望将组件渲染到屏幕上时将其更有效地使用,例如将其打印到屏幕上。打印机...

For example 举个例子

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM