我应该怎么做以防止UI冻结(scheduledexecutorservice)

时间:2016-01-24 22:43:24

标签: java swing concurrency scheduledexecutorservice

我正在使用scheduledexecutorservice来执行绘制图形的动画(一次一个顶点和一个边)。我在逐步更新实际UI时遇到问题,而我看不到实际的动画,只看到最终的图形。

private Runnable newRunnable() {
    return new Runnable() {

        @Override
        public void run() {
            // this method just adds the graph to a JPanel
            displayDiagram();
        }
    };
}

private void animate() {
    executorService.schedule(newRunnable(), 1500, TimeUnit.MILLISECONDS);
    executorService.shutdown();
    try {
        executorService.awaitTermination(1, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    executorService = new ScheduledThreadPoolExecutor(1);
}

我想要实现的是能够绘制一个顶点和一个边,并且每次更新UI然后等待1500ms并再次执行此操作直到显示整个图形。

在动态创建图形时,将多次调用方法动画。

2 个答案:

答案 0 :(得分:3)

awaitTermination是一种阻止方法。相反,您应该使用SwingWorker(并利用它publish / process功能)或Swing Timer

查看Concurrency in SwingWorker Threads and SwingWorkerHow to use Swing Timers了解详情

也许像this

答案 1 :(得分:3)

您的代码不遵守Swing线程规则,因为它会对Swing事件调度线程中的Swing应用程序进行状态更改。我建议您使用SwingWorker作为后台任务以及它的发布/处理方法对,以便以线程安全的方式将信息传递回Swing GUI。如果您需要使用其他方法来创建后台线程,那么请确保使用类似

之类的内容将后台线程中的任何Swing调用排入Swing事件队列。
SwingUtilities.invokeLater(() -> {
    // swing call here
});