JavaFX LineChart as a cell in TreeTableView

2019-07-26 05:05发布

First, I'm familiar with Java and Swing but am new to FX, and working in FX8.

I'm trying to put a JavaFX LineChart as a cell in a TreeTableView. I've gathered that I need to use setCellFactory on the column that will show the graph, and I'm defining a custom version of TreeTableCell as follows

public class SparklineCell<T> extends TreeTableCell<T,Series> {

  private LineChart getEmptyLineChart() {
    final NumberAxis xAxis = new NumberAxis();
    final NumberAxis yAxis = new NumberAxis();
    final LineChart xyChart = new LineChart<>(xAxis, yAxis);
    // configure the chart and axes...
    return xyChart;
  } 

  @Override
  protected void updateItem(Series item, boolean empty) {
    super.updateItem(item, empty);

    if (!empty && item!=null) {
        LineChart chart = getEmptyLineChart();
        chart.getData().setAll(item);
        Platform.runLater( () -> {
            setGraphic(chart);
            setText(null);
        });
    } else {
        Platform.runLater( () -> {
            setGraphic(null);
            setText(null);
        });
    }

  }
}

Notice that every time I run updateItem I am instantiating a new LineChart and fully configuring it before I add my data to it. I know this is bad form, but I've tried putting it as a member of the SparklineCell class and reusing it each time (as many examples online do with an imageview...see the above link for an example using ProgressBar as well), and it runs into problems where the chart shows up empty, or moves to a different cell, or two sets of data appear on a single chart, or exceptions are thrown for adding duplicate series to the chart, etc.

This is obviously happening because the SparklineCell instances are being reused all over the table, but what can I do about it? To be more specific, the following code doesn't work, how can I fix it without making a whole new chart every time the cell redraws?

public class SparklineCell<T> extends TreeTableCell<T,Series> {

  final NumberAxis xAxis = new NumberAxis();
  final NumberAxis yAxis = new NumberAxis();
  final LineChart xyChart = new LineChart<>(xAxis, yAxis);

  public SparklineCell() {
    //configure the chart and axes...
  } 

  @Override
  protected void updateItem(Series item, boolean empty) {
    super.updateItem(item, empty);

    if (!empty && item!=null) {
        xyChart.getData().setAll(item);
        Platform.runLater( () -> {
            setGraphic(xyChart);
            setText(null);
        });
    } else {
        Platform.runLater( () -> {
            setGraphic(null);
            setText(null);
        });
    }

  }
}

0条回答
登录 后发表回答