Java 复制JPanel-(将JPanel的静态图像复制到不同的JPanel)
我对swing是个新手,我想在我被任务缠住的时候得到一些帮助 当前状态: 我有一个漂亮的Java 复制JPanel-(将JPanel的静态图像复制到不同的JPanel),java,swing,clone,Java,Swing,Clone,我对swing是个新手,我想在我被任务缠住的时候得到一些帮助 当前状态: 我有一个漂亮的JFrame对象(guiFrame),上面有两个JPanel(tabsPanel和cardPanel)(一个是带按钮的简单JPanel,另一个有cardplayout,由tabsPanel按钮切换) 问题: 任务是,如果我按下tabsPanel上的“显示”按钮,我需要将cardPanel以静态“图像”的形式发送到另一个窗口(ShowFrame),而在上一个窗口上,程序仍在运行且状态良好。因此,基本上我正在尝试
JFrame
对象(guiFrame),上面有两个JPanel
(tabsPanel和cardPanel)(一个是带按钮的简单JPanel
,另一个有cardplayout
,由tabsPanel按钮切换)
问题:
任务是,如果我按下tabsPanel上的“显示”按钮,我需要将cardPanel以静态“图像”的形式发送到另一个窗口(ShowFrame),而在上一个窗口上,程序仍在运行且状态良好。因此,基本上我正在尝试复制/克隆cardPanel
我尝试过的:
- 我试着简单地
当然不工作,因为参考号正在被复制,如果我运行程序,cardPanel“消失”JPanel jPanelShow = cardPanel; show.add(jPanelShow);
- 我已尝试使用
为此,它几乎可以工作,但我得到了一些奇怪的clone()
,这不是由我的代码引起的NullPointerException
/**
* This is basicly a JPanel, just with a clone() implemented
*/
package javaapplication5;
import javax.swing.JPanel;
import java.util.Stack;
public class CardPanel extends JPanel implements Cloneable {
public CardPanel() {
super();
}
@Override
public CardPanel clone() throws NullPointerException {
/* Creating return object */
final CardPanel copy;
try {
/* Cloning */
copy = (CardPanel) super.clone();
} catch (CloneNotSupportedException e) {
/* Exception (should not happen though) */
e.printStackTrace();
return null;
}
return copy;
}
}
CardLayoutExample.java
package javaapplication5;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
public class CardLayoutExample {
JFrame guiFrame;
CardLayout cards;
CardPanel cardPanel;
private int showFrameNotShownYet = 1;
public ShowFrame show = new ShowFrame();
public static void main(String[] args) {
/* Random things for Swing */
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
new CardLayoutExample();
}
});
}
public CardLayoutExample()
{
/* Creating the main JFrame */
guiFrame = new JFrame();
/* Making sure the program exits when the frame closes */
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("CardLayout Example");
guiFrame.setSize(400,300);
/* This will center the JFrame in the middle of the screen */
guiFrame.setLocationRelativeTo(null);
guiFrame.setLayout(new BorderLayout());
/* Border for JPanel separation */
Border outline = BorderFactory.createLineBorder(Color.black);
/* Creating JButton1 for tabsPanel */
JButton switchCards1 = new JButton("1");
switchCards1.setActionCommand("1");
switchCards1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
cards.show(cardPanel, "TestContent");
}
});
/* Creating JButton2 for tabsPanel */
JButton switchCards2 = new JButton("2");
switchCards2.setActionCommand("2");
switchCards2.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
cards.show(cardPanel, "TestContent1");
}
});
/* Creating JButton3 for tabsPanel */
JButton switchCards3 = new JButton("3");
switchCards3.setActionCommand("3");
switchCards3.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
cards.show(cardPanel, "TestContent2");
}
});
JButton switchCards4 = new JButton("Show");
switchCards4.setActionCommand("Show");
switchCards4.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
/* If there is no ShowFrame yet */
if(showFrameNotShownYet == 1){
show.add((JPanel)cardPanel.clone());
show.setVisible(true);
showFrameNotShownYet = 0;
}
/* If there is a ShowFrame already */
else {
show.setVisible(false);
showFrameNotShownYet = 1;
guiFrame.repaint();
}
}
});
JButton switchCards5 = new JButton("Refresh");
switchCards5.setActionCommand("Refresh");
switchCards5.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
show.setVisible(false);
show.add((JPanel)cardPanel.clone());
show.setVisible(true);
showFrameNotShownYet = 0;
}
});
/* Creating JPanel for buttons */
JPanel tabsPanel = new JPanel();
tabsPanel.setBorder(outline);
tabsPanel.add(switchCards1);
tabsPanel.add(switchCards2);
tabsPanel.add(switchCards3);
tabsPanel.add(switchCards4);
tabsPanel.add(switchCards5);
/* Creating JPanel for CardLayout */
cards = new CardLayout();
cardPanel = new CardPanel();
cardPanel.setLayout(cards);
cards.show(cardPanel, "TestContent");
/* Adding 1st card */
JPanel firstCard = new TestContent();
cardPanel.add(firstCard, "TestContent");
/* Adding 2nd card */
JPanel secondCard = new TestContent1();
cardPanel.add(secondCard, "TestContent1");
/* Adding 3rd card */
JPanel thirdCard = new TestContent2();
cardPanel.add(thirdCard, "TestContent2");
/* Filling up JFrame with stuff */
guiFrame.add(tabsPanel,BorderLayout.NORTH);
guiFrame.add(cardPanel,BorderLayout.CENTER);
guiFrame.setVisible(true);
}
}
TestContent、TestContent1和TestContent2是简单的JPanel,带有SwingGUI生成的随机内容,就像ShowFrame是空的JFrame一样。但如果需要,我也会粘贴这些代码。如果您只需要cardPanel
的“图像”,您只需创建图像并使用JLabel
来显示,例如
BufferedImage img = new BufferedImage(cardPanel.getWidth(), cardPane.getHeight(), BufferedImage.BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
cardPanel.printAll(g2d);
g2d.dispose();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.DIPOSE_ON_CLOSE);
frame.add(new JLabel(new ImageIcon(img)));
frame.pack();
frame.setLocationRelativeTo(this);
frame.setVisible(true);
现在您有了cardPanel
的“副本”,您只需使用JLabel
即可显示它,例如
BufferedImage img = new BufferedImage(cardPanel.getWidth(), cardPane.getHeight(), BufferedImage.BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
cardPanel.printAll(g2d);
g2d.dispose();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.DIPOSE_ON_CLOSE);
frame.add(new JLabel(new ImageIcon(img)));
frame.pack();
frame.setLocationRelativeTo(this);
frame.setVisible(true);
切勿对swing组件使用克隆方法。此方法继承自类对象,如果使用它,将得到完全错误的组件层次结构。”任务是,如果我按tabsPanel上的按钮“Show”,我需要将cardPanel作为静态“图像”发送到其他窗口(ShowFrame)“为什么是静态”而不是动画?为什么要“克隆”它(视觉上或任何其他意义上的)?顺便说一句,对于经验丰富的开发人员来说,这听起来是一项复杂的任务。对于一个“刚刚开始荡秋千”的人来说,这是无法承受的。也许你应该做更多(标准)和更简单的项目一段时间。当我按下显示按钮时,我想发送cardPanel的最新状态,我不愿意更新它。即使我将在主窗口上工作并在卡之间切换,我仍然希望在新的showFrame对象上显示“先前”状态,而不会发生任何变化。这就是“刷新”按钮稍后将要使用的功能。这是我愿意作为替代解决方案来做的,但如果可能的话,我希望避免这样做,因为这不是解决问题的“好方法”,而是一种解决方法。与尝试克隆UI组件不同,包括它的整个组件层次结构和状态…好吧…耶,我也不愿意做深度复制,因为它超出了我的技能水平。寻找第三种解决方案(如果有的话)。如果您不要求用户与“克隆”进行交互,那么创建快照是您可用的最简单的解决方案,我可能会选择。非常感谢。