From: Bill Kuker Date: Thu, 2 Jul 2009 17:54:48 +0000 (+0000) Subject: Made incremental render threadsafe X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=ae9aa06b552cd207063bc1be03decfaa8268cf4a;p=sw%2Fmotorsim Made incremental render threadsafe --- diff --git a/src/com/billkuker/rocketry/motorsim/visual/Chart.java b/src/com/billkuker/rocketry/motorsim/visual/Chart.java index 8f168fe..ab6dc73 100644 --- a/src/com/billkuker/rocketry/motorsim/visual/Chart.java +++ b/src/com/billkuker/rocketry/motorsim/visual/Chart.java @@ -1,4 +1,5 @@ package com.billkuker.rocketry.motorsim.visual; + import java.awt.BorderLayout; import java.awt.Color; import java.lang.reflect.InvocationTargetException; @@ -17,7 +18,9 @@ import javax.measure.unit.SI; import javax.measure.unit.Unit; import javax.swing.JFrame; import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import org.apache.log4j.Logger; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; @@ -28,25 +31,27 @@ import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jscience.physics.amount.Amount; +import com.billkuker.rocketry.motorsim.Burn; import com.billkuker.rocketry.motorsim.RocketScience; import com.billkuker.rocketry.motorsim.grain.CoredCylindricalGrain; -public class Chart extends JPanel { +public class Chart extends JPanel { private static final long serialVersionUID = 1L; - - private static ThreadFactory tf = new ThreadFactory(){ + private static Logger log = Logger.getLogger(Burn.class); + + private static ThreadFactory tf = new ThreadFactory() { public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setDaemon(true); return t; } }; - private static ExecutorService fast = Executors.newFixedThreadPool(2, tf) ; + private static ExecutorService fast = Executors.newFixedThreadPool(2, tf); private static ExecutorService slow = Executors.newFixedThreadPool(2, tf); - private boolean stop = false; + private volatile boolean stop = false; + + public class IntervalDomain implements Iterable> { - public class IntervalDomain implements Iterable>{ - Amount low, high, delta; int steps = 100; @@ -63,11 +68,10 @@ public class Chart extends JPanel { delta = high.minus(low).divide(steps); } - public Iterator> iterator() { - return new Iterator>(){ + return new Iterator>() { Amount current = low; - + public boolean hasNext() { return current.isLessThan(high.plus(delta)); } @@ -77,17 +81,16 @@ public class Chart extends JPanel { current = current.plus(delta); return ret; } - + public final void remove() { - throw new UnsupportedOperationException("Chart domain iterators are not modifiable."); + throw new UnsupportedOperationException( + "Chart domain iterators are not modifiable."); } }; } - + } - - XYSeries series; XYSeriesCollection dataset = new XYSeriesCollection(); JFreeChart chart; @@ -97,67 +100,66 @@ public class Chart extends JPanel { Object source; Method f; - @SuppressWarnings("unchecked") public Chart(Unit xUnit, Unit yUnit, Object source, String method) throws NoSuchMethodException { super(new BorderLayout()); f = source.getClass().getMethod(method, Amount.class); - series = new XYSeries(f.getName()); this.source = source; - dataset.addSeries(series); - this.xUnit = RocketScience.UnitPreference.preference.getPreferredUnit(xUnit); - this.yUnit = RocketScience.UnitPreference.preference.getPreferredUnit(yUnit); - - chart = ChartFactory.createXYLineChart( - method.substring(0,1).toUpperCase() + method.substring(1), // Title + this.xUnit = RocketScience.UnitPreference.preference + .getPreferredUnit(xUnit); + this.yUnit = RocketScience.UnitPreference.preference + .getPreferredUnit(yUnit); + + chart = ChartFactory.createXYLineChart(method.substring(0, 1) + .toUpperCase() + + method.substring(1), // Title this.xUnit.toString(), // x-axis Label this.yUnit.toString(), // y-axis Label - dataset, - PlotOrientation.VERTICAL, // Plot Orientation + dataset, PlotOrientation.VERTICAL, // Plot Orientation false, // Show Legend true, // Use tool tips false // Configure chart to generate URLs? ); add(new ChartPanel(chart)); } - + private Marker marker; - public void mark(Amount m){ - if ( marker != null ) + + public void mark(Amount m) { + if (marker != null) chart.getXYPlot().removeDomainMarker(marker); - if ( m != null ){ - marker = new ValueMarker(m.doubleValue(xUnit)); - marker.setPaint(Color.blue); - marker.setAlpha(0.8f); + if (m != null) { + marker = new ValueMarker(m.doubleValue(xUnit)); + marker.setPaint(Color.blue); + marker.setAlpha(0.8f); chart.getXYPlot().addDomainMarker(marker); } } - public void setDomain(final Iterable> d) { - series.clear(); stop = true; fill(d, 100); - fast.submit(new Thread(){ - public void run(){ - if ( !stop ) + fast.submit(new Thread() { + public void run() { + if (!stop) fill(d, 10); - slow.submit(new Thread(){ - public void run(){ - if ( !stop ) + slow.submit(new Thread() { + public void run() { + if (!stop) fill(d, 1); } }); } }); } - + @SuppressWarnings("unchecked") private synchronized void fill(Iterable> d, int skip) { + log.debug(f.getName() + " " + skip + " Start"); stop = false; int sz = 0; if (d instanceof Collection) { @@ -169,22 +171,31 @@ public class Chart extends JPanel { // series.clear(); int cnt = 0; + final XYSeries newSeries = new XYSeries(f.getName()); try { Amount last = null; for (Amount ax : d) { - if ( stop ){ - System.out.println("Stopping early " + skip); + if (stop) { + log.debug(f.getName() + " " + skip + " Abort"); return; } last = ax; if (cnt % skip == 0) { Amount y = (Amount) f.invoke(source, ax); - add(ax, y); + newSeries.add(ax.doubleValue(xUnit), y.doubleValue(yUnit)); } cnt++; } Amount y = (Amount) f.invoke(source, last); - add(last, y); + newSeries.add(last.doubleValue(xUnit), y.doubleValue(yUnit)); + SwingUtilities.invokeLater(new Thread() { + @Override + public void run() { + dataset.removeAllSeries(); + dataset.addSeries(newSeries); + log.debug(f.getName() + " Replaced"); + } + }); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -195,18 +206,15 @@ public class Chart extends JPanel { // TODO Auto-generated catch block e.printStackTrace(); } + log.debug(f.getName() + " " + skip + " Done"); } - private void add(Amount x, Amount y) { - series.add(x.doubleValue(xUnit), y.doubleValue(yUnit)); - } - - public void show(){ - new JFrame(){ + public void show() { + new JFrame() { private static final long serialVersionUID = 1L; { setContentPane(Chart.this); - setSize(640,480); + setSize(640, 480); setDefaultCloseOperation(DISPOSE_ON_CLOSE); } }.setVisible(true); @@ -225,7 +233,7 @@ public class Chart extends JPanel { .webThickness())); c.show(); - + Chart v = new Chart(SI.MILLIMETER, SI.MILLIMETER.pow(3).asType(Volume.class), g, "volume");