0

我正在尝试创建一个带有开始停止和重置按钮的简单计时器。我是使用线程和 ActionListeners 的新手。我有这个工作,可以让我的计时器开始,我的按钮可以从开始到停止更改文本。但在那之后我被困住了。如果我按下开始按钮,我需要停止计时器,然后重新启动它。然后当然重置将其变回零。我不想使用java.util.Timer,我只想使用线程。一旦开始,我将如何让我的线程暂停然后恢复。我尝试使用内置方法,但无法正确编译。

import javax.swing.*;
import java.awt.Font;
import java.lang.String;
import java.awt.*;

public class Timer extends JPanel {

  // Here are the fields from below!

  private static JLabel label = new JLabel("   0.00 seconds");
  private static javax.swing.JButton start = new javax.swing.JButton("Start");
  private static javax.swing.JButton reset = new javax.swing.JButton("reset");

  /**
   * Here is the Timer method- Begins with JLabel with medium alignment.
   */
  public Timer() {
    //new Thread(this).start();
    //label = new JLabel("   0.00 Seconds");
    //this.label = label;
    reset();
  }


  /**
   * Here is the Reset method- pressing this button from below will 
   * stop the thread and reset the text.
   */
  public static void reset() {
    label.setFont(new Font("Arial",Font.BOLD,36));
    label.setText("   0.00 Seconds");

  }

  public static void startStop() {
    //start.setText("stop");
    //validate();

  }

  public static void countDown() {
    int Msec=0,min=0,sec=0;
    while(sec < 60) {
          label.setText(min+":"+sec+":"+Msec);
          //label.setLayout(new BorderLayout.CENTER);
          //label.
          Msec++;
          if(Msec==60) {
            Msec=0;
            sec++;
            //label.setText(min+":"+sec+":"+Msec);
          }
          if(sec ==60) {
            Msec =0;
            sec = 0;
            min++;
          }
          try
        {
          Thread.sleep(10);
        }
        catch(Exception e)
        {}
      }
  }      

public static void main(String [] args) {

  // we need a JFrame to put these elements into
  javax.swing.JFrame win = new javax.swing.JFrame("Timer");
  // here we are instantating a new timer
  final Timer time = new Timer();

  //Annonymous inner class
  start.addActionListener(new java.awt.event.ActionListener() {
    // here is the action performed method to start this.
    public void actionPerformed(java.awt.event.ActionEvent e) {
      //here we are creating a new thread to run throwable
      // every click creates a new Thread ( so it goes faster)
      String text = (String)e.getActionCommand();
      if (text.equals("Start")){
        start.setText("Stop");
      }
      else{
        start.setText("Start");
      }
      Thread restart = new Thread(new Runnable() {
        public void run() {
          countDown();
          //startStop();
        }

      });
      restart.start();
    }
  });


  //Look at the below abstract actionlistener below to get reset to work
  javax.swing.JButton reset = new javax.swing.JButton("reset");

  // here we are creating a new annonomys inner class.... check the
  // curly braces
  reset.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent e) {
      Thread restart = new Thread(new Runnable() {
        public void run() {
          reset();
          //Thread.stop();
        }

      });
      restart.destroy();
    }
  });


  //label.setVisible(true);

  javax.swing.JPanel tb = new javax.swing.JPanel();
  tb.add(reset);
  tb.add(start);
  //tb.add(circle);
  win.add(tb,java.awt.BorderLayout.NORTH);
  win.setSize(300,300);
  //win.add(tb);
  win.add(label,java.awt.BorderLayout.CENTER);

  win.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);
  // hiding inside setVisible is borderLayout
  win.setVisible(true);
}
}
4

1 回答 1

1

你想通过线程练习和改进是令人钦佩的,也是一个伟大的目标,但这真的不是它的舞台。问题是 Swing 是单线程的——只有 ui 线程应该更新图形环境。

对于涉及图形的操作,您应该使用 javax.swing.Timer 和 javax.swing.SwingWorker,因为它们是线程安全的。一方面,你在这里学习线程安全,所以你正在进步!

于 2012-04-25T20:47:03.703 回答