7

I am trying to add a timer to my program. I've tried calling upon java.util.Timer but it frustrates me as i do not completely understand the concepts behind it. I have just done a semester of coding in python but this is an entirely different level to me.

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.awt.event.ActionListener;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class main extends Application implements EventHandler<ActionEvent>{

    Button button;
    Button button2;
    Counter counter = new Counter(0);
    Counter timecounter = new Counter(0);
    Text text_counter = new Text(counter.S_count.get());
    Text text_timecounter = new Text(timecounter.S_count.get());

    Date currdate = new Date();
    int currsec = currdate.getSeconds();


    public static void main(String[] args) {
        launch(args);


    }


    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Counter Window");

        button = new Button();
        button2 = new Button();
        button.setText("Reset");
        button.setOnAction(this);
        button2.setText("Tick");
        button2.setOnAction(this);
        button.setTranslateY(-120);
        button2.setTranslateY(-80);
        text_counter.textProperty().bind(counter.S_count);
        text_timecounter.textProperty().bind(timecounter.S_count);
        text_timecounter.setTranslateX(-100);



        StackPane layout = new StackPane();
        layout.getChildren().add(button);
        layout.getChildren().add(button2);
        layout.getChildren().add(text_counter);
        layout.getChildren().add(text_timecounter);

        Scene scene = new Scene(layout, 360,280);
        primaryStage.setScene(scene);

        primaryStage.show();
    }

    @Override
    public void handle(ActionEvent event) {
        if(event.getSource()==button){
            counter.Reset();
        }
        if(event.getSource()==button2){
            counter.Tick();
        }
    }
}

I built a program in python with a main loop. I was thinking of a "dirty" way of doing it by adding a check to the loop that checks if the seconds of the current date has changed and if it has, increment a value by one.

class timerclass {
    Timer timer1;
    private int timecounter = 0;

    TimerTask Task1 = new TimerTask() {
        @Override
        public void run() {
            setTimecounter(getTimecounter()+1);
        }
    };

    public timerclass(){
        timer1 = new Timer();

    }

    public int getTimecounter() {
        return timecounter;
    }

    public void setTimecounter(int timecounter) {
        this.timecounter = timecounter;
    }
}

This is how far i've come creating a new timer. I understood that I have to create a task and schedule it to the timer but I don't have the slightest clue how...

How would I go about this? Sorry for the inconvieniences.

Dennis Lukas
  • 483
  • 2
  • 6
  • 20
  • You don't need a timer, you can use a [Timeline](https://docs.oracle.com/javase/8/javafx/api/javafx/animation/Timeline.html). Tomas's blog (ignore the ReactFX stuff in it) [Timers in JavaFX and ReactFX](http://tomasmikula.github.io/blog/2014/06/04/timers-in-javafx-and-reactfx.html). – jewelsea Feb 19 '16 at 19:42
  • You shouldn't import awt classes into a JavaFX application. – jewelsea Feb 19 '16 at 19:42
  • You should provide an [mcve](http://stackoverflow.com/help/mcve) (complete code that compiles with a copy and paste). – jewelsea Feb 19 '16 at 19:42
  • You should not do "adding a check to the loop" as this may freeze your app or unnecessarily consume CPU cycles. – jewelsea Feb 19 '16 at 19:44
  • Follow [standard naming conventions](https://google.github.io/styleguide/javaguide.html#s5-naming) for your code. – jewelsea Feb 19 '16 at 19:45

1 Answers1

14

Timer is used to schedule tasks.. So where do you write those tasks?? Well you have to write those tasks in a TimerTask class...

Confused ? Let me break it down,

Timer timer = new Timer();

Now you have created a object of Timer class .. Now you have to do some task right? So to do that create an object of TimerTask.

TimerTask task = new TimerTask()
{
        public void run()
        {
            //The task you want to do       
        }

};

Now you have created a task where you should be defining the tasks you want to do inside the run method..

Why have I written a TimerTask class itself?? Thats because TimerTask is a abstract class with three methods.. So you need to define whichever method you want to use..

Now scheduling the task

timer.schedule(task,5000l);

Note the 'l' after 5000. It is to denote long data type because the schedule method is defined as

void schedule(TimerTask task,long milliseconds)

For further reference

https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html

https://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html

Vaibhav G
  • 627
  • 5
  • 13
  • 2
    You're the man, man! Thanks for helping me out. I'm 6 months into my study to become a programmer and it's people like you that help me grasp this stuff. Thanks! – Dennis Lukas Feb 19 '16 at 20:18
  • 3
    If you use a Timer, make sure any modifications that might effect the active scene graph are done using [`Platform.runLater()`](https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#runLater-java.lang.Runnable-), otherwise you might get unpredictable results. – jewelsea Feb 20 '16 at 01:07
  • 1
    Well I edited that part of code which had Platform.runLater.. And yes as @jewelsea states you have to call this method if your Making updates to any node.. Anything related to the JavaFX interface (nodes, Scene.. Etc......) – Vaibhav G Feb 20 '16 at 03:53
  • @Dennis Lukas happy to help ..!! :) – Vaibhav G Feb 20 '16 at 04:11
  • 1
    Great explanation + it works perfect. – Israelm Dec 01 '16 at 23:41