2016-12-15 2 views
4

Ich schrieb eine kleine ausführbare JavaFX-Anwendung auf zwei Arten, um Größenänderungen einer ObservableList abzuhören. Der erste Listener (Zeile 52-58) funktioniert korrekt. Der zweite Listener (Zeile 60-66) hört nach einigen Ereignissen auf zu arbeiten.JavaFX Bindings.size() funktioniert nach einigen Ereignissen nicht mehr

Sie können diesen Fehler (?) Reproduzieren, wenn Sie oft auf die Schaltfläche "Hinzufügen" klicken. Die erste Ansicht klickt, beide Nachrichten wurden gedruckt und einige Klicks später funktioniert nur der erste Listener weiter.

Runnable Beispiel:

import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.beans.binding.Bindings; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ListView; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 


public class Main extends Application { 
    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) { 
     final ObservableList<String> list = FXCollections.observableArrayList(); 
     primaryStage.setTitle("Demonstrator"); 

     // Button 
     Button addButton = new Button(); 
     addButton.setText("Add Element"); 
     addButton.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       list.add("TEST"); 
      } 
     }); 

     // ListView 
     ListView<String> lv = new ListView<String>(); 
     lv.setItems(list); 

     // Add elements to root 
     VBox root = new VBox(); 
     root.getChildren().add(addButton); 
     root.getChildren().add(lv); 

     // Show scene 
     primaryStage.setScene(new Scene(root, 300, 250)); 
     primaryStage.show(); 

     // This listener works correct 
     list.addListener(new ListChangeListener<String>() { 
      @Override 
      public void onChanged(Change<? extends String> c) { 
       System.out.println("#listener1: " + list.size()); 
      } 
     }); 

     // This listener stops working after 10-30 clicks on the button 
     Bindings.size(list).addListener(new ChangeListener<Number>() { 
      @Override 
      public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
       System.out.println("#listener2: " + newValue); 
      } 
     }); 
    } 
} 

Ich versuchte es mit jdk-8u112-windows-x64 und jdk-8u112-windows-i586

Hat eine Idee jemand hat, wenn jeder Fehler dort in meinem Code, oder wenn es wirklich ein Problem mit JavaFX ist?

habe ich die Lösung:

Die vom Garbage Collector entfernt Bindung wurde. Sie müssen die Bindung als Feld speichern.

Danke!

Antwort

4

Nachdem die Zeile 61 ausgeführt wird. Die Instanz, die in Bindings.size() erstellt wurde, ist in keiner Weise stark erreichbar. Daher ist sie für die Garbage Collection geeignet. Es ist leicht über den Listener erreichbar, aber das verhindert die Garbage-Collection nicht.

So wird es schließlich Müll sammeln und aufhören zu arbeiten.

Die Lösung ist: mach es stark erreichbar, z.B. indem Sie es in einem Feld in der Klasse speichern.

Verwandte Themen