【问题标题】:How to update view via model in JavaFX MVC?如何通过 JavaFX MVC 中的模型更新视图?
【发布时间】:2018-01-06 20:08:36
【问题描述】:

我有带有模型、视图和控制器的 FXML 应用程序。我的视图在 .fxml 文件中,我有这样的文本

<Text fx:id="position" text="None" GridPane.columnIndex="1" GridPane.rowIndex="3">
   <font>
      <Font name="System Bold" size="18.0" />
   </font>
</Text>

我的控制器看起来像这样

public class Controller{

   @FXML
   private Text position;

   public void updatePosition(String text){
      position.setText(text);
   }
}

在我的模型中,我有字符串变量,它在我的所有项目中都在变化。模型是这样的

public class Model {

   public String position = "None";

   public  String getPosition() {
      return tactic;
   }

   public void setPosition(String position) {
      this.position = position;
   }
}

我的项目中还有另外一个类,调用 setPositon 方法并更新变量位置。当有人在模型类中更改位置变量时,有没有办法在我的视图中更改文本?

【问题讨论】:

    标签: java model-view-controller javafx fxml


    【解决方案1】:

    您需要观察模型。在 JavaFX 中最简单的方法是使用JavaFX properties 来表示数据。

    public class Model {
    
        private final StringProperty position = new SimpleStringProperty("None");
    
        public StringProperty positionProperty() {
            return position ;
        }
    
        public final String getPosition() {
            return positionProperty().get();
        }
    
        public final void setPosition(String position) {
            positionProperty().set(position);
        }
    }
    

    现在你可以简单地将文字的textProperty()绑定到模型的positionProperty(),如果模型的位置发生变化,文字会自动更新:

    public class Controller{
    
       @FXML
       private Text position;
    
       private Model model ;
    
       public void initialize() {
           position.textProperty().bind(model.positionProperty());
       }
    
       // ...
    }
    

    现在唯一棘手的部分是确保控制器具有对正确模型实例的引用。最好的方法是为采用模型的控制器提供一个构造函数:

    public class Controller {
    
       @FXML
       private Text position;
    
       private final Model model ;
    
       public Controller(Model model) {
           this.model = model ;
       }
    
       public void initialize() {
           position.textProperty().bind(model.positionProperty());
       }
    
       // ...
    }
    

    现在的问题是,通过FXMLLoader 创建控制器的默认机制依赖于零参数构造函数,因此它不起作用。因此,您需要从 FXML 文件中删除 fx:controller 属性并“手动”设置控制器:

    Model model = new Model(); // or just reference to existing model...
    
    FXMLLoader loader = new FXMLLoader(getClass().getResource("View.fxml"));
    loader.setController(new Controller(model));
    Parent root = loader.load();
    // ...
    
    model.setPosition("Left"); // will update text in view
    

    有关将模型(或其他数据)传递给控制器​​的更多方法,请参阅Passing Parameters JavaFX FXML

    另见相关问题Applying MVC With JavaFx

    【讨论】:

    • 非常感谢 :) 它运行良好。还有一件事——当我创建像这样Model model = new Model(); 这样的模型实例时,我必须在另一个类中使用这个实例,所以它必须是静态的,因为我无法创建扩展应用程序的类的实例。有办法不使用模型的静态实例吗?
    • @M.Barabas 如果您在例如start() 方法中创建它,您应该能够将它传递给任何需要它的控制器(或其他类),因为@987654335 @方法是整个应用程序的入口点。这有时会变得有点复杂,在这种情况下,我建议使用依赖注入框架(例如 Guice、Weld 或 Spring)。您可能还对afterburner.fx(本质上是一个特定于 JavaFX 的 DI 框架)感兴趣。
    猜你喜欢
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 2013-08-26
    • 2014-07-22
    • 1970-01-01
    • 2018-09-10
    相关资源
    最近更新 更多