TableColumn 中的 Lambda 运算符:: setOnEditCommit()

Yur*_*ura 2 java lambda javafx

我在我的代码中使用 TableView。我想让单元格可编辑。我在Oracle 站点上找到了运行良好的示例

lastNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
lastNameCol.setOnEditCommit(
    new EventHandler<CellEditEvent<Person, String>>() {
       @Override
       public void handle(CellEditEvent<Person, String> t) {
            ((Person) t.getTableView().getItems().get(
                t.getTablePosition().getRow())
                ).setLastName(t.getNewValue());
        }
    }
);
Run Code Online (Sandbox Code Playgroud)

然后我决定使用 lambda 运算符而不是匿名类。

lastNameCol.setCellFactory(TextFieldTableCell.<Person>forTableColumn());
lastNameCol.setOnEditCommit(
    (CellEditEvent<Person, String> t) -> {
            ((Person) t.getTableView().getItems().get(
                    t.getTablePosition().getRow())
                    ).setLastName(t.getNewValue());
    });
Run Code Online (Sandbox Code Playgroud)

我收到编译器错误。

不兼容的类型:lambda 表达式中不兼容的参数类型

但是我也在Oracle 站点上找到了这个示例。

也许这个问题是众所周知的,但我没有找到解决方案。为什么这段代码是错误的?

Jam*_*s_D 5

看起来您已将表列声明为原始类型:

TableColumn lastNameCol = new TableColumn(...);
Run Code Online (Sandbox Code Playgroud)

你不应该这样做(你的 IDE 真的应该在这里给你一个警告)。使用正确参数化的类型:

TableColumn<Person, String> lastNameCol = new TableColumn<>(...);
Run Code Online (Sandbox Code Playgroud)

现在,由于编译器知道列的类型,因此 lambda 将起作用。此外,您可以摆脱演员阵容Person

lastNameCol.setOnEditCommit(
    (CellEditEvent<Person, String> t) -> {
        t.getTableView().getItems().get(
                t.getTablePosition().getRow())
                .setLastName(t.getNewValue());
});
Run Code Online (Sandbox Code Playgroud)

请注意,CellEditEvent有一个getRowValue(),你可以使用:

lastNameCol.setOnEditCommit((CellEditEvent<Person, String> t) ->
    t.getRowValue().setLastName(t.getNewValue()));
Run Code Online (Sandbox Code Playgroud)

或者您可以完全利用类型推断

lastNameCol.setOnEditCommit(t ->
    t.getRowValue().setLastName(t.getNewValue()));
Run Code Online (Sandbox Code Playgroud)