2015-07-28 16 views
6

Hier ist der Code:Rückruf und Extraktoren für JavaFX ObservableList

package sample; 

import javafx.beans.Observable; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener; 
import javafx.collections.ObservableList; 
import javafx.util.Callback; 

import java.util.List; 

/** 
* Created by IDEA on 28/07/15. 
*/ 
public class ListUpdateTest { 
    public static void main(String[] args) { 
     Callback<IntegerProperty, Observable[]> extractor = (IntegerProperty p) -> { 
      System.out.println("The extractor is called."); 
      Observable[] res = new Observable[]{p}; 
      System.out.println("Result from extractor: " + res); 
      return res; 
     }; 
     ObservableList<IntegerProperty> list = FXCollections.observableArrayList(extractor); 
     System.out.printf("Before adding"); 
     IntegerProperty p1 = new SimpleIntegerProperty(10); 
     IntegerProperty p2 = new SimpleIntegerProperty(20); 
     list.addAll(p1, p2); 
     System.out.println("After adding"); 
     list.addListener(new ListChangeListener<IntegerProperty>() { 
      @Override 
      public void onChanged(Change<? extends IntegerProperty> c) { 
       System.out.println("List is " + c.getList()); 
       while (c.next()) { 
        if (c.wasUpdated()) { 
         System.out.println("An update is detected."); 
         int start = c.getFrom(); 
         int end = c.getTo(); 
         System.out.println(
           String.format("Updated range: %d to %d", 
             start, end) 
         ); 
         List<? extends IntegerProperty> updatedElementsList; 
         updatedElementsList = c.getList().subList(start, end); 
         System.out.println("Updated elements: " + updatedElementsList); 
        } 
       } 
      } 
     }); 
     p1.set(100); 
    } 
} 

Was ist extractor und warum brauchen wir hier?

+0

es verwendet die Liste Feuer Update Ereignis zu machen, wenn ein _property_ einem eingegrenzten Artikel geändert wird , siehe z http://StackOverflow.com/A/24839492/203657 die einen Extraktor verwendet, der auf die Namenseigenschaft einer Person hört – kleopatra

Antwort

7

Ein ObservableList löst Änderungsereignisse aus, wenn Elemente hinzugefügt und aus der Liste entfernt werden, unabhängig davon, ob sie mit einem Extraktor erstellt wurden oder nicht.

Wenn jedoch Elemente in der Liste Observable-Eigenschaften sind oder Verweise auf beobachtbare Eigenschaften enthalten, werden in der Liste Aktualisierungen ausgelöst, wenn diese Eigenschaften nur dann geändert werden, wenn sie mit einem Extraktor erstellt werden, der ein Array mit Verweisen auf diese Eigenschaften zurückgibt.

Dieser Unterschied zeigen sollte:

import javafx.beans.Observable; 
import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener; 
import javafx.collections.ListChangeListener.Change; 
import javafx.collections.ObservableList; 


public class ListExtractorDemo { 
    public static void main(String[] args) { 
     ObservableList<IntegerProperty> listWithoutExtractor = 
       FXCollections.observableArrayList(); 

     ObservableList<IntegerProperty> listWithExtractor = 
       FXCollections.observableArrayList(p -> new Observable[]{p}); 

     listWithoutExtractor.addListener(createListener("listWithoutExtractor")); 
     listWithExtractor.addListener(createListener("listWithExtractor")); 

     IntegerProperty p1 = new SimpleIntegerProperty(1); 
     IntegerProperty p2 = new SimpleIntegerProperty(2); 

     // both lists will fire change events when items are added or removed: 
     listWithoutExtractor.addAll(p1, p2); 
     listWithExtractor.addAll(p1, p2); 

     // only the list with the extractor will fire a change event when the observable value of an element changes: 
     p2.set(3); 
    } 

    private static ListChangeListener<IntegerProperty> createListener(String listId) { 
     return (Change<? extends IntegerProperty> c) -> { 
      while (c.next()) { 
       if (c.wasAdded()) { 
        System.out.println(listId + " added: "+c.getAddedSubList()); 
       } 
       if (c.wasRemoved()) { 
        System.out.println(listId + " removed: "+c.getRemoved()); 
       } 
       if (c.wasUpdated()) { 
        System.out.println(listId + " updated"); 
       } 
      } 
     }; 
    } 
} 

Ein typischer Anwendungsfall ist in @ kleopatra Antwort auf JavaFX 2.0 Choice Box Issue. How to update a choiceBox, which represents a list of objects, when an object is updated?

Verwandte Themen