2012-01-18 48 views
1

首先,道歉,但它是真的很難重建對這個SSCCE,但我認爲我可以解釋的情況相當好,瞭解我的問題,的JLabel將不會更新,除非有導致方法掛

我的情況是這樣的:我有一個用作狀態指示器的JLabel(例如,它將顯示「正在加載...」或「就緒」),在調用另一個方法之前調用MouseAdapter中的setText方法行動。然而,JLabel文本永遠不會改變,除非我在這種情況下調用JOptionPane.showMessageDialog()來更新文本。

因此,沒有任何人有任何建議,我怎麼能解決沒有做這樣的事情顯示一個消息框(會是什麼)沒有任何理由這種情況呢?

在此先感謝

+0

對不起,如果這看起來像不好的建議,但是你有沒有在更改標籤的文本後嘗試在你的框架上調用'revalidate()'或'repaint()'? – fireshadow52 2012-01-18 19:43:30

+0

糟糕。不理我以前的評論。如答案中所述,確保你沒有在美國東部時間執行你的任務。 – fireshadow52 2012-01-18 19:50:36

+0

我認爲@ fireshadow52的建議是一個很好的嘗試,最好是使用擺動工具,但如果你只是原型設計,你可以先嚐試一下。 – 2012-01-18 20:04:21

回答

6

確保您不在EDT(Event Dispatch Thread)上運行您的任務(您的「加載...」過程);如果你這樣做,你的GUI將不會被更新。

你必須運行你的應用程序代碼(除非它的速度非常快,說小於100ms,沒有網絡接入,沒有數據庫訪問等),在一個單獨的線程。爲了這個目的,SwingWorker(參見javadocs)類可能會派上用場。

的EDT(內部用戶接口聽衆例如代碼塊)應只包含用於更新所述圖形用戶界面,上Swing組件操作等一切你應該它自己Runnable對象上運行的代碼。

-

編輯:效應初探安迪的評論。下面是一個原始例子(書面上的蒼蠅,它可能有錯別字和這樣的,可能無法運行不變化),你可以如何使用SwingWorker

在你的鼠標監聽事件將這個或任何讓你的任務開始

//--- code up to this point runs on the EDT 
SwingWorker<Boolean, Void> sw = new SwingWorker<Boolean, Void>() 
{ 

    @Override 
    protected Boolean doInBackground()//This is called when you .execute() the SwingWorker instance 
    {//Runs on its own thread, thus not "freezing" the interface 
     //let's assume that doMyLongComputation() returns true if OK, false if not OK. 
     //(I used Boolean, but doInBackground can return whatever you need, an int, a 
     //string, whatever) 
     if(doMyLongComputation()) 
     { 
      doSomeExtraStuff(); 
      return true; 
     } 
     else 
     { 
      doSomeExtraAlternativeStuff(); 
      return false; 
     } 
    } 

    @Override 
    protected void done()//this is called after doInBackground() has finished 
    {//Runs on the EDT 
     //Update your swing components here 
     if(this.get())//here we take the return value from doInBackground() 
      yourLabel.setText("Done loading!"); 
     else 
      yourLabel.setText("Nuclear meltdown in 1 minute..."); 
     //progressBar.setIndeterminate(false);//decomment if you need it 
     //progressBar.setVisible(false);//decomment if you need it 
     myButton.setEnabled(true); 
    } 
}; 
//---code under this point runs on the EDT 
yourLabel.setText("Loading..."); 
//progressBar.setIndeterminate(true);//decomment if you need it 
//progressBar.setVisible(true);//decomment if you need it 
myButton.setEnabled(false);//Prevent the user from clicking again before task is finished 
sw.execute(); 
//---Anything you write under here runs on the EDT concurrently to you task, which has now been launched 
+0

不幸的是,我在美國東部時間執行任務(愚蠢的我)。儘管如此,我還沒有真正遇到'SwingWorker';你能舉個例子嗎?謝謝。 – Andy 2012-01-18 19:54:20

+0

@我編輯了答案,添加了一個(不是特別漂亮的)例子。希望它有助於理解機制 – 2012-01-18 20:31:01

+1

感謝這個例子,它確實幫助瞭解了我的工作;可能更重要的是,我對「SwingWorker」有了更好的理解。再次感謝。 – Andy 2012-01-18 20:50:27

3

您是否從EDT調用setText()方法?

+0

+1你是正確的,這可能是正確答案http://stackoverflow.com/questions/7943584/update-jlabel-every-x-seconds-from-arraylistlist-java/7944388#7944388 – mKorbel 2012-01-18 19:49:28

+0

OP說,設置文本越來越從鼠標適配器調用,這應該可能在EDT上運行。 – 2012-01-18 20:02:37

+0

@AKJ是的,鼠標適配器在EDT上運行,以回答tilex的問題。我真的不確定該做什麼,任何人都可以向我提供一些例子嗎?請! – Andy 2012-01-18 20:08:13

相關問題