FXML: 绑定到控制器

3

你是否可以像在XAML中一样,在FXML中绑定控制器到类变量?我的做法是:

FXML

<ComboBox fx:id="searchField" 
                    HBox.hgrow="ALWAYS" editable="true" />
<GridPane hgap="5" vgap="5">
    <Label text="Nom" />
    <Label text="$selecteClient.name"
        GridPane.columnIndex="1" />

    <Label GridPane.rowIndex="1" text="tél" />
    <Label text="$electedClient.phoneNumber"
        GridPane.rowIndex="1" GridPane.columnIndex="1" />
<GridPane/>

控制器:

private final List<Client> clients = FXCollections.observableArrayList(ImportingDataService.importClients());
@FXML
private Client selectedClient;

@FXML
private ComboBox<Client> searchField;

@Override
public void initialize(URL location, ResourceBundle resources) {
    // Set appDtat client id so it refreshes when client is changed
    this.appState.clientViewClientIDProperty().addListener((obs, oldValue, newValue) -> {
        selectedClient = ImportingDataService.importClient(newValue.longValue());

    });

    // Set up combo box
    setUpComboBox();

}
private void setUpComboBox() {
    searchField.getItems().addAll(clients);
    UtilService.autoCompleteComboBoxPlus(searchField, (typedText, client) -> client.getName().contains(typedText));

    // Handle selecting clients
    searchField.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
        selectedClient = ImportingDataService.importClient(newValue.getId());
    });
}

我的Client类是一个有namephoneNumber这两个String类型字段的类。而ImportingDataService.importClient用于从数据库导入数据,它们工作得很好(我设置了断点并检查过)。问题在于,当我改变ComboBox的选项时,客户端Label没有更新,而selectedClient确实发生了变化。我做错了什么?
1个回答

6

这有多个原因:

  1. 一个简单的字段是不可观察的。
  2. 您没有在表达式绑定中包含controller
  3. $selecteClient.name$electedClient.phoneNumber这里都有拼写错误。
  4. 整个表达式需要用{}包装才能绑定,而不仅仅是设置。

您可以像这样修复它:

控制器

private final ObjectProperty<Client> selectedClient = new SimpleObjectProperty<>(initialClient);

public final Client getSelectedClient() {
    return this.selectedClient.get();
}

public final void setSelectedClient(Client value) {
    this.selectedClient.set(value);
}

public final ObjectProperty<Client> selectedClientProperty() {
    return this.selectedClient;
}

...

// selectedClient = ImportingDataService.importClient(newValue.getId());
setSelectedClient(ImportingDataService.importClient(newValue.getId()));

fxml

<ComboBox fx:id="searchField" 
                    HBox.hgrow="ALWAYS" editable="true" />
<GridPane hgap="5" vgap="5">
    <Label text="Nom" />
    <Label text="${controller.selectedClient.name}"
        GridPane.columnIndex="1" />

    <Label GridPane.rowIndex="1" text="tél" />
    <Label text="${controller.selectedClient.phoneNumber}"
        GridPane.rowIndex="1" GridPane.columnIndex="1" />
<GridPane/>

客户端

public String getName() {
    return name;
}

public String getPhoneNumber() {
    return phoneNumber;
}

(或类似内容)


这是一个很好的完整答案,但只修复拼写错误就可以了。可观察对象并不是必需的。谢谢。 - Ayoub.A
我收回之前的话,它不起作用。实际上,我添加了几个标签并将它们绑定到其他属性,但是使用组合框选择模型,以这种方式它可以工作而不需要可观察对象。否则就不行。 - Ayoub.A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接