【问题标题】:Swing Timer stopwatch in JavaJava中的Swing Timer秒表
【发布时间】:2015-11-02 21:22:02
【问题描述】:

有人可以为我提供一个使用不断更新的 JLabel 的 Java 中 Swing Timer 秒表 GUI 的示例吗?我不熟悉使用@Override,所以除非绝对必要,否则请不要在其中建议代码(我已经完成了其他 Swing Timers,例如系统时钟,没有它)。

谢谢!

编辑:根据@VGR 的要求,这是我使用摆动计时器的基本时钟的代码:

import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.FlowLayout;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Font;

public class basic_clock extends JFrame
{
    JLabel date, time;

    public basic_clock()
    {
        super("clock");

        ActionListener listener = new ActionListener()
        {
            public void actionPerformed(ActionEvent event)
            {
                Calendar current = Calendar.getInstance();
                current.setTime(new Date());
                date.setText((current.get(Calendar.MONTH) + 1) +"/" +current.get(Calendar.DATE) +"/" +current.get(Calendar.YEAR));
                String timeStr = String.format("%d:%02d:%02d", current.get(Calendar.HOUR), current.get(Calendar.MINUTE), current.get(Calendar.SECOND));
                time.setText(timeStr);                
            }
        };

        date = new JLabel();
        time = new JLabel();

        setLayout(new FlowLayout());
        setSize(310,190);
        setResizable(false);
        setVisible(true);

        add(date);
        add(time);

        date.setFont(new Font("Arial", Font.BOLD, 64));
        time.setFont(new Font("Arial", Font.BOLD, 64));

        javax.swing.Timer timer = new javax.swing.Timer(500, listener);
        timer.setInitialDelay(0);
        timer.start();
    }

    public static void main(String args[])
    {

        basic_clock c = new basic_clock();
        c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

显然我需要不同于 Calendar 对象的东西,因为我想跟踪分钟和秒到最接近的 1/100 秒,而不是日期/月/年/小时/分钟/秒。

【问题讨论】:

  • 你的谷歌坏了吗? Maybe this will help
  • 如果您以前使用过 Swing Timer,那么您必须至少已经编写了一些代码。编辑您的问题以显示您到目前为止所拥有的内容。 “为我编写所有代码”不是一个有效的问题。
  • "@Override,所以除非绝对必要,否则请不要在其中建议代码" - 强烈建议@Override 阻止开发人员犯愚蠢的错误和拼写错误的方法,“认为”它们是压倒一切的。我强烈建议您花时间研究并了解它为您的开发生活带来哪些优势,这将有助于防止您犯愚蠢的小错误
  • @MadProgrammer - 我用谷歌搜索它,但我不理解我找到的代码。

标签: java swing timer stopwatch


【解决方案1】:

我为它使用了谷歌,但我不理解我找到的代码

那么你有一个更大的问题。您希望我们中的任何人如何为您提供您可以理解的示例?

秒表在概念上非常简单,它只是自启动以来经过的时间量。当您希望能够暂停计时器时会出现问题,因为您需要考虑计时器已经运行的时间加上自上次启动/恢复以来的时间。

另一个问题是,大多数计时器只保证最少的时间,因此它们不精确。这意味着您不能只将计时器的延迟量添加到某个变量中,最终会得到一个漂移值(不准确)

这是一个非常简单的例子,它所做的只是提供了一个开始和停止按钮。每次启动秒表,都会再次从0开始。

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import javax.swing.JButton;
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 SimpleStopWatch {

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

    public SimpleStopWatch() {
        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 StopWatchPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class StopWatchPane extends JPanel {

        private JLabel label;
        private long lastTickTime;
        private Timer timer;

        public StopWatchPane() {
            setLayout(new GridBagLayout());
            label = new JLabel(String.format("%04d:%02d:%02d.%03d", 0, 0, 0, 0));

            timer = new Timer(100, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    long runningTime = System.currentTimeMillis() - lastTickTime;
                    Duration duration = Duration.ofMillis(runningTime);
                    long hours = duration.toHours();
                    duration = duration.minusHours(hours);
                    long minutes = duration.toMinutes();
                    duration = duration.minusMinutes(minutes);
                    long millis = duration.toMillis();
                    long seconds = millis / 1000;
                    millis -= (seconds * 1000);
                    label.setText(String.format("%04d:%02d:%02d.%03d", hours, minutes, seconds, millis));
                }
            });

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(4, 4, 4, 4);
            add(label, gbc);

            JButton start = new JButton("Start");
            start.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!timer.isRunning()) {
                        lastTickTime = System.currentTimeMillis();
                        timer.start();
                    }
                }
            });
            JButton stop = new JButton("Stop");
            stop.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    timer.stop();
                }
            });

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.weightx = 0;
            gbc.gridwidth = 1;
            add(start, gbc);
            gbc.gridx++;
            add(stop, gbc);
        }

    }

}

添加暂停功能并不难,它只需要一个额外的变量,但我会让你自己弄清楚。

【讨论】:

  • 非常感谢您,MadProgrammer。接下来,我想做的是在其中实现倒计时功能。我希望能够,而不是停止计时器,允许第二个按钮然后导致已经过去的时间开始倒计时到零。我知道这听起来很奇怪,但我有它的用途。关于我如何能够实现它的任何建议?
  • 这基本上是相同的概念,除了我会使用两个Timers 开始,一个用于前向操作,一个用于后向操作。您有一个“持续时间”,您需要从中减去 Timer 的运行时间
  • 感谢@MadProgrammer。现有的“持续时间”对象本质上是自计时器启动以来经过的时间,对吗?如果我将现有 Timer 代码复制/粘贴到第二个 Timer 中以允许它倒计时而不是倒计时,我会对现有 Timer 代码进行哪些更改?另外,我注意到程序中 JLabel 的毫秒部分中的千分之一和百分之一数字看起来有点小故障(它们不会流畅地移动),但十分之一看起来很正常 - 这是因为你正在占用系统时间仅每 1/10 秒毫秒?
  • Duration 类允许我简单地进行计算以获取要显示的值(java 8 Time API)。正如我在回答中所说,Timer 不准确,它只能保证延迟至少达到指定的数量,可能更多。
【解决方案2】:

对于像我这样更喜欢专注于运动的秒表的人来说,我们的想法是在单击开始按钮时发出声音,以及“Take your Marks”按钮及其相应的声音。例如,在奥运会游泳比赛视频中,我录制了“Take your mark”和开始时的哔声(练习时大喊 GO!就够了)。使用 MadProgrammer 的回答,您将需要很小的 Jaco lib 来播放您想要的 mp3 文件。在 Android 应用中实现这一点是可行的方法。

编辑:这应该是一个评论,但我仍然没有声誉,因此,我想分享这个想法以用于不同的用途。我还添加了一个重置​​按钮。

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.io.File;
import jaco.mp3.player.MP3Player;


public class TimerStopwatch {

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

    public TimerStopwatch() {
        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 StopWatchPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class StopWatchPane extends JPanel {

        private JLabel label;
        private long lastTickTime;
        private Timer timer;

        public StopWatchPane() {
            setLayout(new GridBagLayout());
            label = new JLabel(String.format("%02d:%02d:%02d.%03d", 0, 0, 0, 0));

            timer = new Timer(100, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    long runningTime = System.currentTimeMillis() - lastTickTime;
                    Duration duration = Duration.ofMillis(runningTime);
                    long hours = duration.toHours();
                    duration = duration.minusHours(hours);
                    long minutes = duration.toMinutes();
                    duration = duration.minusMinutes(minutes);
                    long millis = duration.toMillis();
                    long seconds = millis / 1000;
                    millis -= (seconds * 1000);
                    label.setText(String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis));
                }
            });

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.insets = new Insets(4, 4, 4, 4);
            add(label, gbc);

            JButton start = new JButton("Start");
            start.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (!timer.isRunning()) {
                        lastTickTime = System.currentTimeMillis();
                        /* This will play the Beep or Fire sound of your choice */
                        new MP3Player(new File("Beep.mp3")).play();
                        timer.start();


                    }
                }
            });
            JButton stop = new JButton("Stop");
            stop.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    timer.stop();
                }
            });
            
            /* This button will play the "Take your marks" recording of your choice  */
            JButton takeyourmarks = new JButton("Take your Marks");
            takeyourmarks.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new MP3Player(new File("Marks1.mp3")).play();
                }
            });

            JButton reset = new JButton("Reset");
            reset.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    label.setText(String.format("%02d:%02d:%02d.%03d", 0, 0, 0, 0));
                }
            });

            gbc.gridx = 0;
            gbc.gridy++;
            gbc.weightx = 0;
            gbc.gridwidth = 1;
            add(takeyourmarks, gbc);
            gbc.gridx++;
            add(start, gbc);
            gbc.gridx++;
            add(stop, gbc);
            gbc.gridx++;
            add(reset, gbc);

        }

    }

}

【讨论】:

    猜你喜欢
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-23
    • 2012-02-11
    相关资源
    最近更新 更多