確保您不在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
對不起,如果這看起來像不好的建議,但是你有沒有在更改標籤的文本後嘗試在你的框架上調用'revalidate()'或'repaint()'? – fireshadow52 2012-01-18 19:43:30
糟糕。不理我以前的評論。如答案中所述,確保你沒有在美國東部時間執行你的任務。 – fireshadow52 2012-01-18 19:50:36
我認爲@ fireshadow52的建議是一個很好的嘗試,最好是使用擺動工具,但如果你只是原型設計,你可以先嚐試一下。 – 2012-01-18 20:04:21