简体   繁体   English

JavaFX(带 FXML)MVC:模型使用控制器

[英]JavaFX (with FXML) MVC: Model use Controller

I am fairly new to the concept of MVC and JavaFX.我对 MVC 和 JavaFX 的概念还很陌生。 Basically I have game that have some simple animation in it.基本上我的游戏中有一些简单的动画。 Here is a analogy for better understanding my problem.这是一个类比,可以更好地理解我的问题。

Model: model.java模型:model.java

public int fib(int n){
    ctrl.setLabelFib(n)
    someWaitFunction(1000 ms); //Now I can see the changes

    if (n <= 1) return n;
    else return fibonacci(n-1) + fibonacci(n-2);
}

Controller: ctrl.java控制器:ctrl.java

Label lFib = new Label();
public void setLabelFib(int n){
   lFib.setText(n)
}

View: view.fxml查看:view.fxml

*Generate with Scene Builder*

How can I access the controller in a recursive function?如何在递归函数中访问控制器? Or I am doing it completey wrong?还是我完全错了?

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, eg a Timeline .在 JavaFX 中定期更改 UI 的最佳方法是使用 Animation API,例如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 ;
    }
}

In you controller which implements Initializable , you'll have the @override method : initialize在您实现Initializable控制器中,您将拥有@override method : initialize

In this you'll create your model :在此您将创建您的模型:

model md = new model(); //depending of you constructor

To add you controller to the model you can give in throught the constructor :要将您的控制器添加到模型中,您可以通过构造函数提供:

//in initialize of controller
model md = new model(this); 

And

//in you ctrl.java
private ctrl control;
public model(ctrl control){
    this.control = control
}

With this you'll be able to do :有了这个,你将能够做到:

public int fib(int n){
    control.setLabelFib(n)
    Thread.sleep(1000);

    if (n <= 1) return n;
    else return fibonacci(n-1) + fibonacci(n-2);
}

I write the method to wait also我也写了等待的方法

Try and tell in comment how it works尝试并在评论中说明它是如何工作的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM