通常,您将参数传递给线程。在后台运行逻辑。然后使用 SwingUtilities.invokeLater() 回发您需要对任何这些对象或 UI 线程上的 UI 元素进行的任何修改。通常我会创建一个简单的实用程序,它允许我指定应该在后台线程上运行什么,以及应该在 UI 线程上运行什么。SwingWorker 是您可以使用的东西,尽管我觉得使用起来非常痛苦。像这样简单的东西:
new AsyncThread<Param,T>() {
public T executeInBackground( Param param ) {
// do something long running
T result = // do something long running;
return T;
}
public void executeOnUI( T result ) {
// update the UI here, or modify the model, etc.
}
}.execute( param );
AsyncThread 将在另一个线程上执行 executeInBackground() 方法。然后在内部它会使用 SwingUtilities.invokeLater() 发回 UI 线程。然后 executeOnUI 将在 UI 线程上运行。execute() 方法可以创建一个线程以在后台运行、处理异常等。
我会让 GUI 可能启动线程,并让 GUI 将它的模型或它需要的任何部分传递给线程。而不是反过来。这样,您可以让 UI 提供有关正在运行的后台线程的反馈。但是,您不能让后台线程接触(写入/修改/更改)UI 线程将同时读取/写入的模型的成员。因此,如果您打算修改模型以响应后台线程,请将其发布回 UI 线程以确保安全。