]> git.gag.com Git - sw/motorsim/commitdiff
Made incremental render threadsafe
authorBill Kuker <bkuker@billkuker.com>
Thu, 2 Jul 2009 17:54:48 +0000 (17:54 +0000)
committerBill Kuker <bkuker@billkuker.com>
Thu, 2 Jul 2009 17:54:48 +0000 (17:54 +0000)
src/com/billkuker/rocketry/motorsim/visual/Chart.java

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