#java #javafx #javafx-2 #observablelist
#java #javafx #javafx-2 #observablelist
Вопрос:
У меня есть a masterData
, который является an ObservableList
и filteredData
который также является an ObservableList
.
Затем я хочу использовать его для отображения отфильтрованных данных при установке фильтра, а также для возможности восстановления при необходимости. Вот 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();
}
}
Фильтр класса, который я использую для фильтрации данных:
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;
}
}
И Foo
класс, который представляет собой просто [String] name
и [int] bar
(плюс геттеры / сеттеры)
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;}
}
Когда вы запустите этот код, вы получите:
aa
bb
c
Как когда фильтр был установлен на 3 (который фильтровал данные, как ожидалось), так и после того, как фильтр был «сброшен» на ноль.
Как я могу убедиться, что фильтр всегда обрабатывается с данными в MasterData, а затем сохраняется в filteredData ?
Примечание: это для проекта JavaFX, поэтому мне действительно нужно использовать ObservableList
.
Ответ №1:
Проблема
public void setData(ObservableList<Foo> data) {
this.data = data;
}
Объяснение
В случае, если вам интересно, что Java подчиняется передаче по значению, и значение MasterData должно было быть скопировано в данные списка. Вы правы! Но в этой истории есть небольшой поворот !
В случае примитивов передаются значения, но в случае объектов ссылки на объекты передаются по значению.
Итак, вы ссылаетесь на объект MasterData, вместо того, чтобы копировать значения в новый список!
Решение
this.data = FXCollections.observableArrayList(data);
Это создаст новый объект, на который будут ссылаться данные, и все манипуляции будут выполняться с данными этого нового объекта.
Комментарии:
1. Я просто хотел сказать, что это помогло мне, большое спасибо! Класс FXCollections очень полезен в нескольких экземплярах!