【问题标题】:Java Swing Timer CountdownJava Swing 计时器倒计时
【发布时间】:2015-04-04 22:32:50
【问题描述】:

我必须制作一个倒计时程序,它还显示十分之一秒; 例如从 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 秒。

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

int timeLeft2=5;

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

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

他们不一样是很自然的吗?

【问题讨论】:

  • 您需要显示毫秒还是分秒? IE。 9.8s、9.7s...或9.899s、9.898s...
  • 9.8, 9.7 会很好:D
  • 请在计时器上包含您安排倒计时2(以及倒计时)的行。您是否以相同的时间间隔执行它们?
  • 已更新:D 抱歉,详情不完整
  • 你的意思是 timer.start() 和 timer2.start() 吗?我的意思是您初始化计时器的行。例如timer = new Timer(100, 倒计时); timer2 = new Timer(1000, 倒计时);

标签: java swing timer


【解决方案1】:

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

您应该尝试计算Timer 的启动时间与当前时间之间的差异,例如...

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

    }

}

【讨论】:

    【解决方案2】:

    更新标签可能需要超过 1 毫秒,这就是它无法跟上的原因。如果您只需要显示十分之一秒,只需减少计时器更新的频率即可。

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

    【讨论】:

    • 哦.. 我编辑了我的帖子,因为我尝试使用只有几秒钟的普通计时器,一个计时器显示的结果与另一个计时器不同是否正常?即 timer1 是 5.5s 而 timer2 仍然是 7s
    • 好的,我用秒表试了一下哈哈,谢谢它已经同步了
    • 请注意,这可能会根据运行时间和系统中可能发生的其他情况(如何例如,美国东部时间很忙)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    相关资源
    最近更新 更多