在JavaFX中连接视图和模型的预期方法是什么?
绑定?
假设我想使用以下控件在数据库中进行定位:
我在内存中有数据(记录集)对象,它的属性是可绑定的。即它们在当前记录更改时以及记录数更改时通知。
我希望用户能够使用滑块和文本字段在记录集内部进行定位。
如何实现这一目标? JavaFX中没有数字旋转,那么如何将文本,滑块和记录集对象(三端)绑定在一起?有可能吗?
答案 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;
}
}