[英]Display JPanel on another JFrame
當前狀態:我有一個JPanel對象,其中包含復雜的組件(我自己編寫的3D畫布)。
問題:現在有兩個屏幕設備。 我想用一個用於控制,另一個用於顯示,就像PowerPoint一樣。 如何有效地在另一個屏幕上顯示此JPanel(靜態視圖就足夠了,但我希望它反映控制屏幕上的更改?
我試過的:我試圖每隔200ms將靜態圖片繪制到另一個JPanel。
Graphics2D g2 = (Graphics2D) contentPanel.getGraphics();
g2.translate(x, y);
g2.scale(scale, scale);
displayPanel.paintAll(g2);
注意: contentPanel位於顯示屏幕的JFrame中,displayerPanel是我要復制的面板
但我得到一個問題,顯示屏閃爍如此嚴重,我不能接受這個......這是我的CPU或顯卡的問題? 或者這些是我可以使用的有效方法嗎? 請幫忙,非常感謝!
這是MCVE(對不起,這是我第一次在stackoverflow中提問,但我感動了你的幫助!再次感謝!)
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.Timer;
public class DisplayWindow {
private static JFrame frame = new JFrame();
private static JPanel contentPanel = new JPanel();
private static JPanel displayPanel = null;
private static Timer timerDisplay = null;
static {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(50, 50, 1366, 768);
frame.getContentPane().add(contentPanel);
frame.setVisible(true);
if (timerDisplay == null) {
timerDisplay = new java.util.Timer();
timerDisplay.schedule(new DisplayAtFixedRate(), 1000, 250);
}
}
public static void display(JPanel panel) {
displayPanel = panel;
}
private static class DisplayAtFixedRate extends TimerTask {
@Override
public void run() {
if (displayPanel != null && displayPanel.getWidth() != 0) {
double windowWidth = frame.getWidth();
double windowHeight = frame.getHeight();
double panelWidth = displayPanel.getWidth();
double panelHeight = displayPanel.getHeight();
double scale = Math.min(windowWidth / panelWidth, windowHeight / panelHeight);
int x = (int) (windowWidth - panelWidth * scale) / 2;
int y = (int) (windowHeight - panelHeight * scale) / 2;
Graphics2D g2 = (Graphics2D) contentPanel.getGraphics();
g2.translate(x, y);
g2.scale(scale, scale);
displayPanel.paintAll(g2);
}
}
}
public static void main(String[] args) {
JFrame controlFrame = new JFrame();
controlFrame.setBounds(50, 50, 1366, 768);
JPanel controlPanel = new JPanel();
controlFrame.getContentPane().add(controlPanel, BorderLayout.CENTER);
controlPanel.add(new JLabel("Hello Stackoverflow!"));
controlFrame.setVisible(true);
DisplayWindow.display(controlPanel);
}
}
這是一個例子:
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
來源在這里
可以通過傳遞displayPanel來繪制自己來完成繪畫。
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
或您自己的手動重繪。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.