英文:
Filtered ObservableList of properties in JavaFX
问题
我有一个类:
class Person {
private SimpleBooleanProperty graph = new SimpleBooleanProperty(false);
private XYChart.Series<Date, Number> series = new XYChart.Series<>();
public boolean isGraph() {
return graph.get();
}
public XYChart.Series<Date, Number> getSeries() {
return series;
}
}
其中有一个布尔型属性提取器 graphProperty
:
private Callback<Person, Observable[]> extractor = person -> new Observable[] {
person.graphProperty(),
};
要在 XYChart 上显示系列,我现在需要一个可观察的系列列表,其中包含已启用 graph 属性的所有系列,类似于以下方式:
ObservableList<XYChart.Series<Date, Number>> filteredSeries = persons
.filtered(Person::isGraph)
.stream()
.map(Person::getSeries)
.collect(Collectors.toCollection(FXCollections::observableArrayList));
不幸的是,FXCollections::observableArrayList
并不以 person 列表为基础。因此问题是,如何正确创建一个正确的 ObservableList<XYChart.Series<Date, Number>>
,使其基于 person 列表?
更新:
我尝试从 persons 中获取一个经过筛选的列表:
FilteredList<Person> graphedPersons = new FilteredList<>(persons);
graphedPersons.setPredicate(Person::isGraph);
如 @kleopatra 所建议,我尝试在 graphedPersons
中包装一个 TranformationList
:
ObservableList<XYChart.Series<Date, Number>> graphedSeries = new TransformationList<XYChart.Series<Date, Number>, Person>() {
@Override
public int size() {
return getSource().size();
}
@Override
public XYChart.Series<Date, Number> get(int index) {
return getSource().get(index).getSeries();
}
@Override
protected void sourceChanged(ListChangeListener.Change<? extends Person> c) {
}
@Override
public int getSourceIndex(int index) {
return index;
}
};
图表没有显示任何内容。
英文:
I do have a class:
class Person {
private SimpleBooleanProperty graph = new SimpleBooleanProperty(false);
private XYChart.Series<Date, Number> series = new XYChart.Series<>();
public boolean isGraph() {
return graph.get();
}
public XYChart.Series<Date, Number> getSeries() {
return series;
}
}
which has an extractor of a boolean graphProperty
private Callback<Person, Observable[]> extractor = person -> new Observable[] {
person.graphProperty(),
};
For showing the series on a XYChart i now need an observable list of all series which have the graph property enabled like:
ObservableList<XYChart.Series<Date, Number>> filteredSeries = persons
.filtered(Person::isGraph)
.stream()
.map(Person::getSeries)
.collect(Collectors.toCollection(FXCollections::observableArrayList));
Unfortunatly the FXCollections::observableArrayList
is not backed by the person list. So the question is how do I create a correct ObservableList<XYChart.Series<Date, Number>
of the person list?
Update:
I tried getting a filted list from persons by
FilteredList<Person> graphedPersons = new FilteredList<>(persons);
graphedPersons.setPredicate(Person::isGraph);
As @kleopatra suggested I then tried wrapping graphedPersons
in a TranformationList
:
ObservableList<XYChart.Series<Date, Number>> graphedSeries = new TransformationList<XYChart.Series<Date, Number>, Person>() {
@Override
public int size() {
return getSource().size();
}
@Override
public XYChart.Series<Date, Number> get(int index) {
return getSource().get(index).getSeries();
}
@Override
protected void sourceChanged(ListChangeListener.Change<? extends Person> c) {
}
@Override
public int getSourceIndex(int index) {
return index;
}
};
The chart does not show anything.
答案1
得分: 1
解决方案是按照 @klepatra 的建议,将经过筛选的列表包装在 TransformationList
中:
FilteredList<Person> graphedPersons = new FilteredList<>(persons);
graphedPersons.setPredicate(Person::isGraph);
变换列表(Transformation List):
ObservableList<XYChart.Series<Date, Number>> graphedSeries = new TransformationList<XYChart.Series<Date, Number>, Person>(graphedPersons) {
@Override
public int size() {
return getSource().size();
}
@Override
public XYChart.Series<Date, Number> get(int index) {
return getSource().get(index).getSeries();
}
@Override
protected void sourceChanged(ListChangeListener.Change<? extends Person> c) {
beginChange();
while (c.next()) {
if (c.wasReplaced()) {
nextReplace(c.getFrom(), c.getTo(), c.getRemoved().stream().map(Person::getSeries).collect(Collectors.toList()));
} else if (c.wasRemoved()) {
nextRemove(c.getFrom(), c.getRemoved().stream().map(Person::getSeries).collect(Collectors.toList()));
} else if (c.wasAdded()) {
nextAdd(c.getFrom(), c.getTo());
}
}
endChange();
}
@Override
public int getSourceIndex(int index) {
return index;
}
};
英文:
The solution is as @klepatra suggested wrapping a filted listin a TransformationList
FilteredList<Person> graphedPersons = new FilteredList<>(persons);
graphedPersons.setPredicate(Person::isGraph);
Transformation List
ObservableList<XYChart.Series<Date, Number>> graphedSeries = new TransformationList<XYChart.Series<Date, Number>, Person>(graphedPersons) {
@Override
public int size() {
return getSource().size();
}
@Override
public XYChart.Series<Date, Number> get(int index) {
return getSource().get(index).getSeries();
}
@Override
protected void sourceChanged(ListChangeListener.Change<? extends Person> c) {
beginChange();
while (c.next()) {
if (c.wasReplaced()) {
nextReplace(c.getFrom(), c.getTo(), c.getRemoved().stream().map(Person::getSeries).collect(Collectors.toList()));
} else if (c.wasRemoved()) {
nextRemove(c.getFrom(), c.getRemoved().stream().map(Person::getSeries).collect(Collectors.toList()));
} else if (c.wasAdded()) {
nextAdd(c.getFrom(), c.getTo());
}
}
endChange();
}
@Override
public int getSourceIndex(int index) {
return index;
}
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论