2012-09-29 46 views
1

所以我有這個問題。我有一個程序來創建和加載文件。聽衆和驗證/重繪

當我將一個文件加載到我的程序中時,我依靠一個組件偵聽器來告訴我特定組件何時「滿」,然後根據此組件移動所有組件。

我在頂部添加每個組件,然後在父組件「填充」時將偵聽器註冊,並將底部組件添加到它也創建的新父組件。可以把它看作是添加一個新的文本行到一個houndred頁MSWord文檔的開始。

該監聽器還依賴於GUI設置 - 如果內存中的所有內容都沒有繪製到屏幕上,它會抓取錯誤的組件高度(通常爲0),並將其用於計算中,然後出錯,向上。

這是我的那部分程序的流程圖:

(everytning發生在一個JPanel在一個JFrame)

trigger opening method: 
{ 
    repeat this x (lets say e.g. 100) times: 
    { 
     trigger addComponent method 
     { 
      add component 
      { 
       adding component triggers the component listner 8if there is no more room in parent) 
       { 
        move all of the components one place down, move the ones out of bounds to next "page" 
        repaint and revalidate whole JFrame (inside listener) 
       } 
      } 
      repaint and revalidate whole JFrame (part of addComponent method) 
     } 
     repaint and revalidate whole JFrame(part of opening methid, after component addition)  
    } 
    repaint and revalidate whole JFrame (as a part of opening method, final repaint/validate) 
} 

這樣做的原因可能重繪/驗證是addComponent方法,以及聽衆有其他功能,並在其他地方被稱爲是唯一(最佳)重新繪製/驗證的地方。

問題是,在操作方法中,直到最後(最終)驗證/重新繪製調用之前,JFrame纔會重新繪製。我嘗試將Thread.sleep(1000)添加到代碼中的幾個地方(驗證/重繪後)以證明這一點。

另外,就我所知,當組件監聽器被觸發時,它會停在觸發它的那一行,然後執行它自己,然後繼續從那一行開始,對吧?

我該如何解決這個問題?如何在強制添加每個新組件後再強制我的程序重新繪製/驗證?

回覆前兩條評論: 首先,Thread.sleep(1000)只是爲了診斷問題。在Thread.sleep(1000)方法重新繪製/驗證方法之前,我想如果我在調用reapint()之後立即暫停程序,在每次暫停之後,GUI都會重新繪製廣告,我會看到添加了新元素,而不是案子。其次,關於冗長的計算,這些計算並不長(用20個組件執行此操作會得到瞬時結果,但不是那些所需的結果)。此外,這種計算需要經常移除和添加組件(每10-20行),因此將SwingWorker合併到這是幾乎不可能的,而不是必需的。

第三,我想你錯過了整個觀點。執行的時間長度並不是真正的問題,也不是GUI的凍結(無論如何,它並不真正發生,時間也不夠長)。問題是重繪/驗證在循環中被調用,每個組件總共有3-4次(如果我打開一個包含20個組件的文件,約60-80次),並且唯一一次我看到它被執行的時候是最後一次被調用,在循環之後...

我甚至在重繪/驗證之前和之後立即將System.out.println(「something」)方法。它打印出「東西」兩次,但重繪/驗證從未發生過。

+2

它的氣味對我來說,如果你正在對您的GUI的事件線程長期運行的進程(或者更糟的是,調用'的Thread.sleep(...)'在事件線程),這是讓你的GUI進入睡眠狀態。由於這是一個Swing GUI,你使用SwingWorker來完成你的後臺工作嗎?如果不是,我強烈建議你這樣做。 –

+2

+1對HFOE評論肯定聽起來像你睡在你的EDT。如果您發佈[SSCCE](http://sscce.org) –

+0

,請檢查編輯的回覆... – Karlovsky120

回答

2
  • 我可以看到任何問題with add/remove/modify JComponents容器(JFrame - >JPanel EI)

  • 取決於如果集裝箱(JPanel EI)被放置在JScrollPane

  • 取決於是否需要請在add/remov e/modifyJComponent之後撥打pack(),然後在容器中更改尺寸JFram e(例如) Ë屏幕

+0

+1不錯的鏈接,用於演示:) –

+1

@David Kroukamp這些是當我不是奴隸的時候,我無盡的懶惰 – mKorbel

+0

Container實際上是在一個JScroolPane中(JFrame有一個JScrollPane,其中設置了JPanel容器作爲視口)。那是不好的,我該如何解決它? 我不需要調用pack(),並且在此過程中沒有調整JFrame的大小,但沒有任何組件(除了添加組件時減少的Filler,當高度變爲0時偵聽器被觸發 - 我正在檢測溢出)。 – Karlovsky120