一个相对的Java新手问题。
我正尝试解决CheckBoxTableCell
遇到的另一个问题,并遇到了这篇文章:CheckBoxTableCell changelistener not working。
在尝试用户James_D的示例时,我尝试将setSelectedStateCallback
转换为lambda表达式。但是,它没有编译并生成“ lambda表达式中的参数类型不兼容”错误。
原始代码如下:
cbCell.setSelectedStateCallback(new Callback<Integer, ObservableValue<Boolean>>() {
@Override
public ObservableValue<Boolean> call(Integer index) {
return selected;
}
});
NetBeans 8.2将其转换为此:
cbCell.setSelectedStateCallback((Integer index) -> selected);
然后我在这篇帖子Call Back Lambda Expressions + JavaFX中遵循了fabian用户的回答,手动编写了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);
}
}
答案 0 :(得分:1)
这里的问题是,您在此声明中使用了原始类型,因此它期望Object
不是Integer
。但是您在此处显式传递了一个Integer
,从而导致错误。
final CheckBoxTableCell cbCell
一种快速而肮脏的解决方法
cbCell.setSelectedStateCallback(index -> selected);
在上述情况下,编译器会将类型推断为Object
,因为没有明确给出。但这会给您一个未经检查的警告。因此,从长远来看,请使用通用类型而不是原始类型。
像下面一样参数化CheckBoxTableCell
的声明,它将修复代码中所有未检查的警告。因此,这将节省生命。
final CheckBoxTableCell<TestModel, Boolean> cbCell = new CheckBoxTableCell<>();
然后将您的代码改回您最初使用的形式,
cbCell.setSelectedStateCallback((Integer index) -> selected);
请注意,现在没有任何编译错误。然后删除类型Integer
,让编译器进行推断。