有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用带有延迟的while循环每次更新jLabel

   private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
  int count = jSlider1.getValue(); 
  int delay = jSlider2.getValue();
    int valueOfSlider = jSlider2.getValue();
     int valueOfSlider2 = jSlider1.getValue();

while (count > 0) 
{ 
    count--;
    String count2 = ""+count; 
  jLabel3.setText(count2);
try {Thread.sleep(delay); }
catch (InterruptedException ie) { }

 }

它最终会在jLabel上显示最终的数字,但不会增量更新数字。需要帮忙吗


共 (2) 个答案

  1. # 1 楼答案

    你的问题是,你在ActionPerformed回调中做一些耗时的事情,该回调在事件线程中执行。在回调中,您应该快速执行某个操作并返回,即使“某个”正在生成线程。当您占用事件线程时,GUI无法更新,它只会在回调返回后更新

  2. # 2 楼答案

    Swing是单线程的。因此,长时间运行的任务不应该在EDT中进行。这包括睡觉。相反,使用^{}。这将在后台线程中延迟,然后在EDT中发布要执行的操作

    另见:


    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    
    public final class JLabelUpdateDemo {
    
        public static void main(String[] args){
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run() {
                    createAndShowGUI();             
                }
            });
        }
    
        private static void createAndShowGUI(){
            final JFrame frame = new JFrame("Update JLabel Demo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().setLayout(new FlowLayout());
            frame.getContentPane().add(JTimerLabel.getInstance());
            frame.setSize(new Dimension(275, 75)); // used for demonstration purposes
            //frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
            Timer t = new Timer(1000, new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e) {
                    int val = Integer.valueOf(JTimerLabel.getInstance().getText());
                    JTimerLabel.getInstance().setText(String.valueOf(++val));
                }
            });
            t.start();
        }
    
        private static final class JTimerLabel extends JLabel{
            private static JTimerLabel INSTANCE;
    
            private JTimerLabel(){
                super(String.valueOf(0));
                setFont(new Font("Courier New", Font.BOLD,  18));
            }
    
            public static final JTimerLabel getInstance(){
                if(INSTANCE == null){
                    INSTANCE = new JTimerLabel();
                }
    
                return INSTANCE;
            }
        }
    }
    

    这个SSCCE模拟每秒从0开始计数的计数器(即更新JLabel实例),直到应用程序终止