为什么与 CheckBoxTableCell 的 setSelectedStateCallback 等效的 lambda 在 JavaFX8 中编译失败?
Why does the lambda equivalent of a CheckBoxTableCell's setSelectedStateCallback fail to compile in JavaFX8?
亲戚Java菜鸟问题
我试图解决 CheckBoxTableCell
遇到的另一个问题,遇到了这个 post:CheckBoxTableCell changelistener not working。
在试验用户 James_D 的示例时,我尝试将 setSelectedStateCallback
转换为 lambda 表达式。但是,它没有编译并生成 "incompatible parameter types in lambda expression" 错误。
原始代码如下所示:
cbCell.setSelectedStateCallback(new Callback<Integer, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(Integer index) {
return selected;
}
});
NetBeans 8.2 将其转换为:
cbCell.setSelectedStateCallback((Integer index) -> selected);
然后我按照用户 fabian 在这个 post 中的回答手动编写了 lambda 并最终得到了同样的结果。
为什么 lambda 表达式无法编译?应该如何编写才能编译?
如果有帮助,这里是一个 MVCE,带有原始和 lambda 等效代码。
我正在使用 JavaFX8 (JDK1.8.0_181)。
package test26;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Test26 extends Application {
private Parent createContent() {
TableView<TestModel> table = new TableView<>();
ObservableList<TestModel> olTestModel = FXCollections.observableArrayList(testmodel -> new Observable[] {
testmodel.checkboxProperty()
});
olTestModel.add(new TestModel(false));
table.setItems(olTestModel);
TableColumn<TestModel, Boolean> colCheckbox = new TableColumn<>("checkbox");
colCheckbox.setCellValueFactory(cellData -> cellData.getValue().checkboxProperty());
colCheckbox.setCellFactory((TableColumn<TestModel, Boolean> cb) -> {
final CheckBoxTableCell cbCell = new CheckBoxTableCell<>();
final BooleanProperty selected = new SimpleBooleanProperty();
//Original code ...
cbCell.setSelectedStateCallback(new Callback<Integer, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(Integer index) {
return selected;
}
});
//... and lambda equivalent that doesn't compile
cbCell.setSelectedStateCallback((Integer index) -> selected);
return cbCell;
});
table.getSelectionModel().setCellSelectionEnabled(true);
table.setEditable(true);
table.getColumns().add(colCheckbox);
BorderPane content = new BorderPane(table);
return content;
}
public class TestModel {
private BooleanProperty checkbox;
public TestModel() {
this(false);
}
public TestModel(
boolean checkbox
) {
this.checkbox = new SimpleBooleanProperty(checkbox);
}
public Boolean getCheckbox() {
return checkbox.get();
}
public void setCheckbox(boolean checkbox) {
this.checkbox.set(checkbox);
}
public BooleanProperty checkboxProperty() {
return checkbox;
}
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setTitle("Test");
stage.setWidth(500);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
这里的问题是您在此声明中使用了原始类型,因此它期望 Object
而不是 Integer
。但是您在此处明确传递了导致错误的 Integer
。
final CheckBoxTableCell cbCell
一个快速而肮脏的修复方法是
cbCell.setSelectedStateCallback(index -> selected);
在上述情况下,编译器会将类型推断为 Object
,因为它没有明确给出。但这会给你一个未经检查的警告。所以在 long 运行 中使用通用类型而不是原始类型。
参数化您的 CheckBoxTableCell
声明,如下所示,它将修复代码中所有未检查的警告。所以这将是一个救命恩人。
final CheckBoxTableCell<TestModel, Boolean> cbCell = new CheckBoxTableCell<>();
然后将您的代码改回您使用的初始版本,
cbCell.setSelectedStateCallback((Integer index) -> selected);
请注意,现在没有任何编译错误。然后删除类型 Integer
让编译器推断它。
亲戚Java菜鸟问题
我试图解决 CheckBoxTableCell
遇到的另一个问题,遇到了这个 post:CheckBoxTableCell changelistener not working。
在试验用户 James_D 的示例时,我尝试将 setSelectedStateCallback
转换为 lambda 表达式。但是,它没有编译并生成 "incompatible parameter types in lambda expression" 错误。
原始代码如下所示:
cbCell.setSelectedStateCallback(new Callback<Integer, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(Integer index) {
return selected;
}
});
NetBeans 8.2 将其转换为:
cbCell.setSelectedStateCallback((Integer index) -> selected);
然后我按照用户 fabian 在这个 post
为什么 lambda 表达式无法编译?应该如何编写才能编译?
如果有帮助,这里是一个 MVCE,带有原始和 lambda 等效代码。
我正在使用 JavaFX8 (JDK1.8.0_181)。
package test26;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Test26 extends Application {
private Parent createContent() {
TableView<TestModel> table = new TableView<>();
ObservableList<TestModel> olTestModel = FXCollections.observableArrayList(testmodel -> new Observable[] {
testmodel.checkboxProperty()
});
olTestModel.add(new TestModel(false));
table.setItems(olTestModel);
TableColumn<TestModel, Boolean> colCheckbox = new TableColumn<>("checkbox");
colCheckbox.setCellValueFactory(cellData -> cellData.getValue().checkboxProperty());
colCheckbox.setCellFactory((TableColumn<TestModel, Boolean> cb) -> {
final CheckBoxTableCell cbCell = new CheckBoxTableCell<>();
final BooleanProperty selected = new SimpleBooleanProperty();
//Original code ...
cbCell.setSelectedStateCallback(new Callback<Integer, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(Integer index) {
return selected;
}
});
//... and lambda equivalent that doesn't compile
cbCell.setSelectedStateCallback((Integer index) -> selected);
return cbCell;
});
table.getSelectionModel().setCellSelectionEnabled(true);
table.setEditable(true);
table.getColumns().add(colCheckbox);
BorderPane content = new BorderPane(table);
return content;
}
public class TestModel {
private BooleanProperty checkbox;
public TestModel() {
this(false);
}
public TestModel(
boolean checkbox
) {
this.checkbox = new SimpleBooleanProperty(checkbox);
}
public Boolean getCheckbox() {
return checkbox.get();
}
public void setCheckbox(boolean checkbox) {
this.checkbox.set(checkbox);
}
public BooleanProperty checkboxProperty() {
return checkbox;
}
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setTitle("Test");
stage.setWidth(500);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
这里的问题是您在此声明中使用了原始类型,因此它期望 Object
而不是 Integer
。但是您在此处明确传递了导致错误的 Integer
。
final CheckBoxTableCell cbCell
一个快速而肮脏的修复方法是
cbCell.setSelectedStateCallback(index -> selected);
在上述情况下,编译器会将类型推断为 Object
,因为它没有明确给出。但这会给你一个未经检查的警告。所以在 long 运行 中使用通用类型而不是原始类型。
参数化您的 CheckBoxTableCell
声明,如下所示,它将修复代码中所有未检查的警告。所以这将是一个救命恩人。
final CheckBoxTableCell<TestModel, Boolean> cbCell = new CheckBoxTableCell<>();
然后将您的代码改回您使用的初始版本,
cbCell.setSelectedStateCallback((Integer index) -> selected);
请注意,现在没有任何编译错误。然后删除类型 Integer
让编译器推断它。