Generic Callback JavaFX中没有推论

时间:2017-04-04 18:34:30

标签: java generics javafx callback

我需要验证TextFieldTableCell<Item,String>,因此我无法使用通常的方法

column.setCellFactory(TextFieldTableCell.forTableColumn());

所以我的目的是做一些像

这样的事情
column.setCellFactory(param -> {
    TableCell<Item,String> cell = TextFieldTableCell.forTableColumn().call(params);
    validate(validationRules, cell);
});

然而它说

CallbackTableColumn<Object,String>,TableCell<Object,String> cannot be 
applied to TableColumn<Item,String>

我知道,我不知道的是它应该推断出类型而不是Object

我发现的唯一解决方法是定义一个看起来有点令人讨厌的新StringConverter<String>

new StringConverter<String>() {
            @Override
            public String toString(String object) {
                return object;
            }

            @Override
            public String fromString(String string) {
                return string;
            }
        }

2 个答案:

答案 0 :(得分:1)

您需要隐式指定调用forTableColumn()时使用的列类型

TableCell<Item,String> cell = TextFieldTableCell.<Item>forTableColumn().call(param);

如果您要查看forTableColumn() JavaDoc,您会发现它取决于通用类型S,它是TableView中元素的类型。如果未指定,则会使用Object类型,当您尝试将其分配给TableCell<Item,String> cell时会导致问题。

答案 1 :(得分:1)

通过链接两个方法调用(TextFieldTableCell.forTableColumn()call()),您不必指定第一个方法的实际返回类型,因此编译器没有机会推断应该从该方法调用返回的类型。

如果您希望编译器推断出这一点,您可以

Callback<TableColumn<Item, String>, TableCell<Item, String>> callback = TextFieldTableCell.forTableColumn();
TableCell<Item, String> cell = callback.call(param);

当然,这比直接指定泛型方法forTableColumn的类型要简单得多:

TableCell<Item, String> cell = TextFieldTableCell.<Item>forTableColumn().call(param);
但是,所有这些似乎都有点人为。您正在实现回调,并且由于TextFieldTableCell具有适当的构造函数,因此无需通过中间Callback。你可以这样做:

column.setCellFactory(col -> {
    TextFieldTableCell<Item, String> cell = new TextFieldTableCell<>();
    validate(validationRules, cell);
    return cell ;
});

或者,如果您需要指定转换器:

StringConverter<String> converter =  ... ;
column.setCellFactory(col -> {
    TextFieldTableCell<Item, String> cell = new TextFieldTableCell<>(converter);
    validate(validationRules, cell);
    return cell ;
});

对于默认转换器,您只需使用

即可
TextFieldTableCell<Item, String> cell = 
    new TextFieldTableCell<>(TextFormatter.IDENTITY_STRING_CONVERTER);