Package com.quantcomponents.chart

Source Code of com.quantcomponents.chart.Chart$ChartRefreshLoop

/*******************************************************************************
* Copyright (c) 2013 Luigi Sgro. All rights reserved. This
* program and the accompanying materials are made available under the terms of
* the Eclipse Public License v1.0 which accompanies this distribution, and is
* available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Luigi Sgro - initial API and implementation
******************************************************************************/
package com.quantcomponents.chart;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

/**
* Base class for charts.
* Implementors must:
* <ul
* <li>write the method {@link Chart#updateMetrics(IChartMetrics)}, which
* is called at each paint iteration to update the metrics</li>
* <li>add their {@link IDrawable} objects to the list returned by
* {@link Chart#getDrawables()}</li>
* </ul>
* The chart will in turn call {@link IDrawable#draw(IChartMetrics, org.eclipse.swt.graphics.GC)}
* on each of them according to their position in the list.
*
* @param <A> type of the chart abscissa
* @param <O> type of the chart ordinate
*/
public abstract class Chart<A, O> extends Composite {
  private static final long REFRESH_THREAD_WAIT_QUANTUM = 500;
  private static final long MIN_TIME_BETWEEN_REFRESH = 20;
  private final Canvas canvas;
  private final List<IDrawable<A, O>> listOfDrawables = new CopyOnWriteArrayList<IDrawable<A, O>>();
  private volatile IChartMetrics<A, O> metrics;
  private final Thread refreshThread;
  private volatile boolean refreshScheduled;
 
  private final class ChartRefreshLoop implements Runnable {
    @Override
    public void run() {
      while (!isDisposed()) {
        try {
          synchronized (refreshThread) {
            while (!refreshScheduled) {
              refreshThread.wait(REFRESH_THREAD_WAIT_QUANTUM);
              if (isDisposed()) {
                return;
              }
            }
            refreshScheduled = false;
            getDisplay().asyncExec(new Runnable() {
              @Override
              public void run() {
                updateView();
              }});
            Thread.sleep(MIN_TIME_BETWEEN_REFRESH);
          }
        } catch (InterruptedException e) { /* who cares? */ }
      }
    }
  }
 
  public Chart(Composite parent, int style) {
    super(parent, style);
    setLayout(new FillLayout());
    canvas = new Canvas(this, SWT.DOUBLE_BUFFERED);
    canvas.addControlListener(new ControlListener() {
      @Override
      public void controlMoved(ControlEvent e) { /* do nothing */ }

      @Override
      public void controlResized(ControlEvent e) {
        updateView();
      }
    });
    canvas.addPaintListener(new PaintListener() {
      @Override
      public void paintControl(PaintEvent e) {
        Rectangle canvasBounds = canvas.getBounds();
        canvas.setBackground(Chart.this.getBackground());
        canvas.drawBackground(e.gc, 0, 0, canvasBounds.width, canvasBounds.height);
        IChartMetrics<A, O> currentChartMetrics = metrics;
        if (currentChartMetrics != null) {
          updateMetrics(currentChartMetrics);
          currentChartMetrics.setDrawingArea(canvasBounds);
          for (IDrawable<A, O> drawable : listOfDrawables) {
            drawable.draw(currentChartMetrics, e.gc);
          }
        }
      }});
    refreshThread = new Thread(new ChartRefreshLoop());
    refreshThread.start();
  }
 
  public abstract void updateMetrics(IChartMetrics<A, O> metrics);
 
  public void setMetrics(IChartMetrics<A, O> metrics) {
    this.metrics = metrics;
  }

  public List<IDrawable<A, O>> getDrawables() {
    return listOfDrawables;
  }
 
  public Control getControl() {
    return canvas;
  }
 
  public void refresh() {
    synchronized(refreshThread) {
      refreshScheduled = true;
      refreshThread.notify();
    }
  }

  private void updateView() {
    if (canvas != null && !canvas.isDisposed()) {
      canvas.redraw();
      canvas.update();
    }
  }
}
TOP

Related Classes of com.quantcomponents.chart.Chart$ChartRefreshLoop

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.