我创建了一个如下图所示的图表,并将值添加到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);

最佳答案

我曾经遇到过同样的问题,即JFreechart API相当笨拙,并且每当添加单个数据点时都会简单地重新绘制整个图表,从而导致大量的渲染开销。

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

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;
    }
  }
}

09-16 03:26