我有一个名为BigPanel的JPanel子类作为JFrame的内容窗格,BigPanel对象中有一个嵌套的JPanel子类。在单击按钮时,嵌套面板应从一个JPanel子类更改为另一个。嵌套面板没有重置,正确的子类将打印到控制台,但实际的面板不会更新 包com.grantbroadwater;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BigPanel extends JPanel {
private static final long serialVersionUID = 1L;
public static final int DIM = GUIFrame.DIM;
private JPanel pnl1;
public BigPanel() {
super(null);
setSize(new Dimension(DIM, DIM));
setBackground(Color.WHITE);
JLabel lbl = new JLabel("Big Panel");
lbl.setBounds(20, 20, 100, 20);
add(lbl);
JButton btn = new JButton("Change");
btn.setBounds(140, 20, 100, 20);
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(pnl1 instanceof SubPanelOne){
update(new SubPanelTwo());
}else if(pnl1 instanceof SubPanelTwo){
update(new SubPanelOne());
}
}
});
add(btn);
pnl1 = new SubPanelOne();
pnl1.setLocation(20, 100);
add(pnl1);
}
private void update(JPanel pnl){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.print("Pnl1 is of type "+pnl1.getClass());
pnl1 = pnl;
revalidate();
repaint();
pnl1.revalidate();
pnl1.repaint();
System.out.println(" changing to " + pnl1.getClass());
}
});
}
}
答案 0 :(得分:2)
null
布局,像素完美布局是现代ui设计中的错觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的结束,您将花费越来越多的时间来纠正CardLayout
来实现您的目标,这就是它的设计目标。有关详细信息,请参阅How to Use CardLayout 核心问题似乎是缺乏对变量引用如何工作的理解......
pnl1 = pnl;
revalidate();
repaint();
pnl1.revalidate();
pnl1.repaint();
所有这一切都会将pnl1
在内存中指向的内容更改为pnl
在内存中指向的内容。它不会影响屏幕上的任何内容。您实际上必须删除pnl1
并添加pnl
才能进行任何更改。
随着布局管理器的丢弃,这会增加复杂性,因为每次尝试切换时都需要更新每个组件的大小和位置。
invalidate
,revalidate
和validate
都与布局管理API相关。如果你要选择忽略它,它们真的没什么意义。