在TableView中编辑数字单元格

时间:2013-11-16 15:17:58

标签: java javafx tableview

我有一个TableView控件,其中包含几个包含StringNumber 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());
        }
    });
}

感谢您提前提供任何帮助。

3 个答案:

答案 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,逗号和点符号。您可以设置最小值和最大值。

enter image description here

使用签名的方法:

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));