Added multi burn window
authorBill Kuker <bkuker@billkuker.com>
Thu, 13 Aug 2009 01:34:22 +0000 (01:34 +0000)
committerBill Kuker <bkuker@billkuker.com>
Thu, 13 Aug 2009 01:34:22 +0000 (01:34 +0000)
src/MotorSim.java [new file with mode: 0644]
src/MotorWorkbench.java [deleted file]
src/com/billkuker/rocketry/motorsim/visual/workbench/BurnWatcher.java [new file with mode: 0644]
src/com/billkuker/rocketry/motorsim/visual/workbench/MotorEditor.java
src/com/billkuker/rocketry/motorsim/visual/workbench/MotorWorkbench.java
src/com/billkuker/rocketry/motorsim/visual/workbench/MultiBurnChart.java [new file with mode: 0644]
src/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeCellRenderer.java
src/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeModel.java

diff --git a/src/MotorSim.java b/src/MotorSim.java
new file mode 100644 (file)
index 0000000..6f1a07f
--- /dev/null
@@ -0,0 +1,26 @@
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class MotorSim {
+
+       public static void main(String args[]) throws Exception {
+
+               try {
+                       System.setProperty("apple.laf.useScreenMenuBar", "true");
+                       System.setProperty(
+                                       "com.apple.mrj.application.apple.menu.about.name",
+                                       "MotorSim");
+                       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+               } catch (Exception e1) {
+                       e1.printStackTrace();
+               }
+               SwingUtilities.invokeLater(new Runnable(){
+                       @Override
+                       public void run() {
+                               new com.billkuker.rocketry.motorsim.visual.workbench.MotorWorkbench().setVisible(true);
+                       }
+               });
+               
+       }
+
+}
diff --git a/src/MotorWorkbench.java b/src/MotorWorkbench.java
deleted file mode 100644 (file)
index 716ac06..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
-
-public class MotorWorkbench {
-
-       public static void main(String args[]) throws Exception {
-
-               try {
-                       System.setProperty("apple.laf.useScreenMenuBar", "true");
-                       System.setProperty(
-                                       "com.apple.mrj.application.apple.menu.about.name",
-                                       "MotorWorkbench");
-                       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-               } catch (Exception e1) {
-                       e1.printStackTrace();
-               }
-               SwingUtilities.invokeLater(new Runnable(){
-                       @Override
-                       public void run() {
-                               new com.billkuker.rocketry.motorsim.visual.workbench.MotorWorkbench().setVisible(true);
-                       }
-               });
-               
-       }
-
-}
diff --git a/src/com/billkuker/rocketry/motorsim/visual/workbench/BurnWatcher.java b/src/com/billkuker/rocketry/motorsim/visual/workbench/BurnWatcher.java
new file mode 100644 (file)
index 0000000..7301cbd
--- /dev/null
@@ -0,0 +1,7 @@
+package com.billkuker.rocketry.motorsim.visual.workbench;
+
+import com.billkuker.rocketry.motorsim.Burn;
+
+public interface BurnWatcher {
+       public void replace( Burn oldBurn, Burn newBurn);
+}
index 315f6437c9fae943688bbfc2e502e47a2cd495e9..369e44138df5a519cc30adf524f56e2bc214c276 100644 (file)
@@ -10,6 +10,7 @@ import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;\r
 import java.beans.PropertyVetoException;\r
 import java.io.IOException;\r
+import java.util.Vector;\r
 \r
 import javax.measure.quantity.Pressure;\r
 import javax.measure.quantity.Velocity;\r
@@ -63,6 +64,9 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
        Motor motor;\r
        GrainEditor grainEditor;\r
        BurnTab bt;\r
+       Burn burn;\r
+       \r
+       private Vector<BurnWatcher> burnWatchers = new Vector<BurnWatcher>();\r
 \r
        private static final int XML_TAB = 0;\r
        private static final int CASING_TAB = 1;\r
@@ -133,6 +137,10 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                                                        remove(bar);\r
                                                        add(bp, BorderLayout.CENTER);\r
                                                        \r
+                                                       for( BurnWatcher bw : burnWatchers )\r
+                                                               bw.replace(burn, b);\r
+                                                       burn = b;\r
+                                                       \r
                                                        revalidate();\r
                                                }\r
                                        });\r
@@ -371,6 +379,10 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                if (o instanceof Fuel || o instanceof Fuel.CombustionProduct)\r
                        setSelectedIndex(FUEL_TAB);\r
        }\r
+       \r
+       public void addBurnWatcher(BurnWatcher bw){\r
+               burnWatchers.add(bw);\r
+       }\r
 \r
        @Deprecated\r
        public void showAsWindow() {\r
index 77083055325f226c8f827c71121cf66cc30f8a73..f1f0f20c947d2f61d5c55cfc1ce17b81cad0bf03 100644 (file)
@@ -39,6 +39,8 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
        private JTree tree;\r
        private JTabbedPane motors;\r
        private WorkbenchTreeModel tm;\r
+       private MultiBurnChart mb;\r
+       private JFrame allBurns;\r
 \r
        private HashMap<MotorEditor, File> e2f = new HashMap<MotorEditor, File>();\r
        private HashMap<File, MotorEditor> f2e = new HashMap<File, MotorEditor>();\r
@@ -46,12 +48,19 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
        private HashMap<Motor, MotorEditor> m2e = new HashMap<Motor, MotorEditor>();\r
 \r
        public MotorWorkbench() {\r
-               setTitle("MotorWorkbench");\r
+               setTitle("MotorSim 1.0 RC1");\r
                addMenu();\r
                setSize(1024, 768);\r
                top = new JPanel(new BorderLayout());\r
                setContentPane(top);\r
-\r
+               \r
+               mb = new MultiBurnChart();\r
+               allBurns = new JFrame();\r
+               allBurns.setSize(800, 600);\r
+               setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);\r
+               allBurns.add(mb);\r
+               allBurns.setVisible(true);\r
+               \r
                motors = new JTabbedPane();\r
 \r
                tree = new JTree(tm = new WorkbenchTreeModel());\r
@@ -69,7 +78,7 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                // split.setResizeWeight(.25);\r
                top.add(split, BorderLayout.CENTER);\r
 \r
-               setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);\r
+               setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);\r
                setVisible(true);\r
 \r
        }\r
@@ -142,6 +151,7 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                                                                                f2e.remove(e2f.get(e));\r
                                                                                e2f.remove(e);\r
                                                                                m2e.remove(e.getMotor());\r
+                                                                               mb.removeBurn(e.burn);\r
                                                                        }\r
                                                                });\r
                                                        }\r
@@ -238,6 +248,7 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
        public void addMotor(Motor m, File f) {\r
                tm.addMotor(m);\r
                MotorEditor e = new MotorEditor(m);\r
+               e.addBurnWatcher(mb);\r
                String title;\r
                if (f == null) {\r
                        title = "New Motor";\r
@@ -252,6 +263,11 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
 \r
        @Override\r
        public void valueChanged(TreeSelectionEvent e) {\r
+               if ( e.getPath().getLastPathComponent() == tm.getRoot() ){\r
+                       allBurns.setVisible(true);\r
+                       allBurns.toFront();\r
+               }\r
+               \r
                Motor m = getMotor(e.getPath());\r
                \r
                if ( m == null )\r
@@ -264,6 +280,8 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                                        .getLastPathComponent()).getUserObject();\r
                        m2e.get(m).focusOnObject(o);\r
                }\r
+               \r
+\r
        }\r
 \r
        private Motor getMotor(TreePath p) {\r
diff --git a/src/com/billkuker/rocketry/motorsim/visual/workbench/MultiBurnChart.java b/src/com/billkuker/rocketry/motorsim/visual/workbench/MultiBurnChart.java
new file mode 100644 (file)
index 0000000..365a8d6
--- /dev/null
@@ -0,0 +1,106 @@
+package com.billkuker.rocketry.motorsim.visual.workbench;
+
+import java.awt.BorderLayout;
+import java.util.HashMap;
+
+import javax.measure.quantity.Duration;
+import javax.measure.quantity.Force;
+import javax.measure.unit.SI;
+import javax.measure.unit.Unit;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.WindowConstants;
+import javax.swing.plaf.multi.MultiButtonUI;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.PlotOrientation;
+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.ConvergentDivergentNozzle;
+import com.billkuker.rocketry.motorsim.Motor;
+import com.billkuker.rocketry.motorsim.RocketScience;
+import com.billkuker.rocketry.motorsim.grain.MultiGrain;
+
+public class MultiBurnChart extends JPanel implements BurnWatcher {
+
+       private XYSeriesCollection dataset = new XYSeriesCollection();
+
+       private HashMap<Burn, XYSeries> burnToSeries = new HashMap<Burn, XYSeries>();
+       private Unit<Duration> time;
+       private Unit<Force> force;
+
+       @SuppressWarnings("unchecked")
+       public MultiBurnChart() {
+               this.setLayout(new BorderLayout());
+               time = RocketScience.UnitPreference.preference
+                               .getPreferredUnit(SI.SECOND);
+               force = RocketScience.UnitPreference.preference
+                               .getPreferredUnit(SI.NEWTON);
+               JFreeChart chart = ChartFactory.createXYLineChart(
+                               "Burns", // Title
+                               time.toString(), // x-axis Label
+                               force.toString(), // y-axis Label
+                               dataset, PlotOrientation.VERTICAL, // Plot Orientation
+                               true, // Show Legend
+                               true, // Use tool tips
+                               false // Configure chart to generate URLs?
+                               );
+               add(new ChartPanel(chart));
+       }
+
+       public void addBurn(Burn b) {
+               XYSeries s = createSeries(b);
+               burnToSeries.put(b, s);
+               dataset.addSeries(s);
+       }
+
+       private XYSeries createSeries(Burn b) {
+               XYSeries s = new XYSeries(b.getMotor().getName());
+               Amount<Force> low = Amount.valueOf(1, SI.NEWTON);
+               for( Burn.Interval i : b.getData().values() ){
+                       s.add(i.time.doubleValue(time), i.thrust.doubleValue(force));
+               }
+               return s;
+       }
+
+       public void removeBurn(Burn b) {
+               XYSeries s = burnToSeries.get(b);
+               if (s == null)
+                       return;
+               dataset.removeSeries(s);
+       }
+       
+       public static void main(String args[]) throws Exception{
+               MultiBurnChart c = new MultiBurnChart();
+               
+               JFrame f = new JFrame();
+               f.setSize(1024, 768);
+               f.setContentPane(c);
+               f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+               f.setVisible(true);
+
+               Motor m = MotorEditor.defaultMotor();
+               Burn b = new Burn(m);
+               c.addBurn(b);
+               
+               m.setName("Motor2");
+               ((ConvergentDivergentNozzle)m.getNozzle()).setThroatDiameter(Amount.valueOf(3, SI.MILLIMETER));
+               c.addBurn(new Burn(m));
+               
+               Thread.sleep(5000);
+               
+               c.removeBurn(b);
+               
+       }
+
+       @Override
+       public void replace(Burn oldBurn, Burn newBurn) {
+               removeBurn(oldBurn);
+               addBurn(newBurn);
+       }
+}
index 7acf3f7416114b0d559f5304e468d132124c38a7..03d85c3dfcc4d814f6e4f708be8af6567fa11151 100644 (file)
@@ -44,6 +44,8 @@ public class WorkbenchTreeCellRenderer extends DefaultTreeCellRenderer {
 
                if (part instanceof Motor) {
                        setText(((Motor) part).getName());
+               } else if ( part instanceof String ) {
+                       setText((String)part);
                } else if ( part == null ) {
                        setText("");
                } else {
index 85a0942cbfd7dc15b2c3818016f38d3b0edfd00d..db6b523c5e1c272e29adb46c10476b5b22bb3ff1 100644 (file)
@@ -95,7 +95,7 @@ public class WorkbenchTreeModel extends DefaultTreeModel {
        }
 
        public WorkbenchTreeModel() {
-               super(new DefaultMutableTreeNode(), true);
+               super(new DefaultMutableTreeNode("All Motors"), true);
        }
        
        @Override