首页 > 解决方案 > 为什么我的 JLabel 不能在循环中正确更新?

问题描述

我想为我的应用程序制作一个加载屏幕,但是显示加载量的 JLabel 没有正确更新。

我创建了一个 JDialog 和 JLabel。我想通过线程更新 JLabel 文本。

JDialog loadingScreen = new JDialog((JFrame) null);
JLabel loaded = new JLabel();
loadingScreen.add(loaded);
loading.add(time);
loading.setSize(new Dimension(200,100));

Thread t = new Thread(() -> {
    loading.setVisible(true);
    while (true) {
        if (i3 < Math.pow(characters.size(), Integer.parseInt(length.getText()))) {
            time.setText(i3 + " / " + Math.pow(characters.size(), Integer.parseInt(length.getText()))); //doesn't work
            System.out.println("hi"); //works
        } else break;
    }
});
...
t.start();

标签: javamultithreadingswingawtjlabel

解决方案


不要通过线程更新 Swing 组件。相反,使用SwingUtilities.invokeLater,如下所示:

JDialog loadingScreen = new JDialog((JFrame) null);
JLabel loaded = new JLabel();
loadingScreen.add(loaded);
loading.add(time);
loading.setSize(new Dimension(200,100));

Thread t = new Thread(() -> {
    loading.setVisible(true);
    while (i3 < Math.pow(characters.size(), Integer.parseInt(length.getText()))) {
        SwingUtilities.invokeLater(() -> time.setText(i3 + " / " + 
            Math.pow(characters.size(), Integer.parseInt(length.getText()))));
        System.out.println("hi");
    }
});
...
t.start();

自然,对 Runnable lambda 使用正确的语法 - 如果它是多行的,则必须使用块。但是,不推荐使用线程来更新 Swing GUI 组件。通常,摆动计时器是一个更好的主意。


推荐阅读