Java Swing';s GroupLayout和setContentPane-丢失组件?
经过实验后,我发现Swing的GroupLayout往往会丢失用于在GUI中重复使用的组件 但是我在文档中没有看到任何东西可以清楚地说明这个一次性使用规则。这让我怀疑我是否犯了一个错误,或者我是一个糟糕的读者 例如,我用JButton(“Foo”)的GroupLayout创建了一个JPanel。然后我制作了另一个JPanel,它的GroupLayout与重命名为“Bar”的JButton相同 如果我使用JFrame.setContentPane从第二个JPanel切换回第一个JPanel,我将丢失第一个JPanel中的JButton 有人能解释为什么会丢失组件吗?还有人能提供一种克服丢失组件趋势的方法吗 下面是一个完整的SSCCE,演示了该问题:Java Swing';s GroupLayout和setContentPane-丢失组件?,java,swing,grouplayout,contentpane,Java,Swing,Grouplayout,Contentpane,经过实验后,我发现Swing的GroupLayout往往会丢失用于在GUI中重复使用的组件 但是我在文档中没有看到任何东西可以清楚地说明这个一次性使用规则。这让我怀疑我是否犯了一个错误,或者我是一个糟糕的读者 例如,我用JButton(“Foo”)的GroupLayout创建了一个JPanel。然后我制作了另一个JPanel,它的GroupLayout与重命名为“Bar”的JButton相同 如果我使用JFrame.setContentPane从第二个JPanel切换回第一个JPanel,我将丢
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GroupLayoutTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
deployGroupLayoutTest();
}
});
}
static JPanel firstPanel;
static JButton jbtnActionLog;
static JFrame systemFrame;
public static void deployGroupLayoutTest() {
systemFrame = new JFrame("Group Layout Test");
systemFrame.setSize(300, 300);
firstPanel = new JPanel();
JMenuBar jmbSystem = new JMenuBar();
JMenu jmuAction = new JMenu("Action");
JMenuItem jmiActionLog = new JMenuItem("Login");
jmuAction.add(jmiActionLog);
jmbSystem.add(jmuAction);
jbtnActionLog = new JButton("Login");
jbtnActionLog.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setContentPaneToSecondPanel();
}
});
systemFrame.setJMenuBar(jmbSystem);
GroupLayout gl = new GroupLayout(firstPanel);
firstPanel.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setAutoCreateGaps(true);
GroupLayout.ParallelGroup hGroup = gl.createParallelGroup(GroupLayout.Alignment.CENTER);
hGroup
.addComponent(jbtnActionLog);
gl.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();
vGroup
.addComponent(jbtnActionLog);
gl.setVerticalGroup(vGroup);
systemFrame.getContentPane().add(firstPanel);
systemFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
systemFrame.setLocationByPlatform(true);
systemFrame.setVisible(true);
}
public static void setContentPaneToSecondPanel() {
jbtnActionLog.setText("Logout");
ActionListener[] listenerList = jbtnActionLog.getActionListeners();
jbtnActionLog.removeActionListener(listenerList[0]);
jbtnActionLog.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
systemFrame.setContentPane(firstPanel);
systemFrame.revalidate();
}
});
JPanel secondPanel = new JPanel();
GroupLayout gl = new GroupLayout(secondPanel);
secondPanel.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setAutoCreateGaps(true);
GroupLayout.ParallelGroup hGroup = gl.createParallelGroup(GroupLayout.Alignment.CENTER);
hGroup
.addComponent(jbtnActionLog);
gl.setHorizontalGroup(hGroup);
GroupLayout.SequentialGroup vGroup = gl.createSequentialGroup();
vGroup
.addComponent(jbtnActionLog);
gl.setVerticalGroup(vGroup);
systemFrame.setContentPane(secondPanel);
systemFrame.revalidate();
}
}我没有阅读您的所有代码,但是不可能将单个Swing组件添加到多个父级。每个组件只能出现在Swing层次结构中的一个位置。那么代码呢
JPanel firstPanel = ...;
JPanel secondPanel = ...;
JButton button = ...;
firstPanel.add( button );
secondPanel.add( button );
将导致按钮
仅包含在其中一个面板中,而不是同时包含在两个面板中。这与GroupLayout
无关
相关文档包含指向以下内容的链接:
每个GUI组件只能包含一次。如果一个组件已经在一个容器中,并且您尝试将其添加到另一个容器中,那么该组件将从第一个容器中删除,然后添加到第二个容器中
啊哈!谢谢你解释这个问题。我想问题的答案是生成新组件,但使用相同的操作或ActionListener+1以获得清晰而有指导性的答案。