开发者社区 问答 正文

如何在延迟之前更新JLabel?

当我尝试在代码上使用任何类型的延迟时,程序都会延迟,但是在延迟结束之前放置的JLabel会在程序结束后更新。

我希望程序执行以下操作:

在GUI上更新JLabel 等待5秒钟 用不同的文本再次更新JLabel 再等5秒钟 我尝试过使用计时器,invokelater,invokeandwait,thread.sleep等。

问题在于,GUI确实会在正确的位置延迟,但是GUI不会更新代码所在的JLabel。程序结束后,JLabel将更新。

我希望用户能够阅读文本5秒钟,然后依次阅读另一文本5秒钟。我不希望程序在某个特定位置运行gui暂停,然后最后只需更新JLabel。我希望gui在延迟之前得到更新。我不希望发生这样的事情:使用计时器发生时,在键入计时器之前在JLabel的setText中键入内容,然后在运行程序时计时器起作用,但JLabel在延迟后得到更新(这是不是我想要的)。

展开
收起
垚tutu 2019-11-28 18:42:19 664 分享 版权
阿里云 AI 助理回答

在Swing或JavaFX这类GUI框架中,UI更新需要在事件调度线程(EDT)上进行。当你使用Thread.sleep()时,它会阻塞当前线程,如果这个线程是EDT,那么整个GUI都会冻结,直到sleep结束,因此不会看到中间的更新过程。

要实现你的需求,应该使用Swing的Timer类(如果你使用的是Swing)。这样可以在不阻塞EDT的情况下安排任务。下面是一个简单的示例代码,展示了如何使用Swing Timer来完成你的要求:

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class JLabelUpdateExample {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("JLabel Update Example");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JLabel label = new JLabel("First Text");
            frame.getContentPane().add(label);
            frame.pack();
            frame.setVisible(true);

            // 创建并启动第一个定时器,5秒后更新文本
            Timer timer1 = new Timer(5000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setText("Second Text");

                    // 第一个定时器结束后,启动第二个定时器
                    Timer timer2 = new Timer(5000, new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
                            label.setText("Third Text"); // 最终更新文本
                            ((Timer)e.getSource()).stop(); // 停止第二个定时器
                        }
                    });
                    timer2.setRepeats(false); // 只触发一次
                    timer2.start();
                }
            });
            timer1.setRepeats(false); // 只触发一次
            timer1.start();
        });
    }
}

这段代码首先创建了一个窗口,并在其中添加了一个JLabel。然后,它设置了一个定时器,在5秒后将JLabel的文本更改为"Second Text"。当第一次更新完成后,立即启动第二个定时器,再等待5秒后将文本更改为"Third Text"。每个定时器都只运行一次,并且不会阻塞EDT,从而允许GUI在等待期间正常更新和响应。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答地址: