JavaFX stop Timeline

Miki picture Miki · Jan 3, 2013 · Viewed 11.5k times · Source

I use FXML. I've created a button to stop/restart a live chart. For the animation I've used Timeline. I'would like to control it from the guiController (from an other class), but it is not working. How can I stop a Timeline from an other class?

Thank you!

FXML:

            <Button id="button" layoutX="691.0" layoutY="305.0" mnemonicParsing="false" onAction="#btn_startmes" prefHeight="34.0" prefWidth="115.0" text="%start" />

guiController:

@FXML      
private void btn_stopmes(ActionEvent event) {
  MotionCFp Stopping = new MotionCFp();
Stopping.animation.stop();
}  

MotionCFp.java:

    @Override
    public void start(final Stage stage) throws Exception {
       else{
        ResourceBundle motionCFp = ResourceBundle.getBundle("motionc.fp.Bundle", new Locale("en", "EN"));
        AnchorPane root = (AnchorPane) FXMLLoader.load(MotionCFp.class.getResource("gui.fxml"), motionCFp);
        final guiController gui = new guiController();
        Scene scene = new Scene(root);
        stage.setTitle(motionCFp.getString("title"));
        stage.setResizable(false);
        stage.setScene(scene);        
        root.getChildren().add(gui.createChart());
                animation = new Timeline();
                animation.getKeyFrames().add(new KeyFrame(Duration.millis(1000/60), new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent actionEvent) {
                // 6 minutes data per frame
                for(int count=0; count < 6; count++) {
                    gui.nextTime();
                    gui.plotTime();
                    animation.pause();
                    animation.play();
                }
            }
        }));
        animation.setCycleCount(Animation.INDEFINITE);
        stage.show();
        animation.play();
       } 

   }

Answer

jewelsea picture jewelsea · Jan 3, 2013

What you need is a reference in your controller to the original animation created in the start method of your application. This will allow you to code the button event handler in the controller to stop the animation.

The MotionCFp class can contain the code:

final FXMLLoader loader = new FXMLLoader(
  getClass().getResource("gui.fxml"), 
  ResourceBundle.getBundle("motionc.fp.Bundle", new Locale("en", "EN"))
);
final Pane root = (Pane) loader.load();
final GuiController controller = loader.<GuiController>getController();
...
animation = new Timeline();
controller.setAnimation(animation);

And the GuiController class can contain the code:

private Timeline animation;

public void setAnimation(Timeline animation) {
  this.animation = animation;
}

@FXML private void btn_stopmes(ActionEvent event) {
  if (animation != null) {
    animation.stop();
  }
}  

MotionCFp is your application class. You only need one instance of it. That instance is created by the the JavaFX launcher, you should never do new MotionCFp().

Please note that these kinds of questions are much easier to answer quickly and correctly if the code in the question is simple, complete, compilable and executable.