Java Swing Timer Countdown

后端 未结 2 698
梦谈多话
梦谈多话 2020-11-30 16:17

I have to make a countdown program which also shows the tenths of a second; for example from a 10.0 second countdown, it should display 9.9s, 9.8s, ... 0.0s

         


        
相关标签:
2条回答
  • 2020-11-30 16:21

    The time between ticks (the time when actionPerfomed is called) is variable, it only guarantees that it will be at least n milliseconds

    Instead of relying on some counter, which could become unreliable over time, you should try and calculate the difference between the time the Timer was started and the current time, for example...

    CountDown

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.text.SimpleDateFormat;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class CountDown {
    
        public static void main(String[] args) {
            new CountDown();
        }
    
        public CountDown() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private Timer timer;
            private long startTime = -1;
            private long duration = 5000;
    
            private JLabel label;
    
            public TestPane() {
                setLayout(new GridBagLayout());
                timer = new Timer(10, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (startTime < 0) {
                            startTime = System.currentTimeMillis();
                        }
                        long now = System.currentTimeMillis();
                        long clockTime = now - startTime;
                        if (clockTime >= duration) {
                            clockTime = duration;
                            timer.stop();
                        }
                        SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
                        label.setText(df.format(duration - clockTime));
                    }
                });
                timer.setInitialDelay(0);
                addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        if (!timer.isRunning()) {
                            startTime = -1;
                            timer.start();
                        }
                    }
                });
                label = new JLabel("...");
                add(label);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
        }
    
    }
    
    0 讨论(0)
  • 2020-11-30 16:46

    Updating the label probably takes more that 1ms, which is why it can't keep up. If you only need to display tenths of a second, simply have your timer update less often.

    ActionListener countDown=new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            timeLeft -= 100;
            SimpleDateFormat df=new SimpleDateFormat("mm:ss:S");
            jLabel1.setText(df.format(timeLeft));
            if(timeLeft<=0)
            {
                timer.stop();
            }
        }
    };
    Timer timer=new Timer(100, countdown);
    
    0 讨论(0)
提交回复
热议问题