JLabel在睡觉前不会出现

时间:2017-03-27 14:53:32

标签: java swing jlabel event-dispatch-thread

我正在研究一个简单的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!");
      }
    }); 
  }
} 

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

3 个答案:

答案 0 :(得分:2)

使用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();
        });
    }
}

答案 1 :(得分:0)

您编写的代码在我的机器上完全正常工作没有任何问题..

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!");
      }
    }); 
  }
} 

答案 2 :(得分:0)

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