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

后端 未结 2 1293
一向
一向 2020-12-10 22:58
   private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
  int count = jSlider1.getValue(); 
  int delay =          


        
相关标签:
2条回答
  • 2020-12-10 23:06

    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 讨论(0)
  • 2020-12-10 23:19

    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.

    0 讨论(0)
提交回复
热议问题