2014-05-11 32 views
3

在为游戏制作动画和更新计时器时,我读到与GUI有关的任何活动都应该在EDT上运行,包括重新绘制屏幕。我正在使用一个ScheduledExecutorService来更新和绘制游戏(使用主动渲染)。最初的时间表服务(这是一个嵌套类implements Runnable)在呼叫完成这样的:如何确保ScheduledExecutorService在EDT上运行?

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(); 
SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      ex.schedule(new UpdatingService(), 1, TimeUnit.MILLISECONDS); 
     } 
    }); 

我认为这将使在美国东部时间的服务运行,但增加System.out.println(SwingUtilities.isEventDispatchThread());证明,这是不。

我做了一番搜索,发现this后面提到了启动EDT 里面的这个定时器。我试过这个,它确实有效。但是,像这样嵌套线程似乎不是一个好主意。

所以,嵌套这样的线程不像它看起来那么糟糕?如果这是一个坏主意,那么确保在EDT上运行ScheduledExecutorService的正确方法是什么?

+0

“*我做了一些搜索,发现这篇文章提到在定时器内启动EDT。*”=>这是要走的路。 – assylias

+1

确保代码在事件派发线程上执行的最简单方法是使用[javax.swing.Timer](http://docs.oracle.com/javase/8/docs/api/javax/swing/Timer.html )(而不是java.util.Timer)而不是ScheduledExecutorService。 – VGR

回答

3

在您的代码:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(); 
SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      ex.schedule(new UpdatingService(), 1, TimeUnit.MILLISECONDS); 
     } 
    }); 

这里的EDT执行的唯一代码为ex.schedule调用。稍后由调度程序调用的代码(例如new UpdatingService())将在调度程序内部的线程上运行,该线程不会是EDT,而是通过调用Executors.newSingleThreadScheduledExecutor

创建的某个线程。也许我会做的是让您的调度程序安排更新方法(您的更新服务),然后它自己通过invokeLater拨打电话到EDT。

例如,像:

ScheduledExecutorService ex = Executors.newSingleThreadScheduledExecutor(); 
ex.schedule(new Updater(), 1, TimeUnit.MILLISECONDS); 
... 
class Updater extends Runnable { 
    @Override 
    public void run() { 
     // invoke the EDT via Swing Utilities here.  
    } 
} 

这是没有看到你的代码的其余部分是当仁不让的最好的建议。

相关问题