Models should not have any reference to the controller(s), or to the view(s). You should make the properties of the model observable, so that interested clients (the controller or view) can observe them and receive notification when they change.
The best way to change the UI periodically in JavaFX is to use the Animation API, e.g. a Timeline
.
So you can do
private class FibonacciModel {
private final IntegerProperty currentValue = new SimpleIntegerProperty(1);
private int previous = 0 ;
public IntegerProperty currentValueProperty() {
return currentValue ;
}
public final int getCurrentValue() {
return currentValueProperty().get();
}
public final void setCurrentValue(int value) {
currentValueProperty().set(value);
}
public void nextValue() {
int next = previous + getCurrentValue();
previous = getCurrentValue();
setCurrentValue(next);
}
}
And then your view can do
public class FibonacciView extends VBox {
private final Label label ;
private final Button startButton ;
public FibonacciView(FibonacciModel model) {
label = new Label();
label.textProperty().bind(model.currentValueProperty().asString());
FibonacciController controller = new FibonacciController(model);
startButton = new Button("Start");
startButton.setOnAction(e -> {
startButton.setDisable(true);
controller.animateNumbers(20)
.setOnFinished(event -> startButton.setDisable(false));
});
getChildren().add(label, startButton);
}
}
and
public class FibonacciController {
private final FibonacciModel model ;
public FibonacciController(FibonacciModel model) {
this.model = model ;
}
public Animation animateNumbers(int howMany) {
Timeline timeline = new Timeline(
newKeyFrame(Duration.seconds(1), event -> model.nextValue());
);
timeline.setCycleCount(howMany);
timeline.play();
return timeline ;
}
}