我在fxml中有以下tableView
<TableView fx:id="tableView" prefHeight="525.0" prefWidth="814.0">
<columns>
<TableColumn prefWidth="75.0">
<graphic><ToggleButton fx:id="mainToggleButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" onAction="#onMainToggleButtonAction" text="Start all" /></graphic>
<cellFactory><ToggleButtonTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" activatedText="Started" deactivatedText="Stopped"/></cellFactory>
<cellValueFactory><PropertyValueFactory property="state"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Side">
<cellValueFactory><PropertyValueFactory property="side"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Source">
<cellValueFactory><PropertyValueFactory property="sourceContract"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Reference" editable="true">
<cellFactory>
<ChoiceBoxTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<items>
<FXCollections fx:factory="observableArrayList">
<String fx:value="r01" />
<String fx:value="r02" />
</FXCollections>
</items>
</ChoiceBoxTableCellFactory>
</cellFactory>
<cellValueFactory><PropertyValueFactory property="referenceContract"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Destination">
<cellValueFactory><PropertyValueFactory property="destinationContract"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Margin" editable="true">
<cellFactory><SpinnerTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" min="0" max="1" initialValue="0" amountToStepBy="0.025" decimalFormat="0.000"/></cellFactory>
<cellValueFactory><PropertyValueFactory property="margin"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Bot">
<cellValueFactory><PropertyValueFactory property="bot"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Price">
<cellValueFactory><PropertyValueFactory property="price"/></cellValueFactory>
</TableColumn>
<TableColumn prefWidth="75.0" text="Volume">
<cellValueFactory><PropertyValueFactory property="volume"/></cellValueFactory>
</TableColumn>
</columns>
<items>
<FXCollections fx:factory="observableArrayList">
<GridRowModel state="false" side="BID" sourceContract="s01" referenceContract="r01" destinationContract="d01" margin="0" bot="MinMax" price="15.125" volume="0" />
<GridRowModel state="false" side="ASK" sourceContract="s02" referenceContract="r01" destinationContract="d02" margin="0" bot="MinMax" price="15.125" volume="0" />
</FXCollections>
</items>
</TableView>
ChoiceBoxTableCellFactory
有一个构造函数,它接受来自fxml的命名参数和items元素的setter。
public class ChoiceBoxTableCellFactory<S, T> implements Callback<TableColumn<S, String>, TableCell<S, String>> {
private ObservableList<String> items;
private double maxHeight;
private double maxWidth;
public ChoiceBoxTableCellFactory() {
}
public ChoiceBoxTableCellFactory(
@NamedArg("maxHeight") double maxHeight,
@NamedArg("maxWidth") double maxWidth) {
this.maxHeight = maxHeight;
this.maxWidth = maxWidth;
}
@Override
public TableCell<S, String> call(TableColumn<S, String> param) {
return new TableCell<S, String>() {
ChoiceBox<String> choiceBox = new ChoiceBox<>(getItems());
{
choiceBox.setMaxHeight(maxHeight);
choiceBox.setMaxWidth(maxWidth);
choiceBox.valueProperty().addListener((obs, oldValue, newValue) -> {
ObservableValue<String> value = getTableColumn().getCellObservableValue(getIndex());
if (value instanceof WritableValue) {
((WritableValue<String>) value).setValue(newValue);
}
});
}
@Override
protected void updateItem(String 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);
}
}
}
};
}
public ObservableList<String> getItems() {
return items;
}
public void setItems(ObservableList<String> items) {
this.items = items;
}
}
但是这引发了这个异常
Caused by: java.lang.IllegalArgumentException: Unable to coerce [[r01, r02]] to interface javafx.collections.ObservableList.
at com.sun.javafx.fxml.BeanAdapter.coerce(BeanAdapter.java:496)
at com.sun.javafx.fxml.builder.ProxyBuilder$Setter.invoke(ProxyBuilder.java:533)
at com.sun.javafx.fxml.builder.ProxyBuilder.createObjectFromDefaultConstructor(ProxyBuilder.java:338)
... 144 more
当我删除maxHeight
和maxWidth
属性时,通过设置器正确设置了items字段。使用这些属性,items值将包含在另一个数组中。我怎样才能达到预期的效果?
答案 0 :(得分:1)
看起来它应该有效。我尝试了一个更简单的测试,以下解决方法似乎在那里工作:
如果您在代码中的其他位置不需要setItems()
方法,请将其删除并使用read only list properties方法。即完全删除setItems(...)
方法,并在FXML中删除
<ChoiceBoxTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<items>
<String fx:value="r01" />
<String fx:value="r02" />
</items>
</ChoiceBoxTableCellFactory>
反过来似乎是使用<fx:define>
块来定义项目,并使用属性对其进行初始化:
<fx:define>
<FXCollections fx:factory="observableArrayList" fx:id="items">
<String fx:value="r01"/>
<String fx:value="r02"/>
</FXCollections>
<fx:define>
<ChoiceBoxTableCellFactory maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
items="$items" />