JavaFX秒表计时器

时间:2012-02-20 01:59:36

标签: time javafx stopwatch

这是一个用于JavaFX的简单秒表的类,根据需要设置Label对象的样式

package aaa;

import java.text.SimpleDateFormat;
import java.util.Date;
import javafx.beans.property.SimpleStringProperty;

/**
 *
 * @author D07114915
 */
public class KTimer extends Thread {

private Thread thread = null;
private SimpleDateFormat sdf = new SimpleDateFormat("mm:ss:S");
private String[] split;
private SimpleStringProperty min, sec, millis, sspTime;
private long time;

public static void main(String[] args) {
    KTimer t = new KTimer();
    t.startTimer(00);
}

public KTimer() {
    min = new SimpleStringProperty("00");
    sec = new SimpleStringProperty("00");
    millis = new SimpleStringProperty("00");
    sspTime = new SimpleStringProperty("00:00:00");
}

public void startTimer(long time) {
    this.time = time;
    thread = new Thread(this);
    thread.setPriority(Thread.MIN_PRIORITY);
    thread.start();
}

public void stopTimer(long time) {
    if (thread != null) {
        thread.interrupt();
    }
    this.time = time;
    setTime(time);
}

public void setTime(long time) {
    this.time = time;
    split = sdf.format(new Date(time)).split(":");
    min.set(split[0]);
    sec.set(split[1]);

    if (split[2].length() == 1) {
        split[2] = "0" + split[2];
    }
    millis.set(split[2].substring(0, 2));

    sspTime.set(min.get() + ":" + sec.get() + ":" + millis.get());
}

public long getTime() {
    return time;
}

public SimpleStringProperty getSspTime() {
    return sspTime;
}

@Override
public void run() {
    try {
        while (!thread.isInterrupted()) {
            setTime(time);
            sleep(10);
            time = time + 10;
        }
    } catch (Exception e) {
    }

}
}//end of class

现在只需在属性上获取GUI的监听器

添加变种

    KTimer ktimer;
    Label timeLabel;
你班上的

初始化变种

    //Clock
    ktimer = new KTimer();
    timeLabel = new Label(ktimer.getSspTime().get());
    ktimer.getSspTime().addListener(new InvalidationListener() {

        @Override
        public void invalidated(Observable observable) {
            timeLabel.setText(ktimer.getSspTime().get());
        }
    });

然后调用方法在任何需要的地方启动和停止

停止并重置

                ktimer.stopTimer(0);

启动和暂停计时器

               ktimer.startTimer(ktimer.getTime());

由于该类有点CPU饥饿感,所以有任何改进...,但您可以调整运行线程和setTime(时间)函数以适应应用程序

2 个答案:

答案 0 :(得分:4)

这是一个略有不同的版本(可能更好),我不确定同步方法是否真的有必要

package aaa;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javafx.beans.property.SimpleStringProperty;

/**
 *
 * @author D07114915
 */
public class KTimer {

private SimpleDateFormat sdf = new SimpleDateFormat("mm:ss:S");
private String[] split;
private SimpleStringProperty sspTime;
private long time;
private Timer t = new Timer("Metronome", true);
private TimerTask tt;
boolean timing = false;

public KTimer() {
    sspTime = new SimpleStringProperty("00:00:00");
}

public void startTimer(final long time) {
    this.time = time;
    timing = true;
    tt = new TimerTask() {

        @Override
        public void run() {
            if (!timing) {
                try {
                    tt.cancel();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                updateTime();
            }
        }
    };
    t.scheduleAtFixedRate(tt, 10, 10);
}

public synchronized void stopTimer() {
    timing = false;
}

public synchronized void updateTime() {
    this.time = this.time + 10;
    split = sdf.format(new Date(this.time)).split(":");
    sspTime.set(split[0] + ":" + split[1] + ":" + (split[2].length() == 1 ? "0" + split[2] : split[2].substring(0, 2)));
}

public synchronized void moveToTime(long time) {
    stopTimer();
    this.time = time;
    split = sdf.format(new Date(time)).split(":");
    sspTime.set(split[0] + ":" + split[1] + ":" + (split[2].length() == 1 ? "0" + split[2] : split[2].substring(0, 2)));
}

public synchronized long getTime() {
    return time;
}

public synchronized SimpleStringProperty getSspTime() {
    return sspTime;
}
}

答案 1 :(得分:4)

基于我在互联网上找到的KEV的答案和各种演示,这里有一个简单的"计数"精度为100ms的定时器:

package fxtimer;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;

public class FXTimer extends Application {

    private Timeline timeline;
    private Label timerLabel = new Label(), splitTimerLabel = new Label();
    private DoubleProperty timeSeconds = new SimpleDoubleProperty(),
            splitTimeSeconds = new SimpleDoubleProperty();
    private Duration time = Duration.ZERO, splitTime = Duration.ZERO;

    @Override
    public void start(Stage primaryStage) {
        // Configure the Label
        // Bind the timerLabel text property to the timeSeconds property
        timerLabel.textProperty().bind(timeSeconds.asString());
        timerLabel.setTextFill(Color.RED);
        timerLabel.setStyle("-fx-font-size: 4em;");
        splitTimerLabel.textProperty().bind(splitTimeSeconds.asString());
        splitTimerLabel.setTextFill(Color.BLUE);
        splitTimerLabel.setStyle("-fx-font-size: 4em;");

        // Create and configure the Button
        Button button = new Button();
        button.setText("Start / Split");
        button.setOnAction(new EventHandler() {
            @Override
            public void handle(Event event) {
                if (timeline != null) {
                    splitTime = Duration.ZERO;
                    splitTimeSeconds.set(splitTime.toSeconds());
                } else {
                    timeline = new Timeline(
                        new KeyFrame(Duration.millis(100),
                        new EventHandler<ActionEvent>() {
                            @Override
                            public void handle(ActionEvent t) {
                                Duration duration = ((KeyFrame)t.getSource()).getTime();
                                time = time.add(duration);
                                splitTime = splitTime.add(duration);
                                timeSeconds.set(time.toSeconds());
                                splitTimeSeconds.set(splitTime.toSeconds());
                            }
                        })
                    );
                    timeline.setCycleCount(Timeline.INDEFINITE);
                    timeline.play();
                }
            }
        });

        // Setup the Stage and the Scene (the scene graph)
        StackPane root = new StackPane();
        Scene scene = new Scene(root, 300, 250);

        // Create and configure VBox
        // gap between components is 20
        VBox vb = new VBox(20);
        // center the components within VBox
        vb.setAlignment(Pos.CENTER);
        // Make it as wide as the application frame (scene)
        vb.setPrefWidth(scene.getWidth());
        // Move the VBox down a bit
        vb.setLayoutY(30);
        // Add the button and timerLabel to the VBox
        vb.getChildren().addAll(button, timerLabel, splitTimerLabel);
        // Add the VBox to the root component
        root.getChildren().add(vb);

        primaryStage.setTitle("FX Timer");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}