2016-07-04 13 views
7

Anfängliche AusgangspunktKann nicht Element ObservableList (UnsupportedOperationException) in JavaFX

Ich habe eine bestehende List von 1000 Person Objekte hinzufügen, die Ich mag würde eine Extractor hören für Eigenschaftsänderungen in allen Person Objekte einfügen (dieses ObservableList wird später an eine TableView angehängt).

So würde mein Code wie:

ObservableList<Person> observablePersons = FXCollections.observableList(personlist, 
    personextractor); 

Fehlermeldung

Aber wenn ich versuche, eine neue Person zu diesem ObservableList, observablePersons Objekte hinzufügen ich in diesen Fehler laufen:

run: 
Exception in thread "main" java.lang.UnsupportedOperationException 
    at java.util.AbstractList.add(AbstractList.java:148) 
    at com.sun.javafx.collections.ObservableListWrapper.doAdd(ObservableListWrapper.java:101) 
    at javafx.collections.ModifiableObservableListBase.add(ModifiableObservableListBase.java:151) 
    at java.util.AbstractList.add(AbstractList.java:108) 
    at test.listchangelistener.listChangeDemo.main(listChangeDemo.java:72) 
Java Result: 1 

Können Sie mir bitte sagen, warum würde ich auf diesen Fehler stoßen r Nachricht? Meine Java-Version ist jdk1.8.0_91 (32-Bit)

Person Klasse

package test.listchangelistener; 

import javafx.beans.property.IntegerProperty; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 

class Person { 

    private final IntegerProperty age = new SimpleIntegerProperty(); 
    private final StringProperty name = new SimpleStringProperty(); 

    public Person(String name, Integer age) { 
     setName(name); 
     setAge(age); 
    } 

    public int getAge() { 
     return age.get(); 
    } 

    public final void setAge(int value) { 
     age.set(value); 
    } 

    public IntegerProperty ageProperty() { 
     return age; 
    } 

    public String getName() { 
     return name.get(); 
    } 

    public final void setName(String value) { 
     name.set(value); 
    } 

    public StringProperty nameProperty() { 
     return name; 
    } 

    @Override 
    public String toString() { 
     return "Person{" + "age=" + age.get() + ", name=" + name.get() + '}'; 
    } 

} 

Testcode

package test.listchangelistener; 

import java.util.Arrays; 
import java.util.List; 
import javafx.beans.Observable; 
import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener; 
import javafx.collections.ObservableList; 
import javafx.util.Callback; 


public class listChangeDemo { 
    public static void main(String[] args) { 

     Person p1 = new Person("Ted", 26); 
     Person p2 = new Person("Anne", 19); 

     // just a simple list 
     List<Person> persons = Arrays.asList(p1, p2); 

     // extractor to observe change of person properties 
     Callback<Person, Observable[]> extractor = (Person p) -> { 
      return new Observable[]{ 
       p.ageProperty(), 
       p.nameProperty() 
      }; 
     }; 

     // make list observable and attach extractor 
     ObservableList<Person> observablePersons = FXCollections.observableList(persons, extractor); 

     // create listchangeListener for observableList 
     ListChangeListener listener = (ListChangeListener) (ListChangeListener.Change c) -> { 
      while (c.next()) { 
       if (c.wasAdded()) { 
        System.out.println("these were added: "); 

        List addedSubList = c.getAddedSubList(); 
        addedSubList.forEach((Object t) -> { 
         System.out.println("added Person: " + t); 
        }); 
       } else if (c.wasRemoved()) { 
        System.out.println("these were removed"); 

        List removedSubList = c.getRemoved(); 
        removedSubList.forEach((Object t) -> { 
         System.out.println("removed Person: " + t); 
        }); 

       } else if (c.wasUpdated()) { 
        System.out.println("these were updated"); 

        System.out.println("Updated elements are: " 
          + c.getList().subList(c.getFrom(), c.getTo())); 
       } 
      } 
     }; 

     // attach listchangeListener to observableList 
     observablePersons.addListener(listener); 

     // testing changes 
     observablePersons.add(new Person("Siegfried", 10)); 

    } 
} 
+0

Ich glaube nicht, diese Frage als Duplikat markiert werden sollte. Während das zugrunde liegende Problem dasselbe ist, sind die Situationen anders. Meiner Meinung nach macht die Hinzufügung der beobachtbaren Liste in diesem Fall eine einzigartige Frage –

Antwort

11

Das Problem kommt von der Erstellung Ihrer Unterlage List:

List<Person> persons = Arrays.asList(p1, p2); 

Wenn Sie einen Blick auf die javadoc of Arrays.asList nehmen:

Returns a fixed-size list backed by the specified array.

Auf einen genaueren Blick Sie eine UnsupportedOperationException weil List.add() bekam eine wahlweisen Betrieb:

Throws: UnsupportedOperationException - if the add operation is not supported by this list.

Sie die Erstellung aktualisieren kann die Hintergrundliste als:

List<Person> persons = new ArrayList<Person>(Arrays.asList(p1, p2)); 

Der Unterschied ist, dass die zurückgegebene ArrayList eine exakte, unabhängige Kopie des übergebenen ist, daher gilt die oben beschriebene Einschränkung in diesem Fall nicht mehr.

können Sie auch einen Blick auf diese Frage, die dieses Thema in Tiefen explaines:

Difference between Arrays.asList(array) vs new ArrayList<Integer>(Arrays.asList(ia)) in java

+0

Hallo DVarga! Vielen Dank für Ihre schnelle Antwort! Ja, ich habe die Einschränkung der Arrays.asList() völlig übersehen. Das war so dumm von mir. Jedenfalls vielen Dank! – Chiggiddi

Verwandte Themen