正如帖子所说,重要的是不要阻塞 EDT(事件调度线程)。在我下面的示例中,实际工作从 EDT 线程开始,因为它是从按钮单击 ActionListener 开始的。我需要用一个单独的线程包装它,以便它与事件调度线程分开。因此 EDT 没有被阻塞。
另请注意,从单独的线程更新 UI 时需要 SwingUtilities.invokeLater()。下面的代码示例从我的原始代码中进行了一些简化。我实际上使用多个线程并行执行多个任务,并且在每个线程中调用 updateProgress() 通过附加最新状态来更新 TextArea。
完整的源代码在这里:https ://github.com/mhisoft/rdpro/blob/master/src/main/java/org/mhisoft/rdpro/ui/ReproMainForm.java
btnOk.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//Don't block the EDT, wrap it in a seperate thread
DoItJobThread t = new DoItJobThread();
t.start();
}
});
class DoItJobThread extends Thread {
@Override
public void run() {
//do some task
// output the progress
updateProgress();
}
}
public void updateProgress(final String msg) {
//invokeLater()
//This method allows us to post a "job" to Swing, which it will then run
// on the event dispatch thread at its next convenience.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
// event dispatch thread
outputTextArea.append(msg);
outputTextArea.setCaretPosition(outputTextArea.getDocument().getLength());
//labelStatus.setText(msg);
}
});
}