2014-06-26 7 views
10

Ich habe eine MasterData, die eine ObservableList und filteredData ist, die auch eine ObservableList ist.Kopieren ObservableList Java

Dann will ich es verwenden, um die gefilterten Daten zu zeigen, wenn die Filter gesetzt ist, sondern auch in der Lage sein, um erholen, wann immer notwendig, hier ist die MCVE:

package br; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 

public class Main{ 
    private static ObservableList<Foo> masterData = FXCollections.observableArrayList(); 
    private static ObservableList<Foo> filteredData = FXCollections.observableArrayList(); 
    static Filter filter = new Filter(); 
    public static void addDummy(){ 
     masterData.add(new Foo("a",1)); 
     masterData.add(new Foo("aa",3)); 
     masterData.add(new Foo("b",2)); 
     masterData.add(new Foo("bb",4)); 
     masterData.add(new Foo("c",3)); 
    } 
    public static void printData(ObservableList<Foo> list){ 
     for(Foo f: list) System.out.println(f.getName()); 
    } 
    public static void main(String[] args) { 
     addDummy(); 
     applyFilter(3); 
     printData(filteredData); 
     applyFilter(0); 
     printData(filteredData); 
    } 
    public static void applyFilter(int num){ 
     filter.setData(masterData); 
     filter.setFilter(num); 
     filteredData = filter.getData(); 
    } 
} 

Die Klasse-Filter, den ich die Daten zu filtern, verwenden:

package br; 

import java.util.ArrayList; 
import java.util.List; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 

public class Filter { 
    private ObservableList<Foo> data = FXCollections.observableArrayList(); 
    public void setFilter(int filter){ 
     List<Foo> copy = new ArrayList<Foo>(data); 
     for(Foo f: copy) 
      if(f.getBar()<filter) data.remove(f); 
    } 
    public ObservableList<Foo> getData() { 
     return data; 
    } 

    public void setData(ObservableList<Foo> data) { 
     this.data = data; 
    } 

} 

und die Foo-Klasse, die nur ein String Name und ein int bar (plus gett ers/Setter)

package br; 

public class Foo { 
    private String name; 
    private int bar; 
    public Foo(String name, int bar){ 
     this.setBar(bar); 
     this.setName(name); 
    } 
    public String getName() {return name;} 
    public void setName(String name) {this.name = name;} 
    public int getBar() {return bar;} 
    public void setBar(int bar) {this.bar = bar;} 
} 

Wenn Sie diesen Code ausführen, erhalten Sie:

aa
bb
c

Beide, wenn der Filter eingestellt wurde auf 3 (die die Daten wie erwartet gefiltert) und nach dem Filter war "zurückgesetzt" auf Null.

Wie kann ich sicherstellen, dass die Filter immer mit den Daten in der Stamm und dann gespeichert auf dem filteredData verarbeitet wird?

Hinweis: Dies ist für ein JavaFX-Projekt, so dass ich wirklich die ObservableList verwenden muss.

Antwort

12

Problem

public void setData(ObservableList<Foo> data) { 
    this.data = data; 
} 

Erklärung

Falls Sie sich fragen, dass Java Pass von Wert und dem Wert von Stamm sollten in die Liste kopiert wurden gehorcht Daten. Du hast Recht ! Aber es gibt nur eine kleine Wendung zur Geschichte!

Incase von Primitiven werden die Werte vergangen, aber einhüllen von Objekten, Objektreferenzen von Wert geben.

Sie verweisen also auf das Objekt masterData, anstatt die Werte in eine neue Liste zu kopieren!

Lösung

this.data = FXCollections.observableArrayList(data); 

Dies ein neues Objekt für Daten schafft beziehen und die alle Manipulation wird auf diese neuen Objektdaten durchgeführt werden.

+1

Ich wollte nur sagen, das hat mir geholfen, vielen Dank! Die FXCollections-Klasse ist in mehreren Fällen sehr nützlich! – XaolingBao