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

时间:2013-11-10 22:19:09

标签: java model-view-controller binding javafx

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

绑定?

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

enter image description here

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

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

如何实现这一目标? JavaFX中没有数字旋转,那么如何将文本,滑块和记录集对象(三端)绑定在一起?有可能吗?

1 个答案:

答案 0 :(得分:10)

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

对于你的具体问题,我有一个蹩脚但有效的解决方案。 Lame因为我无法弄清楚如何使用低级绑定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:

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:

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:

包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;
    }
}