java - 如何在同一个按钮上添加两个ActionListener来执行Timer.start()/Timer.stop()方法

标签 java

我试图制作一个秒表,并且在我在这里找到的一些 YouTube 视频和代码的帮助下我能够做到这一点。但所有这些代码都有两个 JButton 对象,一个用于启动计时器,另一个用于停止计时器。任何人都可以帮助我通过一个按钮执行启动和停止功能。提前致谢。

以下是我尝试过但不起作用的方法之一。

import javax.swing.*;
import java.awt.event.*;

public class Test extends JFrame
{
private Timer t;
private int sec, min, hrs;
static private JPanel p;
private JButton start;
private JLabel l1;

public Test()
{
    p = new JPanel();
    l1 = new JLabel("" + hrs + " : " + min + " : " + sec);
    start = new JButton("Start");
    start.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
            t = new Timer(1000, new ActionListener() {
                public void actionPerformed(ActionEvent ev)
                {
                    sec++;
                    if (sec == 60)
                    {
                        min++;
                        sec = 0;
                    }
                    if (min == 60)
                    {
                        hrs++;
                        min = 0;
                    }
                    l1.setText("" + hrs + " : " + min + " : " + sec);
                    start.setText("Stop");

                }
            });
            t.start();
            if(start.getText().equals("Stop"))
            {
                start.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent eve)
                    {
                        t.stop();
                    }
                });
            }
        }
    });

    p.add(l1);
    p.add(start);
}

public static void main(String[] args)
{
    Test te = new Test();
    te.add(p);
    te.setSize(240, 360);
    te.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    te.setVisible(true);
}
}

最佳答案

尝试这样的类(class):

class ToggleButton extends JButton {
    private boolean selected;
    private String otherText;

    public ToggleButton(String text, String otherText) {
        super(text);
        this.otherText = otherText;
        this.setSelected(true);
        this.fixListener();
    }

    public boolean isSelected() {
        return selected;
    }

    public void setSelected(boolean selected) {
        this.selected = selected;
    }

    private void fixListener() {
        addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (isSelected()) {
                    setSelected(false);
                    t.start();
                } else {
                    setSelected(true);
                    t.stop();
                }
                String text = getText();
                setText(otherText);
                otherText = text;
            }
        });
    }
}

并像这样调用它:JButton start = new ToggleButton("Start","Stop");

这也意味着,如果计时器也可以通过另一个按钮或方法停止和启动,则需要更新此按钮。这就是为什么 setSelected() 是公开的。

我还添加了一个计时器类来帮助您使用计时器。 通过执行new Timer(ping);来初始化它(ping是一个整数,显示以毫秒为单位的刻度之间的延迟)。 分别使用 start()pause() 启动和暂停它。

public class Timer extends Thread {
    private Thread thread;
    private boolean running;
    private boolean paused;
    private int ping;

    public Time(int ping){
        this.ping = ping;
        running = false;
        paused = true;
    }

    private void loop(){
        while(running){
            if(paused){
                tick();//check at the end
            }
            delay(ping);
        }
    }

    private void delay(int mil) {
        try {
            Thread.sleep(mil);
        } catch (InterruptedException e) {
        }
    }

    public void start() {
        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }else{
            paused = false;
        }
    }

    public void pause(){
        paused = true;
    }

    public void reset(){
        thread = null;
        running = false;
        paused = true;
    }

    @Override
    public void run() {
        running = true;
        paused = false;
        loop();
    }
}

将此方法添加到您的测试类

public void tick(){
    sec++;
    if (sec >= 60){
        min++;
        sec = sec - 60;
    }
    if (min >= 60){
        hrs++;
        min = min - 60;
    }
}

修复了您的测试类,只需将其更改为:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Test extends JFrame {
    private Timer timer;
    private int sec, min, hrs;
    private JPanel panel;
    private JButton start;
    private JLabel label1;

    public Test() {
        panel = new JPanel();
        label1 = new JLabel("" + hrs + " : " + min + " : " + sec);
        timer = new Timer(1000);
        start = new ToggleButton("Start", "Stop");
        panel.add(label1, BorderLayout.NORTH);
        panel.add(start, BorderLayout.SOUTH);
        getContentPane().add(panel, BorderLayout.CENTER);
        setVisible(true);
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.setSize(240, 360);
        test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void tick() {
        sec++;
        if (sec >= 60) {
            min++;
            sec = sec - 60;
        }
        if (min >= 60) {
            hrs++;
            min = min - 60;
        }
        label1.setText("" + hrs + " : " + min + " : " + sec);
    }

    private class ToggleButton extends JButton {
        private boolean selected;
        private String otherText;

        public ToggleButton(String text, String otherText) {
            super(text);
            this.otherText = otherText;
            this.setSelected(true);
            this.fixListener();
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean selected) {
            this.selected = selected;
        }

        private void fixListener() {
            addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    if (isSelected()) {
                        setSelected(false);
                        timer.start();
                    } else {
                        setSelected(true);
                        timer.pause();
                    }
                    String text = getText();
                    setText(otherText);
                    otherText = text;
                }
            });
        }
    }

    private class Timer extends Thread {
        private Thread thread;
        private boolean running;
        private boolean paused;
        private int ping;

        public Timer(int ping) {
            this.ping = ping;
            running = false;
            paused = true;
        }

        private void loop() {
            while (running) {
                if (!paused) {
                    tick();
                }
                delay(ping);
            }
        }

        private void delay(int mil) {
            try {
                Thread.sleep(mil);
            } catch (InterruptedException e) {
            }
        }

        public void start() {
            if (thread == null) {
                thread = new Thread(this);
                thread.start();
            } else {
                paused = false;
            }
        }

        public void pause() {
            paused = true;
        }

        @Override
        public void run() {
            running = true;
            paused = false;
            loop();
        }
    }
}

关于java - 如何在同一个按钮上添加两个ActionListener来执行Timer.start()/Timer.stop()方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38431278/

相关文章:

java - 将服务器上存储的pdf文件打印到客户端打印机

java - 经过训练的神经网络对所有评估行输出相同的结果

java - 我如何必须返回 Iterator<E> 的 "next"方法?

java - Text.setText() 不更新文本,抛出 NullPointerException

java - 带有 Apache Tiles 的 AngularJS

java - 如何将 void 方法结果存储到 int 数组方法中

java - Java中MongoDB的MapReduce函数返回null

Javascript:eval 中的 replaceAll 不起作用

java - HashMap 类型不是通用的;它不能用参数 <String, Integer> 参数化

java - 在netbeans中安装定时器组件?