我试图制作一个秒表,在这里找到的一些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 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();
}
}
}
您可以声明一个表示计时器是否打开的字段。在ActionListener
中,您可以在调用该变量时检查其状态,并根据该状态停止或启动计时器。
start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent eve){
if(timerIsOn)
t.stop();
else
t.start();
timerIsOn = !timerIsOn; // This will toggle the value of the variable, so if it was false it will now be true and vice versa
}
});
将timerIsOn
替换为您声明的字段的名称,并确保使用值false
对其进行初始化。