[英]How can I remove a JPanel from a JFrame?
最近我在这里问如何向 JFrame 添加新的 JPanel 。 答案帮助我获得了一个工作代码。 但不是我有一个相关的问题:“如何删除旧的 JPanel”。 由于以下问题,我需要它。
当我想要时会出现一个新的 JPanel(超过时间限制或用户按下“提交”按钮)。 但是在几秒钟内,旧 JPanel 的某些元素与新 JPanel 的组件一起出现。 我不明白为什么会这样。
我认为这是因为我必须更新窗口的其他线程。 但是第一个线程只添加了一次旧面板(因此,它应该完成)。 在第二个线程中,我有一个坏了的循环(因此,它也应该完成)。
这是我的代码:
private Thread controller = new Thread() {
public void run() {
// First we set the initial pane (for the selection of partner).
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generatePartnerSelectionPanel());
frame.invalidate();
frame.validate();
}
});
// Update the pane for the selection of the parnter.
for (int i=40; i>0; i=i-1) {
final int sec = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
timeLeftLabel.setText(sec + " seconds left.");
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) { }
if (partnerSubmitted) {
break;
}
}
// For the given user the selection phase is finished (either the time is over or form was submitted).
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(generateWaitForGamePanel());
frame.invalidate();
frame.validate();
}
});
}
};
从容器(框架)中删除组件(面板)的最简单方法是保留对它的引用,然后调用Container.remove(Component)
即:
private Thread controller = new Thread() {
public void run() {
final Component panel1 = generatePartnerSelectionPanel();
// First we set the initial pane (for the selection of partner).
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().add(panel1);
frame.invalidate();
frame.validate();
}
});
// Update the pane for the selection of the parnter.
for (int i=40; i>0; i=i-1) {
final int sec = i;
SwingUtilities.invokeLater(new Runnable() {
public void run() {
timeLeftLabel.setText(sec + " seconds left.");
}
});
try {Thread.sleep(1000);} catch (InterruptedException e) {}
if (partnerSubmitted) {break;}
}
// For the given user the selection phase is finished (either the time is over or form was submitted).
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame.getContentPane().remove(panel1);
frame.getContentPane().add(generateWaitForGamePanel());
frame.invalidate();
frame.validate();
}
});
}
};
我还没有测试过这段代码,但它应该可以工作。
无论您在可见 GUI 上添加还是删除组件,都是一样的:
panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();
我在TextField
上的requestFocusInWindow
也有问题。 诀窍是不要在JPanel
构造函数中构造组件。 但是,创建一个构建方法并在将其添加到框架后执行以下代码。
这对我有用:
frame.getContentPane().removeAll(); //or .remove(previousPanel);
frame.getContentPane().add(newPanel);
panel.buildPanel(); // panel needs a builder method
frame.revalidate(); // in- and validate in one !!
frame.pack(); //
如果你想调整大小,你需要preferredSize();
在面板上或使用repaint()
如果您不需要调整框架大小。
Roman,这个问题可以这样解决:
run
方法的开头执行此操作: final JPanel partnerSelectionPanel = generatePartnerSelectionPanel();
frame.getContentPane().add(partnerSelectionPanel);
partnerSelectionPanel.setVisible(false);
有用。 我不知道这是否是一个安全和/或优雅的解决方案,但它有效。
panel.invalidate();
panel.setVisible(false);
panel.removeAll();
frame.getContentPane().remove(panel);
panel = null;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.