我有一个Water
对象,该对象的参数为Integer
,value
。如果尚未创建,则此参数可以为空,等于null。值将存储为Integer
,但是在渲染后将其转换为Decimal
,并在应用String
的情况下以TextFormatter
的形式打印给用户。用户进行更改后,应将其转换回适当的Integer
并存储在数据库中。
我的Water
对象:
private Integer value;
表格代码:
@FXML
private TableView<Water> waterTable;
@FXML
private TableColumn<Water, Integer> valueColumn;
@FXML
private void initialize(){
waterTable.setItems(FXCollections.observableArrayList(thisMonthWaterList));
//don't know how to implemeny here instead of this code cell with TextField
/*valueColumn.setCellValueFactory(cellData -> new
SimpleIntegerProperty(cellData.getValue().getAmount()).asObject());
valueColumn.setCellFactory(new Callback<TableColumn<Water,Integer>,
TableCell<Water,Integer>>() {
@Override
public TableCell<Water, Integer> call(TableColumn<Water, Integer> param) {
return new TableCell<Water, Integer>(){
@Override
protected void updateItem(Integer value, boolean empty){
super.updateItem(value, empty);
if(value==null || empty){
setText(null);
}else{
setText(value.toString());
}
}
};
}
});*/
}
这是TextFormatter
的代码:
TextField.setTextFormatter(new TextFormatter<>(change -> {
int maxLength = 10;
if (change.isAdded()) {
if(change.getControlNewText().length()<=maxLength){
if (change.getText().contains(",")) {
change.setText(change.getText().replaceAll(",", "."));
}
change = change.getControlNewText().matches("^\\d*(\\.\\d{0,1})?$") ? change : null;
}else{
if(change.getText().length()==1){
change = null;
}else{
int allowedLength = maxLength - change.getControlText().length();
change.setText(change.getText().substring(0, allowedLength));
}
}
}
return change;
}));
Listener
的代码:
TextField.focusedProperty().addListener(new FocusChangeListener(TextField, text -> {
if(text.isEmpty()){
TextField.setText(Water.getAreaFormat());
}else{
TextField.setText(Water.toString(TextField.getText()));
}
thisObject.setValue(Water.toInt(TextField.getText()));
WaterDA.update(thisObject);
}, text -> {
if(text.equals(Water.getWaterFormat())){
TextField.setText("");
}
}));
答案 0 :(得分:1)
实际上,您可以使用TextFormatter
和StringConverter
使用UnaryOperator
处理转换并防止无效输入。以下代码假定您在ObjectProperty<Integer>
类中有一个Water
,并且amountProperty()
方法将其返回。
如果不存在Water.toString(int)
或Water.toString(Integer)
方法,则需要实现从int
到字符串的转换,以便以下代码起作用。
private static final StringConverter<Integer> VALUE_CONVERTER = new StringConverter<Integer>() {
@Override
public String toString(Integer object) {
return object == null ? Water.getAreaFormat() : Water.toString(object);
}
@Override
public Integer fromString(String string) {
return Water.toInt(string);
}
};
// filter copied unmodified from your code
private static final UnaryOperator<TextFormatter.Change> VALUE_FILTER = change -> {
int maxLength = 10;
if (change.isAdded()) {
if(change.getControlNewText().length() <= maxLength){
if (change.getText().contains(",")) {
change.setText(change.getText().replaceAll(",", "."));
}
change = change.getControlNewText().matches("^\\d*(\\.\\d{0,1})?$") ? change : null;
} else {
if (change.getText().length() == 1){
change = null;
} else {
int allowedLength = maxLength - change.getControlText().length();
change.setText(change.getText().substring(0, allowedLength));
}
}
}
return change;
};
@FXML
private TableColumn<Water, Integer> valueColumn;
@FXML
private void initialize(){
waterTable.setItems(FXCollections.observableArrayList(thisMonthWaterList));
valueColumn.setCellValueFactory(cellData -> cellData.getValue().amountProperty());
valueColumn.setCellFactory(new Callback<TableColumn<Water, Integer>, TableCell<Water, Integer>>() {
@Override
public TableCell<Water, Integer> call(TableColumn<Water, Integer> param) {
return new TableCell<Water, Integer>() {
private final TextFormatter<Integer> formatter;
private final TextField textField;
{
textField = new TextField();
formatter = new TextFormatter<>(VALUE_CONVERTER, null, VALUE_FILTER);
textField.setTextFormatter(formatter);
formatter.valueProperty().addListener((o, oldValue, newValue) -> {
Water water = (Water) getTableRow().getItem();
if (!Objects.equals(water.getAmount(), newValue)) {
// update item and db, if value was modified
water.setAmount(newValue);
WaterDA.update(water);
}
});
}
@Override
protected void updateItem(Integer value, boolean empty){
super.updateItem(value, empty);
if (empty){
setGraphic(null);
} else {
setGraphic(textField);
formatter.setValue(value);
}
}
};
}
});
}
这假设您的TableCell
应该始终处于“编辑状态”。如果不是这种情况,则需要在startEdit
/ cancelEdit
和commitEdit
方法中实现状态更改。