我有一个TableView
控件,其中包含几个包含String
和Number
s等不同类型的列。我一直在尝试为可编辑的Number单元格编写一个合适的回调函数,但是由于我遇到了从空单元格到异常的各种问题,我无法使用它。
我已阅读http://docs.oracle.com/javafx/2/ui_controls/table-view.htm,但这仅涵盖单元格中的字符串值。关键点似乎是lastNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
。这条线似乎是为文本字段而不是为数字字段定制的。
另外,我希望对输入的数字进行验证。这是否需要CellFactory
的自定义回调才能执行此操作?如果是这样,我如何开发一个接受数字类型并验证它们的回调?
这是我目前在项目中的代码片段:
@FXML private TableView<BMIRecord> fxBMITable;
@FXML private TableColumn<BMIRecord, String> fxBMITableDate;
@FXML private TableColumn<BMIRecord, String> fxBMITableTime;
@FXML private TableColumn<BMIRecord, Number> fxBMITableHeight;
@FXML private TableColumn<BMIRecord, Number> fxBMITableWeight;
@FXML private TableColumn<BMIRecord, Number> fxBMITableBMI;
// ...
private void someFunc() {
fxBMITable.setEditable(true);
/* BMI table callback configuration */
fxBMITableHeight.setCellValueFactory(new Callback<CellDataFeatures<BMIRecord, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<BMIRecord, String> p) {
return new SimpleStringProperty(p.getValue().getDateString());
}
});
/*
* ERROR:
* The method setCellFactory(Callback<TableColumn<BMIRecord,Number>,TableCell<BMIRecord,Number>>)
* in the type TableColumn<BMIRecord,Number> is not applicable for the arguments
* (Callback<TableColumn<Object,String>,TableCell<Object,String>>)
*/
fxBMITableHeight.setCellFactory(TextFieldTableCell.forTableColumn());
fxBMITableHeight.setOnEditCommit(new EventHandler<CellEditEvent<BMIRecord, Number>>() {
@Override
public void handle(CellEditEvent<BMIRecord, Number> t) {
((BMIRecord)t.getTableView().getItems().get(t.getTablePosition().getRow())).setHeight(t.getNewValue().doubleValue());
}
});
}
感谢您提前提供任何帮助。
答案 0 :(得分:14)
TextFieldTableCell是参数化类型,具有stringConverter
属性,您可以使用该属性转换为String或您想要的类型。
尝试类似:
TextFieldTableCell.<BMIRecord, Number>forTableColumn(new NumberStringConverter())
NumberStringConverter有一些额外的构造函数用于指定格式,请参阅javadocs。
这是一个更完整的例子:
public class Person {
public Person(String name0, int age0) {
name = name0;
age = age0;
}
public String name;
public int age;
}
TableView<Person> personTable = new TableView<>();
TableColumn<Person, Number> age = new TableColumn<>();
age.setCellValueFactory(new Callback<CellDataFeatures<Person, Number>, ObservableValue<Number>>() {
@Override
public ObservableValue<Number> call(CellDataFeatures<Person, Number> p) {
return new SimpleIntegerProperty(p.getValue().age);
}
});
age.setCellFactory(TextFieldTableCell.<Person, Number>forTableColumn(new NumberStringConverter()));
但是,这不能很好地工作,因为NumberStringConverter是如此,如果你碰巧在单元格中输入一个字符串而不是一个数字,它就会直接抛出一个ParseException
。 / p>
然而,实现自己的字符串转换器应该相对简单,您也可以进行一些简单的验证(例如,值应介于0和100之间)。
答案 1 :(得分:0)
使用此
age.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
答案 2 :(得分:0)
jalvafx库:
解决方案可防止用户输入无效。仅允许使用0-9,逗号和点符号。您可以设置最小值和最大值。
使用签名的方法:
DTO
模拟表:
TableViewUtils.setEditNumberCellFactory(
TableColumn<T, K> cell,
BiConsumer<T, Double> changeHandler,
String editControlHeader,
Double minAllowedValue,
Double maxAllowedValue,
Function<T, Boolean> ignoreEdit)
解决方案:
TableView<String> tableView = new TableView<>();
tableView.getItems().addAll("USA", "Canada", "Brazil");
TableColumn<String, String> country = new TableColumn<>("Country");
TableColumn<String, Integer> column = new TableColumn<>("Some value");
tableView.getColumns().add(country);
tableView.getColumns().add(column);
country.setCellValueFactory(
data -> new SimpleObjectProperty<>(data.getValue()));
column.setCellValueFactory(
data -> new SimpleObjectProperty<>(800));