Binding – wurden Daten gespeichert

Veröffentlicht von

Ich wollte bei einer App, dem Nutzer sichtbar machen, das die Daten noch nicht gespeichert wurden und aus dem Grund…

habe ich folgendes Beispiel geschrieben. Immer wenn sich eine Variable in dem Model Person ändert, wird sich die Text-Farbe vom Button Save ändern.

Variante 1

DemoBindings.java

package com.multitop;

import java.util.Arrays;
import java.util.Random;
import org.kordamp.ikonli.javafx.FontIcon;

import com.functions.icons.ikonli.interfaces.Ikonli;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.converter.NumberStringConverter;


public class DemoBindings extends Application {			// with Text-Color, comment out 
//public class DemoBindings extends Application implements Ikonli { 	// with Ikonli-Icon, comment out 

	private FontIcon saveIcon; // with Ikonli-Icon, comment out 
	
	private ObservableList<Person> listPerson = FXCollections.observableArrayList();
	
	private SimpleBooleanProperty savedProperty = new SimpleBooleanProperty(false);
	private Property<?>[] allProperties = new Property[] {};
	private ObjectBinding<Color> color;

	private Button buttonSave;
	
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
    	
//    	this.saveIcon = getFontIcon("ti-save", "277d28", 24); // with Ikonli-Icon, comment out 

        HBox root = new HBox();
        root.setSpacing(5.0);
        root.setAlignment(Pos.CENTER);
        
        VBox vBoxItems = new VBox();
        vBoxItems.setSpacing(5.0);
        vBoxItems.setAlignment(Pos.CENTER);

        this.buttonSave = new Button("Save");       
        buttonSave.setPrefWidth(100);
        buttonSave.setOnAction(e -> savedProperty.setValue(true));
//      buttonSave.setGraphic(saveIcon);  				     // with Ikonli-Icon, comment out 
        buttonSave.setFont(Font.font("Courier New", FontWeight.BOLD, 26));   // with Text-Color, comment out 
               
        Button buttonNewItem = new Button("New Item");
        buttonNewItem.prefWidthProperty().bind(buttonSave.widthProperty());
        buttonNewItem.prefHeightProperty().bind(buttonSave.heightProperty());
        buttonNewItem.setOnAction(e -> {
        	Person icon = new Person(getRandomFirstName(), getRandomLastName(), getRandomAge());
        	listPerson.add(icon);
        	vBoxItems.getChildren().add(vBoxItems.getChildren().size(), addNewItem(icon));     	
        	refreshSaveBinding(listPerson, false);    	
        });
        
        Button buttonRemoveItem = new Button("Remove Item");
        buttonRemoveItem.prefWidthProperty().bind(buttonSave.widthProperty());
        buttonRemoveItem.prefHeightProperty().bind(buttonSave.heightProperty());
        buttonRemoveItem.setOnAction(e -> {
        	vBoxItems.getChildren().remove(vBoxItems.getChildren().size() - 2);
        	refreshSaveBinding(listPerson, false);
        });
        
        VBox vBoxButton = new VBox(buttonNewItem, buttonRemoveItem, buttonSave);
        vBoxButton.setSpacing(5.0);
        vBoxButton.setAlignment(Pos.CENTER);
        
        setItems(listPerson);
        
        for (Person item : listPerson) {
			vBoxItems.getChildren().add(addNewItem(item));
		}
        
        vBoxItems.getChildren().add(vBoxButton);
        
        root.getChildren().addAll(vBoxButton, vBoxItems);
        Scene scene = new Scene(root, 800, 700, Color.WHITE);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Demo Save Binding");
        primaryStage.show();
    }

    private HBox addNewItem(Person item) {
		
    	TextField textFieldFirstName = new TextField();
    	textFieldFirstName.textProperty().bindBidirectional(item.firstNameProperty());   	
    	
    	TextField textFieldLastName = new TextField();
    	textFieldLastName.textProperty().bindBidirectional(item.lastNameProperty());  
    	
    	TextField textFieldAge = new TextField();
    	textFieldAge.textProperty().bindBidirectional(item.ageProperty(), new NumberStringConverter());  
    	
		HBox hBox = new HBox(textFieldFirstName, textFieldLastName, textFieldAge);
		hBox.setSpacing(5.0);
		hBox.setAlignment(Pos.CENTER);
		return hBox;
	}

    
    private void setItems(ObservableList<Person> list) {

    	for (int i = 0; i < 10; i++) {
        	list.add(new Person(getRandomFirstName(), getRandomLastName(), getRandomAge()));
		}

		refreshSaveBinding(list);
	}
    
    private void refreshSaveBinding(ObservableList<Person> list) {
    	refreshSaveBinding(list, true);
	}
    
    private void refreshSaveBinding(ObservableList<Person> list, boolean isSaved) {
    	allProperties = new Property[] {};
    	allProperties = append(allProperties, savedProperty);
		for (Person item : list) {
			addChildProperties(item);	
		}
		
		addSaveBinding(isSaved);	
	}
    
    private void addSaveBinding() {
    	addSaveBinding(true);
	}
    
    private void addSaveBinding(boolean b) {
    	this.color = Bindings.createObjectBinding(() -> {
			System.out.println("an item has changed");
			if (savedProperty.get()) {
				savedProperty.setValue(false);
				return Color.web("#277d28");
			} else {
				return Color.web("#ff0000");
			}
		}, allProperties);

    	buttonSave.textFillProperty().bind(color); 	// with Text-Color, comment out 
//    	saveIcon.iconColorProperty().bind(color); 	// with Ikonli-Icon, comment out 
    	savedProperty.setValue(b);
	}
    
    private void addChildProperties(Person item) {
		for (Property<?> property : item.allProperty()) {
			allProperties = append(allProperties, property);
		}
	}
    
    static <T> T[] append(T[] arr, T element) {
        final int N = arr.length;
        arr = Arrays.copyOf(arr, N + 1);
        arr[N] = element;
        return arr;
    }
    
    // Person Generator
    final String[] lexiconFirstNames = 
    	new String[] {"Alice", "Bob", "Martin", "Tom", "John", "Robert", "David", "Linda", "Mary", "Lisa"};
    final String[] lexiconLastNames = 
        new String[] {"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Lopez"};
 
    final Random rand = new Random();
   
    public String getRandomFirstName() {
    	int randomNumber= rand.nextInt(lexiconFirstNames.length);
    	return lexiconFirstNames[randomNumber];
    }
    
    public String getRandomLastName() {
    	int randomNumber= rand.nextInt(lexiconLastNames.length);
    	return lexiconLastNames[randomNumber];
    }
    
    public int getRandomAge() {
    	int min = 1;
    	int max = 100;
        return (int) ((Math.random() * (max - min)) + min);
    }

    class Person {
    	
    	private Property<?>[] allProperties;
    	
    	private SimpleStringProperty firstNameProperty = new SimpleStringProperty(this, "firstName");
    	private SimpleStringProperty lastNameProperty = new SimpleStringProperty(this, "lastName");
    	private SimpleIntegerProperty ageProperty = new SimpleIntegerProperty(this, "age");
    	
    	public Person(String firstName, String lastName, int age) {
    		setFirstName(firstName);
    		setLastName(lastName);
    		setAge(age);
    		
    		this.allProperties = new Property[] {firstNameProperty, lastNameProperty, ageProperty};
		}

        // Properties
    	public Property<?>[] allProperty() { return allProperties;}
    	      
        public SimpleStringProperty firstNameProperty() { return firstNameProperty;}
        public SimpleStringProperty lastNameProperty() { return lastNameProperty;}
        public SimpleIntegerProperty ageProperty() { return ageProperty;}

        // Getter        
        public String getFirstName() {return firstNameProperty.get();}
        public String getLastName() {return lastNameProperty.get();}
        public int getAge() {return ageProperty.get();}

        // Setter
        public void setFirstName(String firstName) {this.firstNameProperty.set(firstName);}
        public void setLastName(String lastName) {this.lastNameProperty.set(lastName);}
        public void setAge(int age) {this.ageProperty.set(age);}
    }
  
}

Code-Sprache: JavaScript (javascript)
Variante 2

DemoBindings2.java

package com.saveBinding;

import java.util.Random;
//import org.kordamp.ikonli.javafx.FontIcon;

//import com.functions.icons.ikonli.interfaces.Ikonli;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.converter.NumberStringConverter;


public class DemoBindings2 extends Application {			// with Text-Color, comment out 
//public class DemoBindings extends Application implements Ikonli { 	// with Ikonli-Icon, comment out 

//	private FontIcon saveIcon; // with Ikonli-Icon, comment out 
	private MyObservableList<Person> listPerson = new MyObservableList<>(
			p -> new Observable[]{p.firstNameProperty(), p.lastNameProperty(), p.ageProperty()});

	private MyObservableList<Fruit> listFruits = new MyObservableList<>(
			p -> new Observable[]{p.nameProperty(), p.descriptionProperty()});
	
	private SimpleBooleanProperty savedProperty = new SimpleBooleanProperty(false);

	private ObjectBinding<Color> color;

	private VBox vBoxItemsPerson;
	private VBox vBoxItemsFruits;
	private Button buttonSave;


    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
    	
//    	this.saveIcon = getFontIcon("ti-save", "277d28", 24); // with Ikonli-Icon, comment out 

        VBox root = new VBox();
        root.setSpacing(5.0);
        root.setAlignment(Pos.CENTER);

        this.vBoxItemsPerson = new VBox();
        vBoxItemsPerson.setSpacing(5.0);
        vBoxItemsPerson.setAlignment(Pos.CENTER);

        this.vBoxItemsFruits = new VBox();
        vBoxItemsFruits.setSpacing(5.0);
        vBoxItemsFruits.setAlignment(Pos.CENTER);
        
        this.buttonSave = new Button("Save");       
        buttonSave.setPrefWidth(100);
        buttonSave.setOnAction(e -> savedProperty.setValue(true));
//      buttonSave.setGraphic(saveIcon);  				     // with Ikonli-Icon, comment out 
        buttonSave.setFont(Font.font("Courier New", FontWeight.BOLD, 26));   // with Text-Color, comment out 
               
        setItemsPerson(listPerson);
        setItemsFruits(listFruits);
        
        for (Person item : listPerson) {
			vBoxItemsPerson.getChildren().add(addNewItemPerson(item));
		}
        
        for (Fruit item : listFruits) {
        	vBoxItemsFruits.getChildren().add(addNewItemFruits(item));
		}
        
        addSaveProperties();

        Region space = new Region();
        space.setMinWidth(50.0);
        
        HBox hBoxItems = new HBox();
        hBoxItems.setSpacing(5.0);
        hBoxItems.setAlignment(Pos.CENTER);
        hBoxItems.getChildren().addAll(vBoxButtonsPerson(), vBoxItemsPerson, space, vBoxItemsFruits, vBoxButtonsFruit());
        
        root.getChildren().addAll(hBoxItems, buttonSave);
        Scene scene = new Scene(root, 1200, 700, Color.WHITE);
        primaryStage.setScene(scene);
        primaryStage.setTitle("Demo Save Binding 2");
        primaryStage.show();
    }

    private VBox vBoxButtonsPerson() {
        Button buttonNewItemPerson = new Button("New Person");
        buttonNewItemPerson.prefWidthProperty().bind(buttonSave.widthProperty());
        buttonNewItemPerson.prefHeightProperty().bind(buttonSave.heightProperty());
        buttonNewItemPerson.setOnAction(e -> {
        	Person person = new Person(getRandomFirstName(), getRandomLastName(), getRandomAge());
        	listPerson.add(person);
        	vBoxItemsPerson.getChildren().add(vBoxItemsPerson.getChildren().size(), addNewItemPerson(person));     	  	
        });
        
        Button buttonRemoveItemPerson = new Button("Remove Person");
        buttonRemoveItemPerson.prefWidthProperty().bind(buttonSave.widthProperty());
        buttonRemoveItemPerson.prefHeightProperty().bind(buttonSave.heightProperty());
        buttonRemoveItemPerson.setOnAction(e -> {       	
        	int index = listPerson.size() - 1;
        	listPerson.remove(index);
        	vBoxItemsPerson.getChildren().remove(index);
        });
        
        VBox vBoxButtonPerson = new VBox(buttonNewItemPerson, buttonRemoveItemPerson);
        vBoxButtonPerson.setSpacing(5.0);
        vBoxButtonPerson.setAlignment(Pos.CENTER);
        
		return vBoxButtonPerson;
    }
    
    private VBox vBoxButtonsFruit() {
        Button buttonNewItemFruit = new Button("New Fruit");
        buttonNewItemFruit.prefWidthProperty().bind(buttonSave.widthProperty());
        buttonNewItemFruit.prefHeightProperty().bind(buttonSave.heightProperty());
        buttonNewItemFruit.setOnAction(e -> {
        	Fruit fruit = new Fruit(getRandomName(), getRandomDescription());
        	listFruits.add(fruit);
        	vBoxItemsFruits.getChildren().add(vBoxItemsFruits.getChildren().size(), addNewItemFruits(fruit));     	  	
        });
        
        Button buttonRemoveItemFruit = new Button("Remove Fruit");
        buttonRemoveItemFruit.prefWidthProperty().bind(buttonSave.widthProperty());
        buttonRemoveItemFruit.prefHeightProperty().bind(buttonSave.heightProperty());
        buttonRemoveItemFruit.setOnAction(e -> {       	
        	int index = listFruits.size() - 1;
        	listFruits.remove(index);
        	vBoxItemsFruits.getChildren().remove(index);
        });
        
        VBox vBoxButtonFruits = new VBox(buttonNewItemFruit, buttonRemoveItemFruit);
        vBoxButtonFruits.setSpacing(5.0);
        vBoxButtonFruits.setAlignment(Pos.CENTER);

        return vBoxButtonFruits;
	}
    
    
    private void addSaveProperties() {
        listPerson.saveProperty().addListener(e -> savedProperty.set(false));
        listFruits.saveProperty().addListener(e -> savedProperty.set(false));
        
    	this.color = Bindings.createObjectBinding(() -> {
			System.out.println("an item has changed");
			if (savedProperty.get()) {
				// Saved								
				return Color.web("#277d28");
			} else {
				// not saved
				savedProperty.setValue(false);
				return Color.web("#ff0000");
			}
		}, savedProperty);
    	

    	buttonSave.textFillProperty().bind(color); 	// with Text-Color, comment out 
//    	saveIcon.iconColorProperty().bind(color); 	// with Ikonli-Icon, comment out 
    	savedProperty.setValue(true);
	}
    
    
    private HBox addNewItemPerson(Person item) {
		
    	TextField textFieldFirstName = new TextField();
    	textFieldFirstName.textProperty().bindBidirectional(item.firstNameProperty());   	
    	
    	TextField textFieldLastName = new TextField();
    	textFieldLastName.textProperty().bindBidirectional(item.lastNameProperty());  
    	
    	TextField textFieldAge = new TextField();
    	textFieldAge.textProperty().bindBidirectional(item.ageProperty(), new NumberStringConverter());  
    	
		HBox hBox = new HBox(textFieldFirstName, textFieldLastName, textFieldAge);
		hBox.setSpacing(5.0);
		hBox.setAlignment(Pos.CENTER);
		return hBox;
	}
    
    private HBox addNewItemFruits(Fruit item) {
		
    	TextField textFieldName = new TextField();
    	textFieldName.textProperty().bindBidirectional(item.nameProperty());   	
    	
    	TextField textFieldDescription = new TextField();
    	textFieldDescription.textProperty().bindBidirectional(item.descriptionProperty());  
    	
		HBox hBox = new HBox(textFieldName, textFieldDescription);
		hBox.setSpacing(5.0);
		hBox.setAlignment(Pos.CENTER);
		return hBox;
	}

    
    private void setItemsPerson(ObservableList<Person> list) {
    	for (int i = 0; i < 10; i++) {
        	list.add(new Person(getRandomFirstName(), getRandomLastName(), getRandomAge()));
		}
	}
    

    // Person Generator
    final String[] lexiconFirstNames = 
    	new String[] {"Alice", "Bob", "Martin", "Tom", "John", "Robert", "David", "Linda", "Mary", "Lisa"};
    final String[] lexiconLastNames = 
        new String[] {"Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Lopez"};
 
    final Random rand = new Random();
   
    public String getRandomFirstName() {
    	int randomNumber= rand.nextInt(lexiconFirstNames.length);
    	return lexiconFirstNames[randomNumber];
    }
    
    public String getRandomLastName() {
    	int randomNumber= rand.nextInt(lexiconLastNames.length);
    	return lexiconLastNames[randomNumber];
    }
    
    public int getRandomAge() {
    	int min = 1;
    	int max = 100;
        return (int) ((Math.random() * (max - min)) + min);
    }

    class Person {
    	private SimpleStringProperty firstNameProperty = new SimpleStringProperty(this, "firstName");
    	private SimpleStringProperty lastNameProperty = new SimpleStringProperty(this, "lastName");
    	private SimpleIntegerProperty ageProperty = new SimpleIntegerProperty(this, "age");
    	
    	public Person(String firstName, String lastName, int age) {
    		setFirstName(firstName);
    		setLastName(lastName);
    		setAge(age);
    		
		}

        // Properties     
        public SimpleStringProperty firstNameProperty() { return firstNameProperty;}
        public SimpleStringProperty lastNameProperty() { return lastNameProperty;}
        public SimpleIntegerProperty ageProperty() { return ageProperty;}

        // Getter        
        public String getFirstName() {return firstNameProperty.get();}
        public String getLastName() {return lastNameProperty.get();}
        public int getAge() {return ageProperty.get();}

        // Setter
        public void setFirstName(String firstName) {this.firstNameProperty.set(firstName);}
        public void setLastName(String lastName) {this.lastNameProperty.set(lastName);}
        public void setAge(int age) {this.ageProperty.set(age);}
    }
    
    private void setItemsFruits(ObservableList<Fruit> list) {
    	for (int i = 0; i < 10; i++) {
        	list.add(new Fruit(getRandomName(), getRandomDescription()));
		}
	}
    
    // Fruit Generator
    final String[] namesFruit = 
    	new String[] {"Apfel", "Birne", "Mango", "Litschi", "Ananas", "Kaki", "Banane", "Erdbeere", "Kiwi"};
    final String[] descriptionsFruit = 
        new String[] {"100g", "200g", "300g", "400g", "500g", "600g", "700g", "800g", "900g"};
 
    final Random randFruit = new Random();
   
    public String getRandomName() {
    	int randomNumber= randFruit.nextInt(namesFruit.length);
    	return namesFruit[randomNumber];
    }
    
    public String getRandomDescription() {
    	int randomNumber= randFruit.nextInt(descriptionsFruit.length);
    	return descriptionsFruit[randomNumber];
    }

    class Fruit {
        final StringProperty name = new SimpleStringProperty("name");
        final StringProperty description = new SimpleStringProperty("description");
     
        public Fruit(String name, String description) {
        	setName(name);
        	setDescription(description);
        }
        
        // Properties
        public StringProperty nameProperty() {return name;}
        public StringProperty descriptionProperty() {return description;}
        
        // Getter
        public String getName() {return name.get();}
        public String getDescription() {return description.get();}
     
        // Setter
        public void setName(String name) {this.name.set(name);}
        public void setDescription(String description) {this.description.set(description);}   
    }
  
}


Code-Sprache: JavaScript (javascript)

MyObservableList.java

package com.saveBinding;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.util.Callback;

public class MyObservableList<E> implements ObservableList<E> {

	private final ObservableList<E> delegate;
	
	private SimpleListProperty<E> listProperty;
	
	private final SimpleBooleanProperty changedProperty = new SimpleBooleanProperty(false);
	private final SimpleBooleanProperty permutatedProperty = new SimpleBooleanProperty(false);
	private final SimpleBooleanProperty updatedProperty = new SimpleBooleanProperty(false);
	private final SimpleBooleanProperty removedProperty = new SimpleBooleanProperty(false);
	private final SimpleBooleanProperty addedProperty = new SimpleBooleanProperty(false);
	
	
    public MyObservableList(Callback<E, Observable[]> callback) {
    	// MyObservableList<Person> fruit = new MyObservableList<>(p -> new Observable[]{p.nameProperty(), p.ageProperty()});
        this.delegate = FXCollections.observableArrayList(callback);
        this.listProperty = new SimpleListProperty<>(delegate);
        changedListener();
    }
	
    public MyObservableList(ObservableList<E> delegate) {
        this.delegate = delegate;
        this.listProperty = new SimpleListProperty<>(delegate);
        changedListener();
    }

    private void changedListener() {
    	delegate.addListener(new ListChangeListener<E>() {
            @Override
            public void onChanged(Change<? extends E> c) {       
            	changedProperty.set(changedProperty.not().get());
            	
                while (c.next()) {
                    if (c.wasPermutated()) {
                    	permutatedProperty.set(permutatedProperty.not().get());
                        for (int i = c.getFrom(); i < c.getTo(); ++i) {
                            System.out.println("Permuted: " + i + " " + delegate.get(i));
                        }
                    } else if (c.wasUpdated()) {
                    	updatedProperty.set(updatedProperty.not().get());
                        for (int i = c.getFrom(); i < c.getTo(); ++i) {
                            System.out.println("Updated: " + i + " " + delegate.get(i));
                        }
                    } else {
                    	
                    	if (c.getRemoved().size() > 0) {
                    		removedProperty.set(removedProperty.not().get());
						}                    	
                        for (E removedItem : c.getRemoved()) {                       	
                            System.out.println("Removed: " + removedItem);
                        }
                        
                    	if (c.getAddedSubList().size() > 0) {
                    		addedProperty.set(addedProperty.not().get());
						}   
                        for (E addedItem : c.getAddedSubList()) {
                            System.out.println("Added: " + addedItem);
                        }
                    }
                }
            }
        });
	}
    
    public SimpleBooleanProperty saveProperty() {
    	return changedProperty;
    }
    
    public SimpleBooleanProperty permutatedProperty() {
    	return permutatedProperty;
    }
    
    public SimpleBooleanProperty updatedProperty() {
    	return updatedProperty;
    }
    
    public SimpleBooleanProperty removedProperty() {
    	return removedProperty;
    }
    
    public SimpleBooleanProperty addedProperty() {
    	return addedProperty;
    }
    
    public SimpleListProperty<E> listProperty() {
		return listProperty;
	}
    
    public ReadOnlyBooleanProperty emptyProperty() {
		return listProperty.emptyProperty();
	}
    
    public ReadOnlyIntegerProperty sizeProperty() {
		return listProperty.sizeProperty();
	}
    
    @Override
    public void addListener(ListChangeListener<? super E> listener) {
        delegate.addListener(listener);
    }

    @Override
    public void removeListener(ListChangeListener<? super E> listener) {
        delegate.removeListener(listener);
    }

    @Override
    public boolean addAll(E... elements) {
        return delegate.addAll(elements);
    }

    @Override
    public boolean setAll(E... elements) {
        return delegate.setAll(elements);
    }

    @Override
    public boolean setAll(Collection<? extends E> col) {
        return delegate.setAll(col);
    }

    @Override
    public boolean removeAll(E... elements) {
        return delegate.removeAll(elements);
    }

    @Override
    public boolean retainAll(E... elements) {
        return delegate.retainAll(elements);
    }

    @Override
    public void remove(int from, int to) {
        delegate.remove(from, to);
    }

    @Override
    public int size() {
        return delegate.size();
    }

    @Override
    public boolean isEmpty() {
        return delegate.isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return delegate.contains(o);
    }

    @Override
    public Iterator<E> iterator() {
        return delegate.iterator();
    }

    @Override
    public Object[] toArray() {
        return delegate.toArray();
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return delegate.toArray(a);
    }

    @Override
    public boolean add(E e) {
        return delegate.add(e);
    }

    @Override
    public boolean remove(Object o) {
        return delegate.remove(o);
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return delegate.containsAll(c);
    }

    @Override
    public boolean addAll(Collection<? extends E> c) {
        return delegate.addAll(c);
    }

    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
        return delegate.addAll(index, c);
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        return delegate.removeAll(c);
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        return delegate.retainAll(c);
    }

    @Override
    public void clear() {
        delegate.clear();
    }

    @Override
    public E get(int index) {
        return delegate.get(index);
    }

    @Override
    public E set(int index, E element) {
        return delegate.set(index, element);
    }

    @Override
    public void add(int index, E element) {
        delegate.add(index, element);
    }

    @Override
    public E remove(int index) {
        return delegate.remove(index);
    }

    @Override
    public int indexOf(Object o) {
        return delegate.indexOf(o);
    }

    @Override
    public int lastIndexOf(Object o) {
        return delegate.lastIndexOf(o);
    }

    @Override
    public ListIterator<E> listIterator() {
        return delegate.listIterator();
    }

    @Override
    public ListIterator<E> listIterator(int index) {
        return delegate.listIterator(index);
    }

    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        return delegate.subList(fromIndex, toIndex);
    }

    @Override
    public void addListener(InvalidationListener listener) {
        delegate.addListener(listener);
    }

    @Override
    public void removeListener(InvalidationListener listener) {
        delegate.removeListener(listener);
    }

}
Code-Sprache: PHP (php)