你有一个GUI线程。不要用它来打电话给其他东西;如果你这样做,那些事情必须在你的GUI中发生任何其他事情之前完成。
至少你会想要开始一个新的线程来执行你的 dmc.moveTo(destination) 。很可能这不是你做这个的唯一地方,而且可能想要一个 执行者 设置执行这些任务。
dmc.moveTo(destination)
在不了解您的代码的情况下(特别是因为您使用的是静态方法)我无法评论您希望如何设置 Executor 但是使用a的最简单的例子 Thread 将会:
Executor
Thread
public static void moveTo(final Coordinate destination) { changeState(State.NAVIGATION); controlPnl.addRemote(Remote.createRemote(remoteType.NAVIGATION)); new Thread(new Runnable() { public void run() { dmc.moveTo(destination); changeState(State.IMMEDIATE); controlPnl.addRemote(Remote.createRemote(remoteType.IMMEDIATE)); } }).start(); }
这创造了一个新的 Thread 执行你的(匿名) Runnable 执行你的 moveTo() 。请注意,这远远低于拥有 Executor 准备好运行你的任务;它必须创造一个新的 Thread 每次。但是,如果这不是你需要的性能问题那么它就完全没问题了。另请注意,因为我正在引用 destination 直接在匿名内部类中,必须声明它 final 当传入你的方法时。
Runnable
moveTo()
destination
final
既然你的 moveTo 需要很长时间才能在主事件处理线程上执行它。相反,有 moveTo 更新GUI并在单独的线程中启动实际移动。移动完成后,使用 SwingUtilities.invokeLater 做第二组GUI更新。
moveTo
SwingUtilities.invokeLater
private static ExecutorService executor = Executors.newCachedThreadPool(); public static void moveTo(final Coordinate destination) { changeState(State.NAVIGATION); controlPnl.addRemote(Remote.createRemote(remoteType.NAVIGATION)); executor.execute(new Runnable() { public void run() { dmc.moveTo(destination); SwingUtilities.invokeLater(new Runnable() { public void run() { changeState(State.IMMEDIATE); controlPnl.addRemote(Remote.createRemote(remoteType.IMMEDIATE)); } }); } }); }
这条路 moveTo 做一组初始GUI更新然后立即返回,释放事件循环以保持GUI响应,但第二个 changeState 被推迟到了 dmc.moveTo 完成了。
changeState
dmc.moveTo
(将这些东西分解为单独的方法而不是使用Runnable-in-a-Runnable匿名类可能更有意义)