【问题标题】:How can I pause/sleep/wait in a java swing app?如何在 java swing 应用程序中暂停/睡眠/等待?
【发布时间】:2019-07-18 18:59:17
【问题描述】:

我正在使用 JLabel 创建动画,

public void updateLabels() {
      label.setIcon(new ImageIcon(new Paint().getScaledImage(paint[currentIndexLabel].imageCALA,300,300)));
      label_1.setIcon(new ImageIcon(new Paint().getScaledImage(paint[currentIndexLabel].imageStates,300,300)));
      label_2.setIcon(new ImageIcon(new Paint().getScaledImage(paint[currentIndexLabel].imageStrategies,300,300)));
      label_3.setIcon(new ImageIcon(new Paint().getScaledImage(paint[currentIndexLabel].imagekD,300,300)));

      currentIndexLabel++;
}

我有一个更新标签的按钮

btn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent arg0) {
        while (currentIndexLabel != paint.length-1) {
            updateLabels();
        }
    }
});

但是,我不知道如何等待,例如 1000 毫秒,直到下一次更改。当我添加这个时:

try { Thread.sleep(1000); } catch (Exception e){}

进入我的 ActionListener:

btn.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent arg0) {
           while (currentIndexLabel!=paint.length-1) {
             updateLabels();
             try { Thread.sleep(1000); } catch (Exception e){}
       }
    }
 });

它不工作。它只是停了一会儿,我看不到第一帧和最后一帧之间的变化。是否可以在不停止程序的情况下等待 1000 毫秒?当我删除 while 循环和尝试部分,然后单击我的按钮时,它的变化非常好......

我该怎么做?

【问题讨论】:

标签: java swing


【解决方案1】:

ma​​in 线程的 swing 应用程序中使用 Thread#sleep 方法会导致 GUI 冻结(由于线程休眠,事件无法发生)。 swing应用程序中的Thread#sleep方法只允许SwingWorkers使用,而这在他们的#doInBackround方法中。

为了在一个摇摆应用程序中等待(或定期做某事),你必须use a Swing Timer.看看我做的一个例子:

import java.awt.FlowLayout;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.Timer; //Note the import

public class TimerExample extends JFrame {
    private static final int TIMER_DELAY = 1000;
    private Timer timer;

    public TimerExample () {
        super();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(200, 200);
        setLocationRelativeTo(null);
        getContentPane().setLayout(new FlowLayout());

        timer = new Timer(TIMER_DELAY, e -> {
            System.out.println("Current Time is: " + new Date(System.currentTimeMillis()));
        });
        //timer.setRepeats(false); //Do it once, or repeat it?
        JButton button = new JButton("Start");
        button.addActionListener(e -> timer.start());
        getContentPane().add(button);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new TimerExample().setVisible(true));
    }
}

按下“开始”按钮后的输出:

当前时间是:2019 年 2 月 25 日星期一 13:30:44 EET

当前时间是:2019 年 2 月 25 日星期一 13:30:45 EET

当前时间是:2019 年 2 月 25 日星期一 13:30:46 EET

如您所见,Timer 的动作监听器每秒触发一次。

所以在你的情况下:

timer = new Timer(TIMER_DELAY, e -> {
    if (currentIndexLabel != paint.length-1) {
        upateLabels();
        timer.restart(); //Do this check again after 1000ms
    }
});
button.addActionListener(e -> timer.start());

【讨论】:

  • 但是如何在我的代码中使用它,我看到你替换了 ActionListener 的事件,当我尝试做类似的事情时它不起作用:D
  • 嗯我在这个地方有错误,我的编译器会在整个文本下划线,这是来自你的。 Multiple markers at this line - Line breakpoint:MyCanvasInWindow [line: 95] - MyCanvasInWindow(Paint[]) - The constructor Timer(int, (<no type> e) -> {}) is undefined
  • @Potato 嗯...你用什么java版本?
  • @Potato 你也注意到 Timer 的包裹了吗? import javax.swing.Timer;
  • 哈哈,我注意到我的导入中有不同的 Timer,但我的那个箭头仍然有错误Multiple markers at this line - Syntax error, insert "... VariableDeclaratorId" to complete FormalParameterList - Syntax error on token "->", @ expected - Syntax error, insert "[ ]" to complete Dimension
猜你喜欢
  • 1970-01-01
  • 2010-11-13
  • 2018-11-16
  • 2011-12-12
  • 2022-11-23
  • 2010-12-04
  • 2021-11-02
相关资源
最近更新 更多