我有JavaFX表单,用户可以选择图像。图像存储在ArrayList中,因为我无法将其直接分配给lambda表达式
中的Image字段List<ImageByteInfo> imageBinary = new ArrayList<>();
imageBinary.add(null);//for create button test, null is a valid parameter
chooseImage.setOnAction((ActionEvent e) -> {
File selectedFile = logoChooser.showOpenDialog(stage);
if (selectedFile != null) {
Image logo = new Image("file:" + selectedFile.getAbsolutePath());
imageBinary.clear();
imageBinary.add(ImageConverter.imageToByteArray(logo));
System.out.println("list image first entry, INSIDE: " + imageBinary.get(0));//working
previewLogo.setImage(logo);
}
});
所以当用户完成对所有字段的委托时,我调用了一个createButton,当我尝试直接在setOnAction()方法中获取imageBinary
List中的存储对象时,问题就在这里。它起作用并获得对象。
createButton.setOnAction((ActionEvent e) -> {
System.out.println("list image first entry, Outside: " + imageBinary.get(0));
});
但我想要做的是调用一个方法来保存这个lambda表达式的内容,所以我这样做:
createSchoolButton.setOnAction(createBtnFire(
nameInput.getText(), ..,
imageBinary.get(0),
.., zipInput.getText()));
这是createBtnFire()
private EventHandler<ActionEvent> createBtnFire(String name, ..
ImageByteInfo logo, boolean addressEntered, String... addressFields) {
EventHandler<ActionEvent> createBtn = (ActionEvent e) -> {
//code..
entity.setCreationDate(creationDate);//null
System.out.println(logo);//this print null, so next line throws a NullPointerException
entity.setImageByteInfoEntity(new ImageByteInfoEntity(logo.getByteImage(), logo.getWidth(), logo.getHeight()));
//code..
startUI.continueToMainContent();
};
return createBtn;
}
==&GT; entity.setImageByteInfoEntity(..);
处的NullPointerException
我确实使列表成为实例变量,仍为null。那么为什么当我不使用lambda表达式的方法时它工作,列表返回对象,当我使用该方法时,它返回null。感谢。
答案 0 :(得分:1)
这与lambda表达式的范围有关。将lambda表达式视为匿名内部类。当运行定义lambda的代码片段时,将创建此lambda对象。因为它可以保存对lambda表达式之外的变量的引用,所以它们也会被启动。
因此,当使用lambda表达式(如第一个变量)时,将使用对imageBinary
的引用,并在运行lambda表达式时访问列表的第一个元素。
在第二种情况下,您定义一个事件处理程序并将imageBinary
的第一个元素传递给它,此时该元素仍未初始化。
您可以通过以下方式更改createBtnFire
,因此其行为方式相同:
private EventHandler<ActionEvent> createBtnFire(String name, ..
List<ImageByteInfo> logos, boolean addressEntered, String... addressFields) {
EventHandler<ActionEvent> createBtn = (ActionEvent e) -> {
//code..
entity.setCreationDate(creationDate);//null
ImageByteInfo logo = logos.get(0);
System.out.println(logo);
entity.setImageByteInfoEntity(new ImageByteInfoEntity(logo.getByteImage(), logo.getWidth(), logo.getHeight()));
//code..
startUI.continueToMainContent();
};
return createBtn;
}