0

スタートストップとリセットボタンを備えたシンプルなタイマーを作成しようとしています。Threads と 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 に答える