对于Javafx来说还是新手,我想对单选按钮执行定向绑定
我的fxml中有
<fx:define>
<ToggleGroup fx:id="version_selection" />
</fx:define>
<RadioButton toggleGroup="$version_selection" ............>
<RadioButton toggleGroup="$version_selection" ............>
在我的控制器中,我想绑定所选切换组的值。有了文本框,一切都变得简单
@FXML
TextField name;
@FXML
private ToggleGroup version_selection;
name.textProperty().bindBidirectional(model.field5Property());
模型是我的具有SimpleStringValue属性的类
我如何绑定切换组,因为它没有作为文本字段的文本属性
答案 0 :(得分:2)
即使您的模型中有ObjectProperty<Toggle>
,也无法建立双向绑定,因为ToggleGroup.selectedToggle
是只读的。您需要通过在ToggleGroup.selectedToggle
属性和model属性中添加一个侦听器并更新该属性(而不是更改源)来解决此问题。
使用Map<String, Toggle>
将文本转换为要选择的切换。下面的示例使用TextField
来确定属性,而不是模型属性来演示行为:输入RadioButton
的文本进行选择,然后将其选中。
@Override
public void start(Stage primaryStage) throws IOException {
ToggleGroup group = new ToggleGroup();
VBox vbox = new VBox();
for (char c = 'a'; c <= 'f'; c++) {
RadioButton radio = new RadioButton(Character.toString(c));
radio.setToggleGroup(group);
vbox.getChildren().add(radio);
}
TextField input = new TextField();
vbox.getChildren().add(input);
// create map mapping from text to corresponding toggle
Map<String, Toggle> map = new HashMap<>();
for (Toggle t : group.getToggles()) {
map.put(((RadioButton) t).getText(), t);
}
StringProperty property = input.textProperty();
InvalidationListener listener = new InvalidationListener() {
// flag preventing circular updating
boolean updating = false;
@Override
public void invalidated(Observable observable) {
if (!updating) {
updating = true;
if (observable == group.selectedToggleProperty()) {
// change as result of user interaction with RadioButton
// update property
RadioButton selectedToggle = (RadioButton) group.getSelectedToggle();
property.set(selectedToggle == null ? "" : selectedToggle.getText());
} else {
// change as result of updating the property
// select corresponding toggle
Toggle toggleToSelect = map.get(property.get());
group.selectToggle(toggleToSelect);
}
updating = false;
}
}
};
property.addListener(listener);
group.selectedToggleProperty().addListener(listener);
Scene scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.show();
}