启用/禁用JFreeChart的绘制

时间:2011-04-11 21:49:49

标签: java swing user-interface rendering jfreechart

我有一个如下所示创建的图表,我正在为TimeSeries添加值(在我的程序中的不同位置)。 ChartPanel实际上包含在JTabbedPane中,我想不重绘图表,除非显示它的选项卡。有没有办法让我发出信号,当新数据进入TimeSeries时不应该进行渲染,除非该选项卡是当前显示的选项卡?我猜有一些调用信号表示数据已经更新并需要新的渲染,所以基本上我想拦截那个调用,如果没有显示标签就什么都不做,如果选项卡是正在调用则通过显示,并在用户切换到该选项卡时手动调用一次。这不是一个ChartPanel在后台的主要问题,但我有一些不同的选项卡,它开始吃CPU像讨厌不断更新4-5图表。

    sAccuracy = new TimeSeries("a");
    TimeSeriesCollection dataset = new TimeSeriesCollection(sAccuracy);
    JFreeChart c = ChartFactory.createTimeSeriesChart("Accuracy",
            "", "Percent", dataset, false, false, false);

    ChartPanel cp = new ChartPanel(c);

2 个答案:

答案 0 :(得分:2)

我遇到了同样的问题,即JFreechart API相当笨重,只要添加一个数据点就会重新绘制整个图表,从而导致渲染开销很大。

我解决这个问题的方法是实现我自己的底层模型(例如XYDataset实现),该模型知道何时显示包含它的图表,并且仅在该图表时传播事件是可见的 - 如果图表不可见,那么模型应该将事件的触发推迟到以后; e.g。

public class MyXYDataset extends AbstractXYDataset {
  private boolean shown;
  private boolean pendingEvent;

  /**
   * Called when the chart containing this dataset is being displayed
   * (e.g. hook this into a selection listener that listens to tab selection events).
   */
  public void setShown(boolean shown) {
    this.shown = shown;

    if (this.shown && this.pendingEvent) {
      this.pendingEvent = false;
      fireDatasetChanged();
    }
  }

  public void addDatapoint(double x, double y) {
    // TODO: Add to underlying collection.

    if (this.shown) {
      // Chart is currently displayed so propagate event immediately.
      fireDatasetChanged();
    } else {
      // Chart is hidden so delay firing of event but record that we need to fire one.
      this.pendingEvent = true;
    }
  }
}

答案 1 :(得分:2)

另一种可能性是设置c.setNotify(false);,这会阻止图表收听ChartChangeEvent

http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/JFreeChart.html#setNotify(boolean