简体   繁体   中英

Unable Take screenshot of JFrame Java Swing

I have tried to save the JFrame as an image using the following approach.

        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.

    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. 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...

You Could...

Use printAll to render the component to your own Graphics context, typically from a 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...

For example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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