在 JavaFX 中连接视图和模型的主要方式是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19895951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:09:24  来源:igfitidea点击:

What is the main way to connect a view and a model in JavaFX?

javamodel-view-controllerbindingjavafx

提问by Suzan Cioc

What is an expected method of connecting view and model in JavaFX?

在 JavaFX 中连接视图和模型的预期方法是什么?

Binding?

捆绑?

Suppose I want to make positioning in database with the following controls:

假设我想使用以下控件在数据库中进行定位:

enter image description here

在此处输入图片说明

I have data (recordset) object in memory and it's properties are bindable. I.e. they are notifying when current record changes and when the number of records changes.

我在内存中有数据(记录集)对象,它的属性是可绑定的。即它们在当前记录更改和记录数量更改时发出通知。

I want user to be able position inside recordset both with slider and text field.

我希望用户能够使用滑块和文本字段在记录集中定位。

How to accomplish that? There is no numeric spin in JavaFX, so how to bind text, slider and recordset object (three ends) together? Is it possible?

如何做到这一点?JavaFX中没有数字自旋,那么如何将文本、滑块和记录集对象(三端)绑定在一起呢?是否可以?

回答by Andrei R?nea

I cannot give an authoritative answer since I don't work for Oracle nor am I some JavaFX-pert but I usually construct the controller with an instance of the model and in the initialize method of the controller I create the bindings between the controls' properties and the model's properties.

我无法给出权威答案,因为我不为 Oracle 工作,也不是一些 JavaFX 专家,但我通常使用模型实例构建控制器,并在控制器的 initialize 方法中创建控件属性之间的绑定和模型的属性。

To your concrete problem I have a lame but working solution. Lame because I can't figure out how to use the low-level binding API and I use two properties on the model. Here's how :

对于您的具体问题,我有一个蹩脚但有效的解决方案。跛脚,因为我不知道如何使用低级绑定 API,我在模型上使用了两个属性。就是这样 :

FXML :

文件格式:

<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Slider?>

<?import javafx.scene.control.TextField?>
<GridPane fx:controller="sample.Controller"
          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">

    <Slider GridPane.columnIndex="0" fx:id="slider" min="0" max="99"/>
    <Label GridPane.columnIndex="1" text="Record" />
    <TextField fx:id="textfield" GridPane.columnIndex="2"/>
</GridPane>

Main.java :

主.java :

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import sample.Models.Model;

public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        final Model model = new Model();

        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("sample.fxml"));
        loader.setControllerFactory(new Callback<Class<?>, Object>() {
            @Override
            public Object call(Class<?> aClass) {
                return new Controller(model);
            }
        });
        GridPane root = (GridPane) loader.load();

        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    }
}

Controller.java :

控制器.java :

package sample;

import javafx.beans.binding.DoubleBinding;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import sample.Models.Model;

import java.net.URL;
import java.util.ResourceBundle;

public class Controller implements Initializable {
    private final Model model;

    public Controller(Model model) {
        this.model = model;
    }

    @FXML
    public Slider slider;
    @FXML
    public TextField textfield;

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        slider.valueProperty().bindBidirectional(model.pageProperty());
        textfield.textProperty().bindBidirectional(model.pageTextProperty());
    }
}

Model.java :

模型.java :

package sample.Models;

包 sample.Models;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;

public class Model {

    private IntegerProperty pageProperty;
    private StringProperty pageTextProperty;

    public Model() {
        pageProperty = new SimpleIntegerProperty(2);
        pageProperty.addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observableValue, Number number, Number number2) {
                int value = pageProperty.get();
                //System.out.println("Page changed to " + value);
                if (Integer.toString(value).equals(pageTextProperty.get())) return;
                pageTextProperty.set(Integer.toString(value));
            }
        });

        pageTextProperty = new SimpleStringProperty("2");
        pageTextProperty.addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observableValue, String s, String s2) {
                try {
                    int parsedValue = Integer.parseInt(observableValue.getValue());
                    if (parsedValue == pageProperty.get()) return;
                    pageProperty().set(parsedValue);
                } catch (NumberFormatException e) {
                    // too bad
                }
            }
        });
    }

    public int getPage() {
        return pageProperty.get();
    }

    public void setPage(int page) {
        pageProperty.set(page);
    }

    public IntegerProperty pageProperty() {
        return pageProperty;
    }

    public String getPageText() {
        return pageTextProperty.get();
    }

    public void setPageText(String pageText) {
        pageTextProperty.set(pageText);
    }

    public StringProperty pageTextProperty() {
        return pageTextProperty;
    }
}