JLabel doesn't appear before sleep

ぐ巨炮叔叔 提交于 2019-12-08 12:22:39

问题


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:

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?


回答1:


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. You also want to take care to make sure that your GUI does in fact start on the Swing event thread. 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();
        });
    }
}



回答2:


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



回答3:


Matt's comment that the sleep is happening while the GUI is loading fixed the problem for me. Turns out that although the JFrame loads immediately, loading the other components takes around a second. 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.



来源:https://stackoverflow.com/questions/43049730/jlabel-doesnt-appear-before-sleep

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!