有没有一种方法可以在JFrame中生成一个计时器?

时间:2013-11-30 04:00:19

标签: java swing timer

我正在制作游戏。在BorderLayout(North)我想在你玩的时候显示一个计时器。当你输了,JOptionPane.showMessageDialog显示时间。当你获胜时,在JOptionPane.showMessageDialog胜利的最佳时间显示。

我知道如何使用JOptionPane.showMessageDialog,但我不知道java中是否有一个生成计时器的方法,并获取值,设置值等。 谢谢!如果有人需要更多信息,请告诉我......

2 个答案:

答案 0 :(得分:3)

一些警告开头......

Swing是一个单线程环境,也就是说,所有与UI的交互都应该在Event Dispatching Thread的上下文中执行。同样,您永远不应该阻止EDT,因为这会阻止它处理新事件,包括重绘请求。

为此,最简单的方法是使用类似javax.swing.Timer的方法,它允许您在EDT的上下文中定期执行重复调用

有关详细信息,请参阅How to use Timers ...

enter image description here

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.util.concurrent.TimeUnit;
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 CountDownTimer {

    public static void main(String[] args) {
        new CountDownTimer();
    }

    public CountDownTimer() {
        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 static class TestPane extends JPanel {

        private JLabel label;
        private long startTime = -1;
        private long timeOut = 10;

        public TestPane() {

            label = new JLabel("...");
            final Timer timer = new Timer(500, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {


                    if (startTime == -1) {
                        startTime = System.nanoTime();
                    } else {
                        long endTime = startTime + TimeUnit.SECONDS.toNanos(10);
                        long time = System.nanoTime();

                        if (time < endTime) {
                            long timeLeft = (endTime - time);
                            label.setText(Long.toString(TimeUnit.NANOSECONDS.toSeconds(timeLeft)) + " seconds");
                        } else {
                            label.setText("Time out");
                            ((Timer) e.getSource()).stop();
                        }
                        revalidate();
                        repaint();
                    }
                }
            });
            timer.setInitialDelay(0);
            timer.start();

            setLayout(new GridBagLayout());
            add(label);

        }

    }

}

答案 1 :(得分:1)

您正在寻找一种方法来了解需要多长时间。在编程中通常不是计时器。

您可能正在寻找System.currentTimeMillis来记录开头的时间,然后再搜索结尾的时间,并采取差异来获得“花费的时间”。

This thread解释了如何将其转换为秒。

编辑:Vulcan有一个好处。 System.nanoTime更值得信赖,因为它对用户更改系统时间具有弹性,并提供更高的分辨率。但请注意,正如它所述in the documentation:“此方法提供纳秒级精度,但不一定是纳秒级分辨率(即,值的变化频率) - 除了分辨率至少与分辨率一样好之外,不做任何保证currentTimeMillis()的那个。 Here是关于nanoTime的讨论。