JavaFX stopwatch timer


Question

This is a class for a simple stopwatch for JavaFX, style the Label object as desired

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

Now just get a listener on the property for your GUI

Add vars

    KTimer ktimer;
    Label timeLabel;

in your class initialize the vars

    //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());
        }
    });

then call the method to start and stop wherever you need to

Stop and reset is

                ktimer.stopTimer(0);

Start and Pause timer is

               ktimer.startTimer(ktimer.getTime());

Any improvements appreciated as the class is a bit CPU hungry..., but you can adjust the run thread and setTime(time) functions to suit the application

1
6
2/21/2012 4:25:18 PM

Building on KEV's answer and various demos I found across the internet, here's a simple "count up" timer with 100ms precision:

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);
    }
}
4
3/23/2014 1:44:52 PM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon