Copy ObservableList java


Question

I have a MasterData which is an ObservableList and filteredData which is also an ObservableList.

Then, I want to use it to show the filtered data when the filter is set, but also to be able to recover whenever necessary, here is the 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();
    }
}

The class filter, which I use to filter the data:

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;
    }

}

And the Foo class, which is just a String Name and a int bar (plus getters /setters)

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;}
}

When you run this code, you will get:

aa
bb
c

Both when the filter was set to 3 (which filtered the data as expected) and after the filter was "reseted" to zero.

How can I make sure the filter is always processed with the data in the masterData and then stored on the filteredData ?

Note: this is for a JavaFX project, so I really need to use the ObservableList.

1
10
6/26/2014 11:28:16 PM

Accepted Answer

Problem

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

Explanation

In case you are wondering that Java obeys Pass By Value and the value of masterData should have been copied to the list data. You are correct ! But there is just a little twist to the story !

Incase of primitives, the values are passed but incase of objects, Object references are passed by value.

So, you are referencing to the Object of the masterData, instead of copying the values to a new List !

Solution

this.data = FXCollections.observableArrayList(data);

This will create a new Object for data to refer and all the manipulation's will be done on this new object's data.

12
6/27/2014 6:29:38 AM

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon