Stop processing a burn on motor close
[sw/motorsim] / gui / com / billkuker / rocketry / motorsim / visual / workbench / MotorEditor.java
index 4005c6420d0ca033aa32fd4b7523a35814c9d69f..c71e2fdbdcc6074d22749fc55161c97164963744 100644 (file)
@@ -1,6 +1,7 @@
 package com.billkuker.rocketry.motorsim.visual.workbench;\r
 \r
 import java.awt.BorderLayout;\r
+import java.awt.Color;\r
 import java.awt.Dimension;\r
 import java.awt.event.ActionEvent;\r
 import java.awt.event.ActionListener;\r
@@ -11,10 +12,11 @@ import java.awt.event.FocusListener;
 import java.beans.PropertyChangeEvent;\r
 import java.beans.PropertyChangeListener;\r
 import java.beans.PropertyVetoException;\r
-import java.util.Collection;\r
+import java.net.URI;\r
 import java.util.List;\r
 import java.util.Vector;\r
 \r
+import javax.measure.quantity.Duration;\r
 import javax.measure.unit.SI;\r
 import javax.swing.Box;\r
 import javax.swing.BoxLayout;\r
@@ -37,6 +39,7 @@ import org.jscience.physics.amount.Amount;
 import com.billkuker.rocketry.motorsim.Burn;\r
 import com.billkuker.rocketry.motorsim.Chamber;\r
 import com.billkuker.rocketry.motorsim.ChangeListening;\r
+import com.billkuker.rocketry.motorsim.Colors;\r
 import com.billkuker.rocketry.motorsim.ConvergentDivergentNozzle;\r
 import com.billkuker.rocketry.motorsim.CylindricalChamber;\r
 import com.billkuker.rocketry.motorsim.Fuel;\r
@@ -44,6 +47,8 @@ import com.billkuker.rocketry.motorsim.Grain;
 import com.billkuker.rocketry.motorsim.Motor;\r
 import com.billkuker.rocketry.motorsim.Nozzle;\r
 import com.billkuker.rocketry.motorsim.cases.Schedule40;\r
+import com.billkuker.rocketry.motorsim.cases.Schedule80;\r
+import com.billkuker.rocketry.motorsim.fuel.FuelResolver;\r
 import com.billkuker.rocketry.motorsim.fuel.KNSU;\r
 import com.billkuker.rocketry.motorsim.grain.CSlot;\r
 import com.billkuker.rocketry.motorsim.grain.CoredCylindricalGrain;\r
@@ -51,7 +56,9 @@ import com.billkuker.rocketry.motorsim.grain.EndBurner;
 import com.billkuker.rocketry.motorsim.grain.Finocyl;\r
 import com.billkuker.rocketry.motorsim.grain.Moonburner;\r
 import com.billkuker.rocketry.motorsim.grain.MultiGrain;\r
+import com.billkuker.rocketry.motorsim.grain.MultiPort;\r
 import com.billkuker.rocketry.motorsim.grain.RodAndTubeGrain;\r
+import com.billkuker.rocketry.motorsim.grain.Square;\r
 import com.billkuker.rocketry.motorsim.grain.Star;\r
 import com.billkuker.rocketry.motorsim.visual.BurnPanel;\r
 import com.billkuker.rocketry.motorsim.visual.ClassChooser;\r
@@ -60,7 +67,7 @@ import com.billkuker.rocketry.motorsim.visual.GrainPanel;
 import com.billkuker.rocketry.motorsim.visual.HardwarePanel;\r
 import com.billkuker.rocketry.motorsim.visual.SummaryPanel;\r
 \r
-public class MotorEditor extends JPanel implements PropertyChangeListener {\r
+public class MotorEditor extends JPanel implements PropertyChangeListener, FuelResolver.FuelsChangeListener{\r
        private static final long serialVersionUID = 1L;\r
        private static Logger log = Logger.getLogger(MotorEditor.class);\r
        Motor motor;\r
@@ -68,14 +75,36 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
        BurnTab bt;\r
        Burn burn;\r
        SummaryPanel sp;\r
-       \r
+       JTextArea error;\r
        JTabbedPane tabs;\r
+       boolean closed = false;\r
 \r
        private Vector<BurnWatcher> burnWatchers = new Vector<BurnWatcher>();\r
        private DefaultComboBoxModel availableFuels = new DefaultComboBoxModel();\r
        \r
-       public void addFuel(Fuel f){\r
-               availableFuels.addElement(f);\r
+       public MotorEditor(Motor m) {\r
+               setLayout( new BorderLayout());\r
+               tabs = new JTabbedPane(JTabbedPane.TOP);\r
+               add(tabs, BorderLayout.CENTER);\r
+               availableFuels.addElement(m.getFuel());\r
+               availableFuels.setSelectedItem(m.getFuel());\r
+               FuelResolver.addFuelsChangeListener(this);\r
+               fuelsChanged();\r
+               setMotor(m);\r
+               \r
+               Burn.getBurnSettings().addPropertyChangeListener(this);\r
+       }\r
+\r
+       @Override\r
+       public void fuelsChanged() {\r
+               while ( availableFuels.getSize() > 0 && availableFuels.getIndexOf(availableFuels.getSelectedItem()) != 0 )\r
+                       availableFuels.removeElementAt(0);\r
+               while ( availableFuels.getSize() > 1 )\r
+                       availableFuels.removeElementAt(1);\r
+               for ( Fuel f : FuelResolver.getFuelMap().values() ){\r
+                       if ( f != availableFuels.getSelectedItem() )\r
+                               availableFuels.addElement(f);\r
+               }\r
        }\r
 \r
        //private static final int XML_TAB = 0;\r
@@ -92,12 +121,15 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                grainTypes.add(RodAndTubeGrain.class);\r
                grainTypes.add(CSlot.class);\r
                grainTypes.add(EndBurner.class);\r
+               grainTypes.add(MultiPort.class);\r
+               grainTypes.add(Square.class);\r
        }\r
        \r
        private List<Class<? extends Chamber>> chamberTypes = new Vector<Class<? extends Chamber>>();\r
        {\r
                chamberTypes.add(CylindricalChamber.class);\r
                chamberTypes.add(Schedule40.class);\r
+               chamberTypes.add(Schedule80.class);\r
        }\r
 \r
        private class BurnTab extends JPanel {\r
@@ -116,10 +148,22 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
 \r
                public void reBurn() {\r
                        removeAll();\r
+                       if ( error != null ){\r
+                               MotorEditor.this.remove(error);\r
+                               error = null;\r
+                       }\r
+                       if ( sp != null ){\r
+                               MotorEditor.this.remove(sp);\r
+                               sp = null;\r
+                       }\r
                        currentThread = new Thread() {\r
+                               {\r
+                                       setName("Burn " + motor.getName());\r
+                                       setDaemon(true);\r
+                               }\r
                                public void run() {\r
                                        final Thread me = this;\r
-                                       try {\r
+                                       try {                                           \r
                                                final Burn b = new Burn(motor);\r
                                                b.addBurnProgressListener(\r
                                                                new Burn.BurnProgressListener() {\r
@@ -128,12 +172,16 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                                                                        @Override\r
                                                                        public void setProgress(float f) {\r
                                                                                if ( currentThread != me ){\r
+                                                                                       log.info("Cancel burn on change");\r
+                                                                                       throw new BurnCanceled();\r
+                                                                               }\r
+                                                                               if ( closed ){\r
+                                                                                       log.info("Cancel burn on close");\r
                                                                                        throw new BurnCanceled();\r
                                                                                }\r
                                                                        }\r
                                                                });\r
-                                               if ( sp != null )\r
-                                                       MotorEditor.this.remove(sp);\r
+\r
                                                MotorEditor.this.add(sp = new SummaryPanel(b), BorderLayout.NORTH);\r
                                                revalidate();\r
                                                b.burn();\r
@@ -150,10 +198,19 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                                                });\r
                                        } catch (BurnCanceled c){\r
                                                log.info("Burn Canceled!");\r
-                                       } catch (Exception e) {\r
-                                               JTextArea t = new JTextArea(e.getMessage());\r
-                                               t.setEditable(false);\r
-                                               add(t);\r
+                                       } catch (final Exception e) {\r
+                                               SwingUtilities.invokeLater(new Thread() {\r
+                                                       public void run() {\r
+                                                               if ( sp != null )\r
+                                                                       MotorEditor.this.remove(sp);\r
+                                                               error = new JTextArea(e.getMessage());\r
+                                                               error.setBackground(Colors.RED);\r
+                                                               error.setForeground(Color.WHITE);\r
+                                                               error.setEditable(false);\r
+                                                               MotorEditor.this.add(error, BorderLayout.NORTH);\r
+                                                               revalidate();\r
+                                                       }\r
+                                               });\r
                                        }\r
                                }\r
                        };\r
@@ -256,8 +313,7 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                        \r
                        if (hp != null)\r
                                remove(hp);\r
-                       setBottomComponent(hp = new HardwarePanel(motor.getNozzle(),\r
-                                       motor.getChamber()));\r
+                       setBottomComponent(hp = new HardwarePanel(motor));\r
                        if (motor.getNozzle() instanceof ChangeListening.Subject) {\r
                                ((ChangeListening.Subject) motor.getNozzle())\r
                                                .addPropertyChangeListener(MotorEditor.this);\r
@@ -266,6 +322,10 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                                ((ChangeListening.Subject) motor.getChamber())\r
                                                .addPropertyChangeListener(MotorEditor.this);\r
                        }\r
+                       if (motor.getFuel() instanceof ChangeListening.Subject ){\r
+                               ((ChangeListening.Subject) motor.getFuel())\r
+                                               .addPropertyChangeListener(MotorEditor.this);\r
+                       }\r
                }\r
 \r
                public CaseEditor() {\r
@@ -326,7 +386,7 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                                                @Override\r
                                                public void actionPerformed(ActionEvent e) {\r
                                                        motor.setFuel((Fuel)getSelectedItem());\r
-                                                       System.out.println("FUEL CHANGED");\r
+                                                       log.debug("FUEL CHANGED");\r
                                                }});\r
                                }\r
                        });\r
@@ -352,17 +412,55 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                                                }\r
                                                return motor.getChamber();\r
                                        } catch (InstantiationException e) {\r
-                                               // TODO Auto-generated catch block\r
-                                               e.printStackTrace();\r
+                                               log.error(e);\r
                                        } catch (IllegalAccessException e) {\r
-                                               // TODO Auto-generated catch block\r
-                                               e.printStackTrace();\r
+                                               log.error(e);\r
                                        }\r
                                        return null;\r
                                }\r
                        });\r
                        \r
                        \r
+                       \r
+                       \r
+                       l = new JLabel("Delay:");\r
+                       l.setAlignmentX(LEFT_ALIGNMENT);\r
+                       nameAndFuel.add(l);\r
+                       nameAndFuel.add(new JTextField(Double.toString(motor.getEjectionDelay().doubleValue(SI.SECOND))) {\r
+                               private static final long serialVersionUID = 1L;\r
+                               {\r
+                                       setAlignmentX(LEFT_ALIGNMENT);\r
+                                       setMinimumSize(new Dimension(200, 20));\r
+                                       setMaximumSize(new Dimension(Short.MAX_VALUE, 20));\r
+                                       final JTextField t = this;\r
+                                       addFocusListener(new FocusListener() {\r
+\r
+                                               @Override\r
+                                               public void focusLost(FocusEvent e) {\r
+                                                       try {\r
+                                                               String n = t.getText();\r
+                                                               double d = Double.parseDouble(n);\r
+                                                               Amount<Duration> delay = Amount.valueOf(d, SI.SECOND);\r
+                                                               if ( delay != motor.getEjectionDelay() ){\r
+                                                                       motor.setEjectionDelay(delay);\r
+                                                               }\r
+                                                       } catch ( Exception ex ){\r
+                                                               log.warn(e);\r
+                                                               setText(Double.toString(motor.getEjectionDelay().doubleValue(SI.SECOND)));\r
+                                                       }\r
+                                               }\r
+\r
+                                               @Override\r
+                                               public void focusGained(FocusEvent e) {\r
+\r
+                                               }\r
+                                       });\r
+\r
+                               }\r
+                       });\r
+                       \r
+                       \r
+                       \r
                        nameAndFuel.add(Box.createVerticalGlue());\r
                        parts.add(nameAndFuel);\r
                        \r
@@ -415,16 +513,7 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
        }\r
 \r
 \r
-       public MotorEditor(Motor m, Collection<Fuel> fuels) {\r
-               \r
-               setLayout( new BorderLayout());\r
-               tabs = new JTabbedPane(JTabbedPane.BOTTOM);\r
-               add(tabs, BorderLayout.CENTER);\r
 \r
-               for ( Fuel f : fuels )\r
-                       addFuel(f);\r
-               setMotor(m);\r
-       }\r
 \r
        public Motor getMotor() {\r
                return motor;\r
@@ -445,35 +534,38 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                tabs.add(bt = new BurnTab(), BURN_TAB);\r
        }\r
 \r
+       private static int idx;\r
        public static Motor defaultMotor() {\r
                Motor m = new Motor();\r
-               m.setName("Example Motor");\r
-               m.setFuel(new KNSU());\r
+               m.setName("New Motor " + ++idx);\r
+               try {\r
+                       m.setFuel(FuelResolver.getFuel(new URI("motorsim:KNDX")));\r
+               } catch (Exception e) {\r
+                       throw new Error(e);\r
+               }\r
 \r
                CylindricalChamber c = new CylindricalChamber();\r
-               c.setLength(Amount.valueOf(200, SI.MILLIMETER));\r
-               c.setID(Amount.valueOf(30, SI.MILLIMETER));\r
+               c.setLength(Amount.valueOf(420, SI.MILLIMETER));\r
+               c.setID(Amount.valueOf(70, SI.MILLIMETER));\r
+               c.setOD(Amount.valueOf(72, SI.MILLIMETER));\r
                m.setChamber(c);\r
 \r
-               Schedule40 pvc = new Schedule40();\r
-               pvc.setLength(Amount.valueOf(200, SI.MILLIMETER));\r
-               m.setChamber(pvc);\r
-               \r
                CoredCylindricalGrain g = new CoredCylindricalGrain();\r
                try {\r
-                       g.setLength(Amount.valueOf(70, SI.MILLIMETER));\r
-                       g.setOD(Amount.valueOf(30, SI.MILLIMETER));\r
-                       g.setID(Amount.valueOf(10, SI.MILLIMETER));\r
+                       g.setLength(Amount.valueOf(100, SI.MILLIMETER));\r
+                       g.setOD(Amount.valueOf(62, SI.MILLIMETER));\r
+                       g.setID(Amount.valueOf(20, SI.MILLIMETER));\r
                } catch (PropertyVetoException v) {\r
                        throw new Error(v);\r
                }\r
                \r
-\r
-               m.setGrain(new MultiGrain(g, 2));\r
+               MultiGrain mg = new MultiGrain(g, 4);\r
+               mg.setSpacing(Amount.valueOf(6, SI.MILLIMETER));\r
+               m.setGrain(mg);\r
 \r
                ConvergentDivergentNozzle n = new ConvergentDivergentNozzle();\r
-               n.setThroatDiameter(Amount.valueOf(7.962, SI.MILLIMETER));\r
-               n.setExitDiameter(Amount.valueOf(13.79, SI.MILLIMETER));\r
+               n.setThroatDiameter(Amount.valueOf(14.089, SI.MILLIMETER));\r
+               n.setExitDiameter(Amount.valueOf(44.55, SI.MILLIMETER));\r
                n.setEfficiency(.85);\r
                m.setNozzle(n);\r
 \r
@@ -521,4 +613,5 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
                }\r
        }\r
 \r
+\r
 }\r