Java 使用ActionListener事件进行实时更新

Java 使用ActionListener事件进行实时更新,java,swing,actionlistener,Java,Swing,Actionlistener,我正在尝试在ActionListener事件中运行一个方法,该方法会多次更新imageIcon。这当然行不通。完成后,它只显示最终的图像图标 bottomPanel.startBTN.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { gameArea.runGame(); }

我正在尝试在ActionListener事件中运行一个方法,该方法会多次更新imageIcon。这当然行不通。完成后,它只显示最终的图像图标

        bottomPanel.startBTN.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                gameArea.runGame();
            }
        });
“runGame”方法类似于:

for (int i = 0; i < 10; i++) {
    wait 1 second;
    do something;
}
for(int i=0;i<10;i++){
等待1秒;
做点什么;
}

如果您希望在swing中做一些“后台”工作,那么我建议使用一个。 SwingWorker的外观与此类似:

public static void gameRun(){
    SwingWorker<Void, Image> worker = new SwingWorker<Void, Image>() {

        @Override
        protected Void doInBackground() throws Exception {
            for(int x = 0; x < myImages.length; x++) {
                Thread.sleep(1000);
                Image icon = ImageIO.read(myImages[x]);
                publish(icon);
            }
            return null;
        }

        @Override
        protected void process(List<Image> icon) {
            myLabel.setIcon(new ImageIcon(icon.get(icon.size()-1)));
        }
    };
    worker.execute();
}
publicstaticvoidgamerun(){
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
对于(int x=0;x

编辑:我已使用发布方法更新了答案以更新GUI。

Swing是单线程的,不支持线程安全。这意味着您正在阻止事件调度线程,阻止它更新UI。首先介绍一些背景知识,然后介绍解决该问题的最简单机制——以不违反API中不安全线程规则的方式;)这里重要的是要记住:1。
ActionListener
在EDT的上下文中执行;2.Swing是单线程的,因此阻止EDT将阻止它响应重新绘制请求或其他事件,直到它被解锁;3.Swing不是线程安全的,因此必须确保在EDT上下文中完成对UI(或UI依赖的状态)的更新;4.Swing
Timer
将为您执行此操作(等待关闭EDT和EDT内发生的触发器更新)。不,您不应该在doInBackground()方法中设置图标。看我对奥莫尔答案的评论。似乎他删除了它。能否重新发布您提供的信息?Swing组件需要在
事件调度线程(EDT)
上更新。您不应该在doInBackground(…)方法中设置图标。相反,您应该“发布”要在JLabel上更新的图标。阅读关于[具有临时结果的任务}()的Swing教程有关更多信息和工作示例,请阅读
事件调度线程
一节,非常感谢。如果您不介意看一看我上面编辑的代码,我将不胜感激。使用Swing
计时器更简单
,就我个人而言,
SwingWorker
对于如此简单的事情不必要地笨手笨脚。S由于SwingWorker的处理步骤增加了额外的开销,因此也增加了延迟之间的时间间隔,这可能变得不合理