简体   繁体   English

JLabel在入睡前没有出现

[英]JLabel doesn't appear before sleep

I am working on a simple Swing program that places one label on the frame, sleeps for one second, and then places another label on the frame as follows: 我正在开发一个简单的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!");
      }
    }); 
  }
} 

However, I cannot see the first label on the screen before the sleep. 但是,我无法在睡觉前在屏幕上看到第一个标签。 The screen is blank while sleeping. 睡眠时屏幕空白。 Afterwards, I see the original label for a split second and immediately afterwards the final label of "Hey! This is Different!" 之后,我会立即看到原始标签,然后立即看到最终标签“嘿!这不一样!”。 is on the screen. 在屏幕上。 Why doesn't the original label appear on the JFrame? 为什么原始标签没有出现在JFrame上?

It is much better and safer to use a Swing Timer in place of your sleep code, since the call to sleep risks being done on the event thread and this can put the entire GUI to sleep -- not what you want. 使用Swing计时器代替睡眠代码会更好,更安全,因为睡眠调用可能会在事件线程上完成,这会使整个GUI进入睡眠状态,而不是您想要的。 You also want to take care to make sure that your GUI does in fact start on the Swing event thread. 您还需要注意确保GUI实际上确实在Swing事件线程上启动。 For example 例如

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

The code written by you is working perfectly fine without any issue on my machine.. 您编写的代码运行正常,在我的机器上没有任何问题。

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's comment that the sleep is happening while the GUI is loading fixed the problem for me. 马特(Matt)评论说,在GUI加载时睡眠正在发生,这为我解决了这个问题。 Turns out that although the JFrame loads immediately, loading the other components takes around a second. 事实证明,尽管JFrame立即加载,但加载其他组件大约需要一秒钟。 So by the time the label is done correctly, the sleep is subsequently done and the label is switched almost immediately after. 因此,在正确完成标签时,随后便完成了睡眠,之后几乎立即切换了标签。 Changing the sleep (or the Timer) to over a second allows me to see the original label there for a little longer before it switches. 将睡眠(或计时器)更改为一秒钟以上,可以让我在切换之前看到那里的原始标签更长的时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM