Невозможно сделать скриншот JFrame Java Swing

Я попытался сохранить 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");
        }

Я пытаюсь сохранить снимок экрана следующим образом: введите здесь описание изображения

Я хотел бы, чтобы даже заголовок был на моем скриншоте

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();
    }

}
}

Но у меня образ не создается. Я не могу понять, почему. Я просмотрел это, но не могу понять, как включить его в мой случай.

Изменить

Основываясь на комментариях, я попытался использовать класс робота, но не знаю, откуда вызывать эту функцию. Если я вызову эту функцию из метода 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");
        }

    }

person Dinesh    schedule 24.02.2014    source источник
comment
Вы можете использовать класс робота. А затем проверить, где находится ваш кадр и его размер. Затем возьмите экран буферизованного изображения вашего приложения. И для этого требуется меньше кодирования.   -  person Tomas Bisciak    schedule 24.02.2014
comment
Не помещайте этот код в метод paintComponent, поместите его в другое место. Мне удалось сохранить панель в файле, однако, чтобы сохранить весь фрейм, вам нужно использовать Robot, потому что JFrame — это не JComponent, а компонент, см.: tips4java.wordpress.com/2008/10/13/screen-image   -  person DSquare    schedule 24.02.2014
comment
@DSquare Где я должен разместить свой код, используя класс робота?   -  person Dinesh    schedule 24.02.2014
comment
@TomasBisciak Пожалуйста, посмотрите мое редактирование   -  person Dinesh    schedule 25.02.2014
comment
Взгляните на этот пример и этот пример для сохранения изображений компонентов...   -  person MadProgrammer    schedule 25.02.2014
comment
Где угодно, поместите кнопку, создайте сочетание клавиш... Только не в середине ключевого метода. paintComponent рисует, компоненту не нужно делать скриншоты.   -  person DSquare    schedule 25.02.2014
comment
В вашем методе Main() после разделения Square. Сделайте фрейм глобальным (jFrame frame = null;), чтобы вы могли использовать его везде.   -  person JackTools.Net    schedule 25.02.2014


Ответы (1)


Есть как минимум два способа добиться этого...

Ты мог бы...

Используйте Robot, чтобы сделать снимок экрана. Для примера

Проблема в том, что требуется немного усилий, чтобы нацелить компонент, который вы хотите захватить. Он также захватывает только прямоугольную область, поэтому, если компонент прозрачен, Robot не будет соблюдать это...

Ты мог бы...

Используйте printAll для рендеринга компонента в вашем собственном Graphics контексте, обычно из BufferedImage

printAll позволяет вам распечатать компонент, потому что он не предназначен для печати на экране, printAll отключает двойную буферизацию, что делает его более эффективным для использования, когда вы не хотите отображать компонент на экране, например, распечатывать его на принтер...

Для примера

person MadProgrammer    schedule 24.02.2014