开发者

how to update a jLabel every time with a while loop with a delay

   private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                开发者_JAVA百科                         
  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) { }

 }

It will eventually show the final number on the jLabel but it does not incrementally update the number. any help


Swing is single-threaded. Therefore, long-running tasks should never take place in the EDT. This includes sleeping. Instead, use a javax.swing.Timer. This will delay in a background thread, and then post an action to be executed in the EDT.

See also:

  • How to Use Swing Timers

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

This SSCCE imitates a counter that will count up from 0 every second (i.e. update the JLabel instance) until the application is terminated.


Your problem is that your doing something time consuming in an ActionPerformed callback, which executes in the event thread. In callbacks, you should do something quickly and return, even if that "something" is spawning a thread. The GUI can't update while you're occupying the event thread, it will only update after your callback returns.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜