Question

   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) { }

 }

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

Was it helpful?

Solution

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:


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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top