当前位置: 动力学知识库 > 问答 > 编程问答 >

JavaFX: Bind multiple Charts to single data property

问题描述:

In an attempt to use multiple views with one single backing model instance I tried to bind several charts to the same data property. But strangely only the last bound chart does show the data, while the first appears to be totally empty, although getData() on the first chart does yield the expected results, even after an update of the underlying property's content.

I wrote a short example to illustrate my problem hoping that someone may reveal my mistake to me and show me how to do it properly.

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;

}

});

}

}

As excepted the logging results in

[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]]

but the charts look like this

网友答案:

This is indeed very badly documented by JavaFX...

The PieChart.Data class is a mixture of data and view. For example the legends are stored as Text Nodes inside the data class. As you may know, a Node can only be contained in a single Parent element.

The following modified example works fine:

@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();
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: