JavaFX:将多个图表绑定到单个数据 属性

JavaFX: Bind multiple Charts to single data property

为了尝试将多个视图与一个单一的支持模型实例结合使用,我尝试将多个图表绑定到相同的数据 属性。但奇怪的是只有最后一个绑定图表显示数据,而第一个似乎完全是空的,尽管第一个图表上的 getData() 确实产生了预期的结果,即使在基础 属性 的内容更新之后.

我写了一个简短的例子来说明我的问题,希望有人能向我揭示我的错误并告诉我如何正确地做。

package javafx.databinding;

import java.util.ArrayList;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleListProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.chart.PieChart;
import javafx.scene.chart.PieChart.Data;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class TestDataBinding extends Application
{
    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception
    {
        Property<ObservableList<Data>> sourceData =
            new SimpleListProperty<Data>(FXCollections.observableList(new ArrayList<Data>()));

        sourceData.getValue().add(new Data("first", 1));
        sourceData.getValue().add(new Data("second", 2));

        PieChart firstChart = new PieChart();
        PieChart secondChart = new PieChart();

        firstChart.dataProperty().bind(sourceData);
        secondChart.dataProperty().bind(sourceData);

        HBox layout = new HBox();
        layout.getChildren().addAll(firstChart, secondChart);

        Scene scene = new Scene(layout, 500d, 200d);
        primaryStage.setScene(scene);
        primaryStage.show();

        System.out.println(firstChart.getData());
        System.out.println(secondChart.getData());

        Platform.runLater(new Task<Void>()
        {
            @Override
            protected Void call() throws Exception
            {
                Thread.sleep(5000);

                sourceData.getValue().get(0).setPieValue(5);
                sourceData.getValue().get(1).setPieValue(3);

                System.out.println(firstChart.getData());
                System.out.println(secondChart.getData());

                return null;
            }
        });
    }
}

作为例外,记录结果在

[Data[first,1.0], Data[second,2.0]]
[Data[first,1.0], Data[second,2.0]]
[Data[first,5.0], Data[second,3.0]]
[Data[first,5.0], Data[second,3.0]]

但图表看起来像 this

这确实被 JavaFX 记录得非常糟糕...

PieChart.Data class 是数据和视图的混合体。例如,图例存储为数据 class 中的 Text 个节点。您可能知道,Node 只能包含在单个 Parent 元素中。

以下修改后的示例工作正常:

@Override
public void start(Stage primaryStage) throws Exception {

    IntegerProperty first = new SimpleIntegerProperty(1);
    IntegerProperty second = new SimpleIntegerProperty(1);

    Data d11 = new Data("first", 0);
    d11.pieValueProperty().bind(first);
    Data d12 = new Data("first", 0);
    d12.pieValueProperty().bind(second);
    ObservableList<Data> sourceData1 = FXCollections.observableArrayList(d11,d12);

    Data d21 = new Data("first", 0);
    d21.pieValueProperty().bind(first);
    Data d22 = new Data("first", 0);
    d22.pieValueProperty().bind(second);
    ObservableList<Data> sourceData2 = FXCollections.observableArrayList(d21,d22);

    PieChart firstChart = new PieChart(sourceData1);
    PieChart secondChart = new PieChart(sourceData2);

    HBox layout = new HBox();
    layout.getChildren().addAll(firstChart, secondChart);

    Scene scene = new Scene(layout, 500d, 200d);
    primaryStage.setScene(scene);
    primaryStage.show();

    System.out.println(firstChart.getData());
    System.out.println(secondChart.getData());

    new Thread(new Task<Void>() {
        @Override
        protected Void call() throws Exception {
            Thread.sleep(5000);

            first.set(5);
            second.set(3);

            System.out.println(firstChart.getData());
            System.out.println(secondChart.getData());

            return null;
        }
    }).start();
}