Java Swing 定时器倒计时

标签 java swing timer

我必须制作一个倒计时程序,它还显示十分之一秒; 例如,从 10.0 秒倒计时开始,它应该显示 9.9s、9.8s、...0.0s

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

        timer.start();
        timer2.start();

}                                        


Double timeLeft=5000; //5 seconds
Timer timer=new Timer(1,countDown);
Timer timer2=new Timer(1000,countDown2);
ActionListener countDown=new ActionListener()
{
    public void actionPerformed(ActionEvent e)
    {
        timeLeft--;
        SimpleDateFormat df=new SimpleDateFormat("mm:ss:S");
        jLabel1.setText(df.format(timeLeft));
        if(timeLeft<=0)
        {
            timer.stop();
        }
    }
};

实际情况是需要超​​过 5 秒才能完成这 5 秒。

我将上面的代码与另一个计时器进行了比较

int timeLeft2=5;

ActionListener countDown2=new ActionListener()
{
    public void actionPerformed(ActionEvent e)
    {
        timeLeft2--;

        jLabel2.setText(String.valueOf(timeLeft2));
        if(timeLeft2<=0)
        {
            time2.stop();
        }                  
    }
};

他们得到的结果不同是很自然的吗?

最佳答案

滴答之间的时间(调用 actionPerfomed 的时间)是可变的,它只能保证至少为 n 毫秒

您应该尝试计算 Timer 启动时间与当前时间之间的差异,而不是依赖某个随着时间的推移而变得不可靠的计数器,例如...

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

    }

}

关于Java Swing 定时器倒计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28337718/

相关文章:

java - 我能够捕获 jtable 中的 TAB,但如何捕获 SHIFT+TAB?

ios - NSTimer 似乎被 MKMapView 平移减慢了速度?

java - timerSchedule 不服从启动定时器设置?

java - 多个 "cannot find symbol"错误

java - Android 中的计时器在延迟时无法正确重复

java - 如何在不修改底层接口(interface)的情况下以覆盖样式创建内部框架?

java - 如何在 Android Studio 中使用另一个计时器启动计时器

Java左移并用零填充

java - 显示列表的内容

java - 如何使一个类成为 Java Swing 中的组件?