如何将复杂类型设置为ChoiceBox项?

时间:2016-02-17 15:18:28

标签: drop-down-menu javafx tableview

我有TableView

<TableView fx:id="tableView">
  <columns>
    <TableColumn prefWidth="220.0" text="Reference"
      editable="true">
      <cellFactory>
        <fx:define>
          <FXCollections fx:factory="observableArrayList" fx:id="items">
            <Contract userFriendlyName=""/>
            <Contract userFriendlyName="M1"/>
            <Contract userFriendlyName="M2"/>
            <Contract userFriendlyName="M3"/>
            <Contract userFriendlyName="M4"/>
            <Contract userFriendlyName="Q1"/>
            <Contract userFriendlyName="Q2"/>
            <Contract userFriendlyName="SWS1"/>
            <Contract userFriendlyName="SWS2"/>
          </FXCollections>
        </fx:define>
        <ChoiceBoxTableCellFactory
          maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" items="$items">
        </ChoiceBoxTableCellFactory>
      </cellFactory>
      <cellValueFactory>
        <PropertyValueFactory property="referenceContract" />
      </cellValueFactory>
    </TableColumn>
  </columns>
  <items>
    <FXCollections fx:factory="observableArrayList">
      <GridRowModel>
        <referenceContract>
          <Contract name="" userFriendlyName="" />
        </referenceContract>
      </GridRowModel>
    </FXCollections>
  </items>
</TableView>

这些是用于ChoiceBox项和行的基础类型。

public final class Contract {
  private String name;
  private String userFriendlyName;

  public Contract() {
  }

  public Contract(String name) {
    this(name, null);
  }

  public Contract(String name, String userFriendlyName) {
    this.name = name;
    this.userFriendlyName = userFriendlyName;
  }

  public String getName() {
    return name;
  }

  public String getUserFriendlyName() {
    return userFriendlyName;
  }

  public void setUserFriendlyName(String userFriendlyName) {
    this.userFriendlyName = userFriendlyName;
  }

  public void setName(String name) {
    this.name = name;
  }

  @Override
  public String toString() {
    return userFriendlyName;
  }
}

public class GridRowModel {
  private ObjectProperty<Contract> referenceContract = new SimpleObjectProperty<>();

  public ObjectProperty<Contract> referenceContractProperty() {
    return referenceContract;
  }

  public Contract getReferenceContract() {
    return referenceContract.get();
  }

  public void setReferenceContract(Contract referenceContract) {
    this.referenceContract.set(referenceContract);
  }
}

我在cellFactory

上有ChoiceBox TableColumn
public class ChoiceBoxTableCellFactory<S, T> implements Callback<TableColumn<S, Contract>, TableCell<S, Contract>> {

  private ObservableList<Contract> items;
  private double maxHeight;
  private double maxWidth;

  public ChoiceBoxTableCellFactory() {
  }

  public ChoiceBoxTableCellFactory(
    @NamedArg("maxHeight") double maxHeight,
    @NamedArg("maxWidth") double maxWidth,
    @NamedArg("items") ObservableList<Contract> items) {
    this.maxHeight = maxHeight;
    this.maxWidth = maxWidth;
    this.items = items;
  }

  @Override
  public TableCell<S, Contract> call(TableColumn<S, Contract> param) {
    return new TableCell<S, Contract>() {
      ChoiceBox<Contract> choiceBox = new ChoiceBox<>(items);
      {
        choiceBox.setMaxHeight(maxHeight);
        choiceBox.setMaxWidth(maxWidth);
        choiceBox.valueProperty().addListener((obs, oldValue, newValue) -> {
          ObservableValue<Contract> value = getTableColumn().getCellObservableValue(getIndex());
          if (value instanceof WritableValue) {
            ((WritableValue<Contract>) value).setValue(newValue);
          }
        });
      }

      @Override
      protected void updateItem(Contract item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
          setText(null);
          setGraphic(null);
        } else {
          if (isEditing()) {
            setText(null);
            setGraphic(null);
          } else {
            choiceBox.setValue(item);
            setText(null);
            setGraphic(choiceBox);
          }
        }
      }
    };
  }
}

表格很好,我在ChoiceBox中看到了fxml的值。但是当我点击任何值时,例如M1updateItem方法会调用item参数,userFriendlyName设置为&#34;& #34 ;.这会选择ChoiceBox上的第一个选项。

当我再次点击相同的ChoiceBox并选择任何选项时,不会再次调用updateItem方法,并且值不会更改。

如何设置ChoiceBox以使用复杂类型Contract作为选项,如何修复ChoiceBox上的状态更改?

1 个答案:

答案 0 :(得分:0)

问题是,在fxml中我没有设置在合同的equals实现中使用的name属性。对下拉列表的任何更改都会返回初始项目。