[英]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.