How to make a BarChart behave like a timer?











up vote
0
down vote

favorite












Im trying to build a Quizz Application with JavaFX.
The user is supposed to answer as many questions as possible in one minute. I have created a subclass of BarChart that i want to use to visualise the how much time is left. My class implements Runnable because the timer is supposed to run as its own thread (right?).



I want to set the bargraph to 60, and then decrease the bar for each second. I have tried different ways to do this but none of them are succesful.



Heres what the class look like now:



public class StopWatchBar extends BarChart implements Runnable {

public StopWatchBar() {

super(new CategoryAxis(), new NumberAxis(0, 60, 1));

super.setTitle("Time");
this.setMaxWidth(200);
this.setScaleShape(true);
this.setAnimated(false);
this.setCenterShape(true);
}

@Override
public void run() {

XYChart.Series timeDataSeries = new XYChart.Series();
timeDataSeries.getData().add(new XYChart.Data<String, Integer>("", 60));
this.getData().add(timeDataSeries);

int counterSeconds = 60;
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis() + (counterSeconds * 1000);
long startTimePlusOneSecond = startTime + 1000;

while (startTime < endTime) {
if (startTime == startTimePlusOneSecond) {
timeDataSeries.getData().clear();
timeDataSeries.getData().add(new XYChart.Data<String, Number>("", counterSeconds));
counterSeconds--;
startTimePlusOneSecond += 1000;
}
startTime = System.currentTimeMillis();
}
}


}



I have created an object of the class as an instance object in my Scene in PrimaryStage.
In the same scene i also have a button that i want to use to test to execute the counter:
Like this:



timerTestButton.setOnAction(actionEvent -> {
Thread timeBarRunner = new Thread(timeBar);
timeBarRunner.start();
});


When i push the button in the UI i get the Exception:



Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at javafx.scene.chart.BarChart.seriesAdded(BarChart.java:293)
at javafx.scene.chart.XYChart.lambda$new$550(XYChart.java:160)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at QuizGUI_classes.StopWatchBar.run(StopWatchBar.java:42)
at java.lang.Thread.run(Thread.java:748)


I have no clue if im on the right path or not, hope someone has some insight.










share|improve this question
























  • There is a dedicated thread you have to use when modifying the state of GUI components. I'm not familiar with JavaFX, but typically there would be some utility method in the API to enqueue a Runnable or a Callable or whatever to be run in the appropriate thread.
    – OpenSauce
    Nov 10 at 20:34






  • 1




    In JavaFX, the utility method that OpenSauce refers to is Platform.runLater(Runnable). Though it'd probably be easier to implement this using the animation API.
    – Slaw
    Nov 11 at 0:57















up vote
0
down vote

favorite












Im trying to build a Quizz Application with JavaFX.
The user is supposed to answer as many questions as possible in one minute. I have created a subclass of BarChart that i want to use to visualise the how much time is left. My class implements Runnable because the timer is supposed to run as its own thread (right?).



I want to set the bargraph to 60, and then decrease the bar for each second. I have tried different ways to do this but none of them are succesful.



Heres what the class look like now:



public class StopWatchBar extends BarChart implements Runnable {

public StopWatchBar() {

super(new CategoryAxis(), new NumberAxis(0, 60, 1));

super.setTitle("Time");
this.setMaxWidth(200);
this.setScaleShape(true);
this.setAnimated(false);
this.setCenterShape(true);
}

@Override
public void run() {

XYChart.Series timeDataSeries = new XYChart.Series();
timeDataSeries.getData().add(new XYChart.Data<String, Integer>("", 60));
this.getData().add(timeDataSeries);

int counterSeconds = 60;
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis() + (counterSeconds * 1000);
long startTimePlusOneSecond = startTime + 1000;

while (startTime < endTime) {
if (startTime == startTimePlusOneSecond) {
timeDataSeries.getData().clear();
timeDataSeries.getData().add(new XYChart.Data<String, Number>("", counterSeconds));
counterSeconds--;
startTimePlusOneSecond += 1000;
}
startTime = System.currentTimeMillis();
}
}


}



I have created an object of the class as an instance object in my Scene in PrimaryStage.
In the same scene i also have a button that i want to use to test to execute the counter:
Like this:



timerTestButton.setOnAction(actionEvent -> {
Thread timeBarRunner = new Thread(timeBar);
timeBarRunner.start();
});


When i push the button in the UI i get the Exception:



Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at javafx.scene.chart.BarChart.seriesAdded(BarChart.java:293)
at javafx.scene.chart.XYChart.lambda$new$550(XYChart.java:160)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at QuizGUI_classes.StopWatchBar.run(StopWatchBar.java:42)
at java.lang.Thread.run(Thread.java:748)


I have no clue if im on the right path or not, hope someone has some insight.










share|improve this question
























  • There is a dedicated thread you have to use when modifying the state of GUI components. I'm not familiar with JavaFX, but typically there would be some utility method in the API to enqueue a Runnable or a Callable or whatever to be run in the appropriate thread.
    – OpenSauce
    Nov 10 at 20:34






  • 1




    In JavaFX, the utility method that OpenSauce refers to is Platform.runLater(Runnable). Though it'd probably be easier to implement this using the animation API.
    – Slaw
    Nov 11 at 0:57













up vote
0
down vote

favorite









up vote
0
down vote

favorite











Im trying to build a Quizz Application with JavaFX.
The user is supposed to answer as many questions as possible in one minute. I have created a subclass of BarChart that i want to use to visualise the how much time is left. My class implements Runnable because the timer is supposed to run as its own thread (right?).



I want to set the bargraph to 60, and then decrease the bar for each second. I have tried different ways to do this but none of them are succesful.



Heres what the class look like now:



public class StopWatchBar extends BarChart implements Runnable {

public StopWatchBar() {

super(new CategoryAxis(), new NumberAxis(0, 60, 1));

super.setTitle("Time");
this.setMaxWidth(200);
this.setScaleShape(true);
this.setAnimated(false);
this.setCenterShape(true);
}

@Override
public void run() {

XYChart.Series timeDataSeries = new XYChart.Series();
timeDataSeries.getData().add(new XYChart.Data<String, Integer>("", 60));
this.getData().add(timeDataSeries);

int counterSeconds = 60;
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis() + (counterSeconds * 1000);
long startTimePlusOneSecond = startTime + 1000;

while (startTime < endTime) {
if (startTime == startTimePlusOneSecond) {
timeDataSeries.getData().clear();
timeDataSeries.getData().add(new XYChart.Data<String, Number>("", counterSeconds));
counterSeconds--;
startTimePlusOneSecond += 1000;
}
startTime = System.currentTimeMillis();
}
}


}



I have created an object of the class as an instance object in my Scene in PrimaryStage.
In the same scene i also have a button that i want to use to test to execute the counter:
Like this:



timerTestButton.setOnAction(actionEvent -> {
Thread timeBarRunner = new Thread(timeBar);
timeBarRunner.start();
});


When i push the button in the UI i get the Exception:



Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at javafx.scene.chart.BarChart.seriesAdded(BarChart.java:293)
at javafx.scene.chart.XYChart.lambda$new$550(XYChart.java:160)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at QuizGUI_classes.StopWatchBar.run(StopWatchBar.java:42)
at java.lang.Thread.run(Thread.java:748)


I have no clue if im on the right path or not, hope someone has some insight.










share|improve this question















Im trying to build a Quizz Application with JavaFX.
The user is supposed to answer as many questions as possible in one minute. I have created a subclass of BarChart that i want to use to visualise the how much time is left. My class implements Runnable because the timer is supposed to run as its own thread (right?).



I want to set the bargraph to 60, and then decrease the bar for each second. I have tried different ways to do this but none of them are succesful.



Heres what the class look like now:



public class StopWatchBar extends BarChart implements Runnable {

public StopWatchBar() {

super(new CategoryAxis(), new NumberAxis(0, 60, 1));

super.setTitle("Time");
this.setMaxWidth(200);
this.setScaleShape(true);
this.setAnimated(false);
this.setCenterShape(true);
}

@Override
public void run() {

XYChart.Series timeDataSeries = new XYChart.Series();
timeDataSeries.getData().add(new XYChart.Data<String, Integer>("", 60));
this.getData().add(timeDataSeries);

int counterSeconds = 60;
long startTime = System.currentTimeMillis();
long endTime = System.currentTimeMillis() + (counterSeconds * 1000);
long startTimePlusOneSecond = startTime + 1000;

while (startTime < endTime) {
if (startTime == startTimePlusOneSecond) {
timeDataSeries.getData().clear();
timeDataSeries.getData().add(new XYChart.Data<String, Number>("", counterSeconds));
counterSeconds--;
startTimePlusOneSecond += 1000;
}
startTime = System.currentTimeMillis();
}
}


}



I have created an object of the class as an instance object in my Scene in PrimaryStage.
In the same scene i also have a button that i want to use to test to execute the counter:
Like this:



timerTestButton.setOnAction(actionEvent -> {
Thread timeBarRunner = new Thread(timeBar);
timeBarRunner.start();
});


When i push the button in the UI i get the Exception:



Exception in thread "Thread-4" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-4
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:279)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.add(VetoableListDecorator.java:206)
at javafx.scene.chart.BarChart.seriesAdded(BarChart.java:293)
at javafx.scene.chart.XYChart.lambda$new$550(XYChart.java:160)
at com.sun.javafx.collections.ListListenerHelper$SingleChange.fireValueChangedEvent(ListListenerHelper.java:164)
at com.sun.javafx.collections.ListListenerHelper.fireValueChangedEvent(ListListenerHelper.java:73)
at javafx.collections.ObservableListBase.fireChange(ObservableListBase.java:233)
at javafx.collections.ListChangeBuilder.commit(ListChangeBuilder.java:482)
at javafx.collections.ListChangeBuilder.endChange(ListChangeBuilder.java:541)
at javafx.collections.ObservableListBase.endChange(ObservableListBase.java:205)
at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:155)
at java.util.AbstractList.add(AbstractList.java:108)
at QuizGUI_classes.StopWatchBar.run(StopWatchBar.java:42)
at java.lang.Thread.run(Thread.java:748)


I have no clue if im on the right path or not, hope someone has some insight.







java multithreading javafx timer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 20:26

























asked Nov 10 at 20:10









Alfonso

12




12












  • There is a dedicated thread you have to use when modifying the state of GUI components. I'm not familiar with JavaFX, but typically there would be some utility method in the API to enqueue a Runnable or a Callable or whatever to be run in the appropriate thread.
    – OpenSauce
    Nov 10 at 20:34






  • 1




    In JavaFX, the utility method that OpenSauce refers to is Platform.runLater(Runnable). Though it'd probably be easier to implement this using the animation API.
    – Slaw
    Nov 11 at 0:57


















  • There is a dedicated thread you have to use when modifying the state of GUI components. I'm not familiar with JavaFX, but typically there would be some utility method in the API to enqueue a Runnable or a Callable or whatever to be run in the appropriate thread.
    – OpenSauce
    Nov 10 at 20:34






  • 1




    In JavaFX, the utility method that OpenSauce refers to is Platform.runLater(Runnable). Though it'd probably be easier to implement this using the animation API.
    – Slaw
    Nov 11 at 0:57
















There is a dedicated thread you have to use when modifying the state of GUI components. I'm not familiar with JavaFX, but typically there would be some utility method in the API to enqueue a Runnable or a Callable or whatever to be run in the appropriate thread.
– OpenSauce
Nov 10 at 20:34




There is a dedicated thread you have to use when modifying the state of GUI components. I'm not familiar with JavaFX, but typically there would be some utility method in the API to enqueue a Runnable or a Callable or whatever to be run in the appropriate thread.
– OpenSauce
Nov 10 at 20:34




1




1




In JavaFX, the utility method that OpenSauce refers to is Platform.runLater(Runnable). Though it'd probably be easier to implement this using the animation API.
– Slaw
Nov 11 at 0:57




In JavaFX, the utility method that OpenSauce refers to is Platform.runLater(Runnable). Though it'd probably be easier to implement this using the animation API.
– Slaw
Nov 11 at 0:57












1 Answer
1






active

oldest

votes

















up vote
0
down vote













Here is an example using Timeline. The Timeline is set to run every second. Once the counter reaches zero, the Timeline stops.



import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BarChartExperiments extends Application {

Timeline timeline;
int counter = 60;

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

CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("Devices");

NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Visits");

BarChart barChart = new BarChart(xAxis, yAxis);

XYChart.Series dataSeries1 = new XYChart.Series();
dataSeries1.setName("Time");

barChart.getData().add(dataSeries1);
barChart.setAnimated(false);
dataSeries1.getData().add(new XYChart.Data("Time", counter));

timeline = new Timeline(new KeyFrame(Duration.seconds(1), event ->{
dataSeries1.getData().add(new XYChart.Data("Time", --counter));
System.out.println(counter);
if(counter == 0)
{
timeline.stop();
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);

Button button = new Button("Start");
button.setOnAction(event ->{
switch(button.getText())
{
case "Start":
timeline.play();
button.setText("Reset");
break;
case "Reset":
timeline.stop();
button.setText("Start");
counter = 60;
dataSeries1.getData().add(new XYChart.Data("Time", counter));
break;
}
});
VBox vbox = new VBox(barChart, button);

Scene scene = new Scene(vbox, 400, 200);

primaryStage.setScene(scene);
primaryStage.setHeight(600);
primaryStage.setWidth(500);

primaryStage.show();
}

public static void main(String args) {
Application.launch(args);
}
}


Altered code from here






share|improve this answer





















  • Well @Sedrick, that really helped. The answer was indeed to use the TimeLine to make this happen. You made my day!
    – Alfonso
    Nov 11 at 11:31










  • If the answer helped you, either post your solution or accept this as the correct answer.
    – Sedrick
    Nov 11 at 16:24











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242990%2fhow-to-make-a-barchart-behave-like-a-timer%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













Here is an example using Timeline. The Timeline is set to run every second. Once the counter reaches zero, the Timeline stops.



import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BarChartExperiments extends Application {

Timeline timeline;
int counter = 60;

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

CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("Devices");

NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Visits");

BarChart barChart = new BarChart(xAxis, yAxis);

XYChart.Series dataSeries1 = new XYChart.Series();
dataSeries1.setName("Time");

barChart.getData().add(dataSeries1);
barChart.setAnimated(false);
dataSeries1.getData().add(new XYChart.Data("Time", counter));

timeline = new Timeline(new KeyFrame(Duration.seconds(1), event ->{
dataSeries1.getData().add(new XYChart.Data("Time", --counter));
System.out.println(counter);
if(counter == 0)
{
timeline.stop();
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);

Button button = new Button("Start");
button.setOnAction(event ->{
switch(button.getText())
{
case "Start":
timeline.play();
button.setText("Reset");
break;
case "Reset":
timeline.stop();
button.setText("Start");
counter = 60;
dataSeries1.getData().add(new XYChart.Data("Time", counter));
break;
}
});
VBox vbox = new VBox(barChart, button);

Scene scene = new Scene(vbox, 400, 200);

primaryStage.setScene(scene);
primaryStage.setHeight(600);
primaryStage.setWidth(500);

primaryStage.show();
}

public static void main(String args) {
Application.launch(args);
}
}


Altered code from here






share|improve this answer





















  • Well @Sedrick, that really helped. The answer was indeed to use the TimeLine to make this happen. You made my day!
    – Alfonso
    Nov 11 at 11:31










  • If the answer helped you, either post your solution or accept this as the correct answer.
    – Sedrick
    Nov 11 at 16:24















up vote
0
down vote













Here is an example using Timeline. The Timeline is set to run every second. Once the counter reaches zero, the Timeline stops.



import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BarChartExperiments extends Application {

Timeline timeline;
int counter = 60;

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

CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("Devices");

NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Visits");

BarChart barChart = new BarChart(xAxis, yAxis);

XYChart.Series dataSeries1 = new XYChart.Series();
dataSeries1.setName("Time");

barChart.getData().add(dataSeries1);
barChart.setAnimated(false);
dataSeries1.getData().add(new XYChart.Data("Time", counter));

timeline = new Timeline(new KeyFrame(Duration.seconds(1), event ->{
dataSeries1.getData().add(new XYChart.Data("Time", --counter));
System.out.println(counter);
if(counter == 0)
{
timeline.stop();
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);

Button button = new Button("Start");
button.setOnAction(event ->{
switch(button.getText())
{
case "Start":
timeline.play();
button.setText("Reset");
break;
case "Reset":
timeline.stop();
button.setText("Start");
counter = 60;
dataSeries1.getData().add(new XYChart.Data("Time", counter));
break;
}
});
VBox vbox = new VBox(barChart, button);

Scene scene = new Scene(vbox, 400, 200);

primaryStage.setScene(scene);
primaryStage.setHeight(600);
primaryStage.setWidth(500);

primaryStage.show();
}

public static void main(String args) {
Application.launch(args);
}
}


Altered code from here






share|improve this answer





















  • Well @Sedrick, that really helped. The answer was indeed to use the TimeLine to make this happen. You made my day!
    – Alfonso
    Nov 11 at 11:31










  • If the answer helped you, either post your solution or accept this as the correct answer.
    – Sedrick
    Nov 11 at 16:24













up vote
0
down vote










up vote
0
down vote









Here is an example using Timeline. The Timeline is set to run every second. Once the counter reaches zero, the Timeline stops.



import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BarChartExperiments extends Application {

Timeline timeline;
int counter = 60;

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

CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("Devices");

NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Visits");

BarChart barChart = new BarChart(xAxis, yAxis);

XYChart.Series dataSeries1 = new XYChart.Series();
dataSeries1.setName("Time");

barChart.getData().add(dataSeries1);
barChart.setAnimated(false);
dataSeries1.getData().add(new XYChart.Data("Time", counter));

timeline = new Timeline(new KeyFrame(Duration.seconds(1), event ->{
dataSeries1.getData().add(new XYChart.Data("Time", --counter));
System.out.println(counter);
if(counter == 0)
{
timeline.stop();
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);

Button button = new Button("Start");
button.setOnAction(event ->{
switch(button.getText())
{
case "Start":
timeline.play();
button.setText("Reset");
break;
case "Reset":
timeline.stop();
button.setText("Start");
counter = 60;
dataSeries1.getData().add(new XYChart.Data("Time", counter));
break;
}
});
VBox vbox = new VBox(barChart, button);

Scene scene = new Scene(vbox, 400, 200);

primaryStage.setScene(scene);
primaryStage.setHeight(600);
primaryStage.setWidth(500);

primaryStage.show();
}

public static void main(String args) {
Application.launch(args);
}
}


Altered code from here






share|improve this answer












Here is an example using Timeline. The Timeline is set to run every second. Once the counter reaches zero, the Timeline stops.



import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class BarChartExperiments extends Application {

Timeline timeline;
int counter = 60;

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

CategoryAxis xAxis = new CategoryAxis();
xAxis.setLabel("Devices");

NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Visits");

BarChart barChart = new BarChart(xAxis, yAxis);

XYChart.Series dataSeries1 = new XYChart.Series();
dataSeries1.setName("Time");

barChart.getData().add(dataSeries1);
barChart.setAnimated(false);
dataSeries1.getData().add(new XYChart.Data("Time", counter));

timeline = new Timeline(new KeyFrame(Duration.seconds(1), event ->{
dataSeries1.getData().add(new XYChart.Data("Time", --counter));
System.out.println(counter);
if(counter == 0)
{
timeline.stop();
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);

Button button = new Button("Start");
button.setOnAction(event ->{
switch(button.getText())
{
case "Start":
timeline.play();
button.setText("Reset");
break;
case "Reset":
timeline.stop();
button.setText("Start");
counter = 60;
dataSeries1.getData().add(new XYChart.Data("Time", counter));
break;
}
});
VBox vbox = new VBox(barChart, button);

Scene scene = new Scene(vbox, 400, 200);

primaryStage.setScene(scene);
primaryStage.setHeight(600);
primaryStage.setWidth(500);

primaryStage.show();
}

public static void main(String args) {
Application.launch(args);
}
}


Altered code from here







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 11 at 9:58









Sedrick

5,79531838




5,79531838












  • Well @Sedrick, that really helped. The answer was indeed to use the TimeLine to make this happen. You made my day!
    – Alfonso
    Nov 11 at 11:31










  • If the answer helped you, either post your solution or accept this as the correct answer.
    – Sedrick
    Nov 11 at 16:24


















  • Well @Sedrick, that really helped. The answer was indeed to use the TimeLine to make this happen. You made my day!
    – Alfonso
    Nov 11 at 11:31










  • If the answer helped you, either post your solution or accept this as the correct answer.
    – Sedrick
    Nov 11 at 16:24
















Well @Sedrick, that really helped. The answer was indeed to use the TimeLine to make this happen. You made my day!
– Alfonso
Nov 11 at 11:31




Well @Sedrick, that really helped. The answer was indeed to use the TimeLine to make this happen. You made my day!
– Alfonso
Nov 11 at 11:31












If the answer helped you, either post your solution or accept this as the correct answer.
– Sedrick
Nov 11 at 16:24




If the answer helped you, either post your solution or accept this as the correct answer.
– Sedrick
Nov 11 at 16:24


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242990%2fhow-to-make-a-barchart-behave-like-a-timer%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Florida Star v. B. J. F.

Danny Elfman

Retrieve a Users Dashboard in Tumblr with R and TumblR. Oauth Issues