package com.billkuker.rocketry.motorsim.visual;\r
+\r
import java.awt.BorderLayout;\r
import java.awt.Color;\r
import java.lang.reflect.InvocationTargetException;\r
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
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
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
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
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
// 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
// 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
.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