在线程方面,您有必要了解SwingWorker
哪种方式可以为您提供最大的灵活性。这是短而瘦的:
所有 GUI 操作都应该在Event Dispatch Thread
(简称 EDT)上。所有耗时的任务都应该在后台线程上。SwingWorker 允许您控制在哪个线程上运行代码。
首先,要在 EDT 上运行任何东西,请使用以下代码:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
jLabel1.setText("Yay I'm on the EDT.");
}
});
但是,如果您想运行一项耗时的任务,那将无法满足您的需求。相反,您需要像这样的 SwingWorker:
class Task extends SwingWorker<Void, Void> {
public Task() {
/*
* Code placed here will be executed on the EDT.
*/
jLabel1.setText("Yay I'm on the EDT.");
execute();
}
@Override
protected Void doInBackground() throws Exception {
/*
* Code run here will be executed on a background, "worker" thread that will not interrupt your EDT
* events. Run your time consuming tasks here.
*
* NOTE: DO NOT run ANY Swing (GUI) code here! Swing is not thread-safe! It causes problems, believe me.
*/
return null;
}
@Override
protected void done() {
/*
* All code run in this method is done on the EDT, so keep your code here "short and sweet," i.e., not
* time-consuming.
*/
if (!isCancelled()) {
boolean error = false;
try {
get(); /* All errors will be thrown by this method, so you definitely need it. If you use the Swing
* worker to return a value, it's returned here.
* (I never return values from SwingWorkers, so I just use it for error checking).
*/
} catch (ExecutionException | InterruptedException e) {
// Handle your error...
error = true;
}
if (!error) {
/*
* Place your "success" code here, whatever it is.
*/
}
}
}
}
然后你需要用这个启动你的 SwingWorker:
new Task();
有关更多信息,请查看 Oracle 的文档:http ://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html