我正在使用由我的模型填充的TableView。
我想在一列中使用微调控件。
我能够在所需列的单元格中创建微调器, 但我正在努力将微调器值绑定到模型属性。
这是fxml
<ScrollPane>
<content>
<TableView prefHeight="525.0" prefWidth="814.0">
<columns>
<TableColumn prefWidth="75.0">
<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">
<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 /></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="" destinationContract="d01" margin="0" bot="MinMax" price="15.125" volume="0" />
<GridRowModel state="false" side="ASK" sourceContract="s02" referenceContract="" destinationContract="d02" margin="0" bot="MinMax" price="15.125" volume="0" />
</FXCollections>
</items>
</TableView>
</content>
</ScrollPane>
这是SpinnerTableCellFactory
public class SpinnerTableCellFactory<S, T> implements Callback<TableColumn<S, Double>, TableCell<S, Double>> {
@Override
public TableCell<S, Double> call(TableColumn<S, Double> param) {
return new TableCell<S, Double>() {
Spinner<Double> spinner = new Spinner<>(0d, 1d, 0d, 0.025d);
protected void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
setText(null);
setGraphic(null);
} else {
spinner.getValueFactory().setValue(getItem());
setText(null);
setGraphic(spinner);
}
}
};
};
}
}
当加载fxml时,将使用updateItem
属性的fxml中的默认值调用margin
方法。我可以在细胞中看到并使用旋转器。但是如何将任何新的微调器值传递回GridRowModel对象中的margin属性?
答案 0 :(得分:2)
只需使用微调器valueProperty()
注册一个监听器:
public class SpinnerTableCellFactory<S, T> implements Callback<TableColumn<S, Double>, TableCell<S, Double>> {
@Override
public TableCell<S, Double> call(TableColumn<S, Double> param) {
return new TableCell<S, Double>() {
Spinner<Double> spinner = new Spinner<>(0d, 1d, 0d, 0.025d);
{
spinner.valueProperty().addListener((obs, oldValue, newValue) -> {
ObservableValue<Double> value = getTableColumn().getCellObservableValue(getIndex());
if (value instanceof WritableValue) {
((WritableValue<Double>)value).setValue(newValue);
}
});
}
protected void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
setText(null);
setGraphic(null);
} else {
spinner.getValueFactory().setValue(getItem());
setText(null);
setGraphic(spinner);
}
}
};
};
}
}
我假设您的模型类GridRowModel
遵循JavaFX properties pattern。
如果您不使用JavaFX属性,或者想要避免强制转换,您可以给单元工厂BiConsumer<GridRowModel, Double>
处理更新:
public class SpinnerTableCellFactory<S, T> implements Callback<TableColumn<S, Double>, TableCell<S, Double>> {
private BiConsumer<S, Double> updater = null ;
public void setUpdater(BiConsumer<S, Double> updater) {
this.updater = updater ;
}
@Override
public TableCell<S, Double> call(TableColumn<S, Double> param) {
return new TableCell<S, Double>() {
Spinner<Double> spinner = new Spinner<>(0d, 1d, 0d, 0.025d);
{
spinner.valueProperty().addListener((obs, oldValue, newValue) -> {
if (updater != null) {
updater.accept(getTableView().getItems().get(getIndex()), newValue);
}
});
}
protected void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
setText(null);
setGraphic(null);
} else {
spinner.getValueFactory().setValue(getItem());
setText(null);
setGraphic(spinner);
}
}
};
};
}
}
然后您可以向工厂添加fx:id
:
<cellFactory><SpinnerTableCellFactory fx:id="marginCellFactory" /></cellFactory>
并在您的控制器中执行:
@FXML
private SpinnerTableCellFactory<GridRowModel, Double> marginCellFactory ;
public void initialize() {
marginCellFactory.setUpdater(GridRowModel::setMargin);
}