Java 在另一个JFrame上显示JPanel

Java 在另一个JFrame上显示JPanel,java,swing,jpanel,screenshot,multiple-monitors,Java,Swing,Jpanel,Screenshot,Multiple Monitors,当前状态: 我有一个包含复杂组件的JPanel对象(我自己编写的3D画布) 问题: 现在有两个屏幕设备。我想使用一个控件,另一个仅用于显示,就像PowerPoint一样。如何在另一个屏幕上高效地显示这个JPanel(静态视图已经足够了,但我希望它能反映控制屏幕上的变化 我尝试过的: 我曾尝试每隔200毫秒将静态图片绘制到另一个JPanel Graphics2D g2 = (Graphics2D) contentPanel.getGraphics();

当前状态: 我有一个包含复杂组件的JPanel对象(我自己编写的3D画布)

问题: 现在有两个屏幕设备。我想使用一个控件,另一个仅用于显示,就像PowerPoint一样。如何在另一个屏幕上高效地显示这个JPanel(静态视图已经足够了,但我希望它能反映控制屏幕上的变化

我尝试过的:
我曾尝试每隔200毫秒将静态图片绘制到另一个JPanel

            Graphics2D g2 = (Graphics2D) contentPanel.getGraphics();
            g2.translate(x, y);
            g2.scale(scale, scale); 
            displayPanel.paintAll(g2);
注意:contentPanel位于显示屏的JFrame中,displayerPanel是我要复制的面板

但是我遇到了一个问题,显示屏闪烁非常严重,我无法接受……这是我的CPU或图形卡的问题吗?或者这些是我可以使用的有效方法吗?请帮助,非常感谢

这是MCVE(对不起,这是我第一次在stackoverflow中提问,但我被你们的帮助感动了!再次感谢!)


下面是一个例子:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class PaintImage {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                startUI();
            }
        });
    }

    private static void startUI() {
        final JFrame mainFrm = new JFrame("Main");
        final JFrame paintFrame = new JFrame("Copy");
        mainFrm.add(new JScrollPane(new JTree()), BorderLayout.WEST);
        mainFrm.add(new JScrollPane(new JTextArea("Write your text here...")), BorderLayout.CENTER);
        mainFrm.pack();
        mainFrm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        mainFrm.setLocationRelativeTo(null);

        final JLabel label = new JLabel("");
        paintFrame.add(label);
        paintFrame.setSize(mainFrm.getSize());
        paintFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        mainFrm.setVisible(true);
        paintFrame.setVisible(true);

        final Timer t = new Timer(200, new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                final Image img = getScreenShot(mainFrm.getContentPane());
                label.setIcon(new ImageIcon(img));
            }
        });
        t.start();
    }

    public static BufferedImage getScreenShot(Component component) {

        final BufferedImage image = new BufferedImage(
                component.getWidth(),
                component.getHeight(),
                BufferedImage.TYPE_INT_RGB
                );
        // call the Component's paint method, using
        // the Graphics object of the image.
        component.paint( image.getGraphics() ); // alternately use .printAll(..)
        return image;
    }
}

方法
getScreenShot
的起源是可以通过显示面板来绘制自己

class DuplicatePanel extends JPanel {
    private final JPanel displayPanel;

    DuplicatePanel(JPanel displayPanel) {
        this.displayPanel = displayPanel;
    }

    @Override
    public void paintComponent(Graphics g) {
        displayPanel.paintComponent(g);
    }
}

要触发重绘,如
repaint(50L)
使用
SwingTimer
或您自己的手动重绘。

您是否需要在每次触发计时器时进行平移和缩放?可能在面板上调用repaint会导致较少的闪烁,因为它不会涉及组件的大小调整等。1)为了更快地获得更好的帮助,发布或。2) 我试着每隔200毫秒将静态图片绘制到另一个JPanel上您是否尝试使用SwingTImer,因为来自TimerTask的信号不会通知EDT
Graphics2D g2=(Graphics2D)contentPanel.getGraphics()否。这是做定制绘画的错误方式。浏览本教程的课程,了解如何正确操作。我看到了您的编辑,但MCVE在哪里?太棒了!使用您的示例,它的性能要好得多!我认为摇摆时间是关键问题。非常感谢!
class DuplicatePanel extends JPanel {
    private final JPanel displayPanel;

    DuplicatePanel(JPanel displayPanel) {
        this.displayPanel = displayPanel;
    }

    @Override
    public void paintComponent(Graphics g) {
        displayPanel.paintComponent(g);
    }
}