2013-01-11 65 views
4

我有一個相對較小的類稱爲「LoadingWindow」這個類有一個構造函數調用Initialize函數來設置框架。不是我正在測試一些東西,試圖解決爲什麼它不會更新。在測試中,我添加了「this.removeAll();」到初始化方法的頭部。事實證明,我不能在此之後添加任何內容。我添加的任何內容都不會顯示。無法添加到JFrame後removeAll()

下面是類的略微下調版本:

public class LoadingWindow extends JFrame{ 

public JPanel panel; 

public JProgressBar bar; 

private JLabel label; 

public LoadingWindow() 
{ 

    this.Initialize(); 

} 

public void Initialize() 
{ 
    this.removeAll(); 

    this.setSize(300, 150); 

    panel = new JPanel(new BorderLayout()); 
    bar = new JProgressBar(0,100); 
    label = new JLabel("Please remain calm, we're just loading..."); 

    panel.add(bar,BorderLayout.CENTER); 
    panel.add(label,BorderLayout.SOUTH); 

    this.add(panel); 

    this.validate(); 
    this.repaint(); 
    this.setVisible(true); 
} 
} 

本身並正確彈出,帶有標題的窗口。但窗口本身是完全空白的。

我靜態實現此類,以便其他四個對象可以在EditorPanel類中訪問它。它的定義爲:

public static LoadingWindow loadingWindow; 

,並在構造函數初始化所用:

loadingWindow = new LoadingWindow(); 

有那麼用它來展示它,如果它是隱藏的功能中的雙重檢查。

if(!EditorPanel.loadingWindow.isVisible()){EditorPanel.loadingWindow.Initialize();} 

總的來說,我有點困惑,爲什麼沒有內容顯示,我在問任何問題很感興趣,並願意提供必要的任何信息。谷歌沒有提供很多,我發現我已經實現了每一個答案,例如「重繪和驗證」。

我期待着您的迴音!

〜特拉維斯

+1

通知,不叫'JFrame.removeAll()',結果可能是去掉'RootPane',空使用'Toolbar'和'Borders'的容器,使用'JFrame.getContentPane()。removeAll()'代替 – mKorbel

回答

12

removeAll(),不被轉發到JFrames的contentPane;如add(),remove()setLayout()是。

因此,當您執行JFrame#removeAll()時,它將刪除的根窗格。請參閱How to Use Root Panes進行有趣的閱讀,並可能爲未來的努力取得成果。

你應該這樣做:

的getContentPane()的removeAll(); //將確保我們從contentPane中刪除所有 組件

  • 而且不延長JFrame不必要的(。除非添加功能超出其當前能力),而只是創建一個實例JFrame並使用該實例

  • 請不要致電setSize寧可使用適當的LayoutManager和/或覆蓋的JPanel並返回適合圖紙的尺寸,因此您可以在設置爲可見之前在JFrame上致電pack()

  • 我認爲不需要validate()repaint()這些只能在組件添加到可見容器時調用。甚至比寧做revalidate()將用於添加和刪除組件工作(它依次調用validate()

+0

getContentPane()確實有效。但爲什麼框架在loadingWindow.setVisible(false)後顯示爲空白; loadingWindow.Initialize(); ? –

+0

@TravisTruttschel請提供一個[SSCCE](http://sscce.org)給我準確地回答這個問題 –

+1

+1,因爲「不要不必要地擴展JFrame」,並提出一個解決方案。 –

3

我猜removeAll刪除根窗格。

JFrame是一個容器,它包含許多組件,這些組件是我們所認爲的框架的一部分。在JFrame(和JApplet)中引入了一種黑客攻擊,因此有些方法會在內容窗格而不是框架本身上執行操作。當轉發沒有生效時,使用不同的方法或其中一種特殊方法,它會搞砸。

請參閱JFrame.remove的API文檔,並注意removeAll未被覆蓋。

最安全的辦法是忽略了「有益的」轉發和操作內容窗格本身(無論是通過getContentPane,或可能更好地創建自己的JPanel並使用setContentPane)。如通過@TomHawtintackline(+1到他)所述(亦不會延伸類,如JFrameThread,不必要地並按照標準編碼約定)