JLabel在睡觉前没有出现

我正在研究一个简单的Swing程序,它在框架上放置一个标签,睡眠一秒钟,然后在框架上放置另一个标签,如下所示:

import javax.swing.*; import java.util.concurrent.*; public class SubmitLabelManipulationTask { public static void main(String[] args) throws Exception { JFrame frame = new JFrame("Hello Swing"); final JLabel label = new JLabel("A Label"); frame.add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 100); frame.setVisible(true); TimeUnit.SECONDS.sleep(1); SwingUtilities.invokeLater(new Runnable() { public void run() { label.setText("Hey! This is Different!"); } }); } } 

但是,我无法在睡眠前看到屏幕上的第一个标签。 睡觉时屏幕是空白的。 之后,我看到了原始标签的瞬间,然后是最后的标签“嘿!这是不同的!” 在屏幕上。 为什么原始标签不出现在JFrame上?

使用Swing Timer代替睡眠代码要好得多,也更安全,因为睡眠调用可能会在事件线程上完成,这会使整个GUI进入睡眠状态 – 而不是你想要的。 您还需要注意确保您的GUI确实在Swing事件线程上启动。 例如

 import javax.swing.*; import java.util.concurrent.*; public class SubmitLabelManipulationTask { public static void main(String[] args) throws Exception { SwingUtilities.invokeLater(() -> { JFrame frame = new JFrame("Hello Swing"); final JLabel label = new JLabel("A Label", SwingConstants.CENTER); frame.add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 100); frame.setVisible(true); Timer timer = new Timer(1000, e -> { label.setText("Try this instead"); }); timer.setRepeats(false); timer.start(); }); } } 

您编写的代码在我的机器上完全没有任何问题。

 import javax.swing.*; import java.util.concurrent.*; public class SubmitLabelManipulationTask { public static void main(String[] args) throws Exception { JFrame frame = new JFrame("Hello Swing"); final JLabel label = new JLabel("A Label"); frame.add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 100); frame.setVisible(true); TimeUnit.SECONDS.sleep(1); SwingUtilities.invokeLater(new Runnable() { public void run() { label.setText("Hey! This is Different!"); } }); } } 

Matt的评论说,在GUI加载时发生睡眠会为我解决问题。 事实certificate,尽管JFrame立即加载,但加载其他组件大约需要一秒钟。 因此,当标签正确完成时,随后完成睡眠并且标签几乎立即切换。 将睡眠(或定时器)更改为超过一秒可以让我在切换前看到原始标签一段时间。