2016-05-08 2 views
0

Ich habe JavaFX-Formular, Benutzer kann ein Bild wählen. das Bild in einem Arraylist gespeichert ist, weil ich es direkt auf ein Bildfeld innerhalb der Lambda-Ausdruckjava: NullPointerExc Warum eine Liste das hinzugefügte Objekt enthält, wenn ein Lambda-Ausdruck direkt darauf aufgerufen wird. und nicht, wenn das Lambda eine Methode ist

nicht zuordnen können
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); 
     } 
    }); 

so, wenn der Benutzer Oberfläche alle Felder entring, ich Create aufrufen, ist das Problem hier, wenn ich versuchen Sie, das gespeicherte Objekt in imageBinary Liste, direkt in setOnAction() -Methode zu erhalten. es funktioniert und holt das Objekt.

createButton.setOnAction((ActionEvent e) -> { 
     System.out.println("list image first entry, Outside: " + imageBinary.get(0)); 
    }); 

Aber was ich tun möchte, ist eine Methode aufrufen, die den Inhalt dieser Lambda-Ausdruck hält, so dass ich dies tun:

createSchoolButton.setOnAction(createBtnFire(
      nameInput.getText(), .., 
      imageBinary.get(0), 
      .., zipInput.getText())); 

das ist 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; 
} 

==> NullPointerException um entity.setImageByteInfoEntity(..); Ich habe die Liste eine Instanzvariable, immer noch Null. Warum also, wenn ich keine Methode für den Lambda-Ausdruck verwende, funktioniert es und die Liste gibt das Objekt zurück, und wenn ich die Methode verwende, wird null zurückgegeben. Vielen Dank.

+0

Sieht aus wie Sie die Liste in Ihrer zweiten Version zu löschen vergessen haben, so dass der erste Index ist immer noch 'null' und der zweite Index ist das Bild. – Tom

+0

Wenn das Objekt (Bild) in der Liste gespeichert ist, wird die Liste zuerst gelöscht. imageBinary.clear(); imageBinary.add (ImageConverter.imageToByteArray (Logo)); und wie im No-Method-Beispiel funktioniert get (0). – usertest

Antwort

1

Dies hat mit dem Umfang der Lambda-Ausdruck zu tun. Stellen Sie sich einen Lambda-Ausdruck als anonyme innere Klasse vor. Wenn das Codefragment ausgeführt wird, das das Lambda definiert, wird dieses Lambda-Objekt erstellt. Da es Referenzen auf Variablen außerhalb des Lambda-Ausdrucks enthalten kann, werden sie ebenfalls initiiert.

Daher wird bei Verwendung des Lambda-Ausdrucks wie bei der ersten Variante der Verweis auf imageBinary verwendet und das erste Element der Liste wird aufgerufen, wenn der Lambda-Ausdruck ausgeführt wird.

Im zweiten Fall definieren Sie einen Event-Handler und übergeben das erste Element von imageBinary hinein, das zu diesem Zeitpunkt noch nicht initialisiert ist.

Sie können die createBtnFire in der folgenden Art und Weise ändern, so verhält es sich auf die gleiche Weise:

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; 
} 
+0

Vielen Dank, das funktioniert – usertest

Verwandte Themen