Java奇怪的图形在lock.await()时闪烁

标签 java swing repaint swingworker countdownlatch

我的图形用户界面有一个奇怪的行为。 首先这里有一段代码:

/**
 * 
 */
@Override
protected Void doInBackground() throws Exception {
    final ModelGameState actualGameState = controller.getActualGameState();
    final ModelCoinState actualCoinState = (actualGameState.getPlayersTurn() == ModelConstants.PLAYER_ONE_ID? actualGameState.getCoinsPlayerOne() : actualGameState.getCoinsPlayerTwo());
    final List<ModelCoinState> temp = MoveCalculator.getMoves(actualCoinState, this.cellID);
    final CountDownLatch lock = new CountDownLatch(temp.size());
    int time = 500;
    
    for(int i = 0; i < temp.size(); i++) {
        final int index = i;
        
        Timer timer = new Timer(time, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(actualGameState.getPlayersTurn() == ModelConstants.PLAYER_ONE_ID) {
                    actualGameState.setCoinsPlayerOne(temp.get(index));
                } else {
                    actualGameState.setCoinsPlayerTwo(temp.get(index));
                }

                controller.setActualGameState(new ModelGameState(actualGameState));
                
                lock.countDown();
            }
        });
        
        timer.setRepeats(false);
        timer.start();
        
        time += 500;
    }
    
    lock.await();

    return null;
}

第二个是我的图形用户界面:

enter image description here

这是我的问题:每次 lock.await 被称为我的屏幕 看起来像这样:

enter image description here

正如你所看到的,我的每个圆圈后面都是左上角 每次调用 lock.await() 时都会显示我的 gui(至少我 认为是在调用 lock.await() 时,因为当我删除 lock.await() 时 我看不到我的图形用户界面的整个动画,但我也看不到 看到这种奇怪的行为并且这种行为总是出现 当程序执行完doInBackground()的所有代码时。

是什么导致了这种奇怪的行为?

最佳答案

不是一个答案,只是不同意,我的评论反对,没有评论,没有尝试你的代码,向我道歉,有任何原因,也许是我的不好

  • doInBackground() 是 AWT/Swing EDT 和工作线程之间的桥梁,默认情况下从不通知 EDT

  • 处理、发布、setProgress 并完成()通知 EDT

  • 那么 doInBackground() 中的 Swing Timer 就违背了所有意图,为什么 SwingWorker 在官方 API 中实现,有地方可以执行长时间运行、硬代码或非安全代码

  • SwingWorker 再次被指定为 AWT/Swing 和 Workers Thread(s) 之间的桥梁

    ____________________________________>__

有两种方法

  • 将 CountDownLatch 与 invokeLater() 或 Swing Timer 结合使用。不要将其混合在一起,也不要与 SwingWorker 混合

  • 使用 CountDownLatch、util.Timer、SheduledExecutor 并通过换行通知 EDT(仅相关、仅输出、方法将在屏幕上重新绘制)将 Swing 方法传递给 invokeLater()

  • 仅使用 Swing 计时器(每小时不准确)

关于Java奇怪的图形在lock.await()时闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18290010/

相关文章:

java - 如何用直线填充三角形?

java - 由于 setOpaque(false) 方法,JPanel 不断被重新绘制

java - 刷新 GUI 时线程中出现异常

Java,大型 GUI 类,带有许多 ActionListeners;组织听众的最佳方式?

java - 如何在JAVA 7u80客户端中启用TLSv1.2

swing - 将 Java 组件添加到 Scala Swing 面板

java - 旋转 JLabel 文本的垂直方向

java - 为什么在 PaintComponent(Graphics g) 方法中使用 if 语句会使该方法中的所有代码无效?

用于检测类/接口(interface)/等声明的 Java 正则表达式

java - 不使用Image可以画透明图层吗?-LibGdx