在JavaFX中的过滤后的属性ObservableList。

huangapple go评论59阅读模式
英文:

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&lt;Date, Number&gt; series = new XYChart.Series&lt;&gt;();

    public boolean isGraph() {
        return graph.get();
    }

    public XYChart.Series&lt;Date, Number&gt; getSeries() {
        return series;
    }
}

which has an extractor of a boolean graphProperty

private Callback&lt;Person, Observable[]&gt; extractor = person -&gt; 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&lt;XYChart.Series&lt;Date, Number&gt;&gt; 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&lt;XYChart.Series&lt;Date, Number&gt; of the person list?

Update:

I tried getting a filted list from persons by

FilteredList&lt;Person&gt; graphedPersons = new FilteredList&lt;&gt;(persons);
graphedPersons.setPredicate(Person::isGraph);

As @kleopatra suggested I then tried wrapping graphedPersons in a TranformationList:

ObservableList&lt;XYChart.Series&lt;Date, Number&gt;&gt; graphedSeries = new TransformationList&lt;XYChart.Series&lt;Date, Number&gt;, Person&gt;() {

    @Override
    public int size() {
        return getSource().size();
    }

    @Override
    public XYChart.Series&lt;Date, Number&gt; get(int index) {
       return getSource().get(index).getSeries();
    }

    @Override
    protected void sourceChanged(ListChangeListener.Change&lt;? extends Person&gt; 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&lt;Person&gt; graphedPersons = new FilteredList&lt;&gt;(persons);
graphedPersons.setPredicate(Person::isGraph);

Transformation List

ObservableList&lt;XYChart.Series&lt;Date, Number&gt;&gt; graphedSeries = new TransformationList&lt;XYChart.Series&lt;Date, Number&gt;, Person&gt;(graphedPersons) {

    @Override
    public int size() {
        return getSource().size();
    }

    @Override
    public XYChart.Series&lt;Date, Number&gt; get(int index) {
        return getSource().get(index).getSeries();
    }

    @Override
    protected void sourceChanged(ListChangeListener.Change&lt;? extends Person&gt; 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;
    }
};

huangapple
  • 本文由 发表于 2020年10月23日 00:42:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/64486745.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定