当我尝试在代码上使用任何类型的延迟时,程序都会延迟,但是在延迟结束之前放置的JLabel会在程序结束后更新。
我希望程序执行以下操作:
在GUI上更新JLabel 等待5秒钟 用不同的文本再次更新JLabel 再等5秒钟 我尝试过使用计时器,invokelater,invokeandwait,thread.sleep等。
问题在于,GUI确实会在正确的位置延迟,但是GUI不会更新代码所在的JLabel。程序结束后,JLabel将更新。
我希望用户能够阅读文本5秒钟,然后依次阅读另一文本5秒钟。我不希望程序在某个特定位置运行gui暂停,然后最后只需更新JLabel。我希望gui在延迟之前得到更新。我不希望发生这样的事情:使用计时器发生时,在键入计时器之前在JLabel的setText中键入内容,然后在运行程序时计时器起作用,但JLabel在延迟后得到更新(这是不是我想要的)。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在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在等待期间正常更新和响应。