Add Multiport option
[sw/motorsim] / gui / com / billkuker / rocketry / motorsim / visual / workbench / MotorEditor.java
index 988ad6c53a7c3349061b87a0432050a0e0f876d7..65febeb0bea93238b6be7df1b7f28de69ef8b205 100644 (file)
@@ -1,31 +1,29 @@
 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
+import java.awt.event.ComponentEvent;\r
+import java.awt.event.ComponentListener;\r
 import java.awt.event.FocusEvent;\r
 import java.awt.event.FocusListener;\r
 import java.beans.PropertyChangeEvent;\r
 import java.beans.PropertyChangeListener;\r
 import java.beans.PropertyVetoException;\r
-import java.io.IOException;\r
-import java.util.HashMap;\r
+import java.net.URI;\r
 import java.util.List;\r
-import java.util.Map;\r
 import java.util.Vector;\r
 \r
-import javax.measure.quantity.Length;\r
 import javax.measure.unit.SI;\r
 import javax.swing.Box;\r
 import javax.swing.BoxLayout;\r
-import javax.swing.ComboBoxModel;\r
-import javax.swing.JButton;\r
+import javax.swing.DefaultComboBoxModel;\r
 import javax.swing.JComboBox;\r
 import javax.swing.JFrame;\r
 import javax.swing.JLabel;\r
 import javax.swing.JPanel;\r
-import javax.swing.JProgressBar;\r
 import javax.swing.JSplitPane;\r
 import javax.swing.JTabbedPane;\r
 import javax.swing.JTextArea;\r
@@ -35,20 +33,21 @@ import javax.swing.UIManager;
 import javax.swing.WindowConstants;\r
 \r
 import org.apache.log4j.Logger;\r
-import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;\r
-import org.fife.ui.rsyntaxtextarea.SyntaxConstants;\r
 import org.jscience.physics.amount.Amount;\r
 \r
 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
 import com.billkuker.rocketry.motorsim.Grain;\r
 import com.billkuker.rocketry.motorsim.Motor;\r
 import com.billkuker.rocketry.motorsim.Nozzle;\r
-import com.billkuker.rocketry.motorsim.RocketScience;\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
@@ -56,25 +55,54 @@ 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.Star;\r
-import com.billkuker.rocketry.motorsim.io.MotorIO;\r
 import com.billkuker.rocketry.motorsim.visual.BurnPanel;\r
+import com.billkuker.rocketry.motorsim.visual.ClassChooser;\r
 import com.billkuker.rocketry.motorsim.visual.Editor;\r
 import com.billkuker.rocketry.motorsim.visual.GrainPanel;\r
 import com.billkuker.rocketry.motorsim.visual.HardwarePanel;\r
+import com.billkuker.rocketry.motorsim.visual.SummaryPanel;\r
 \r
-public class MotorEditor extends JTabbedPane 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
-       RSyntaxTextArea text = new RSyntaxTextArea();\r
        Motor motor;\r
        GrainEditor grainEditor;\r
        BurnTab bt;\r
        Burn burn;\r
+       SummaryPanel sp;\r
+       JTextArea error;\r
+       JTabbedPane tabs;\r
 \r
        private Vector<BurnWatcher> burnWatchers = new Vector<BurnWatcher>();\r
-       private ComboBoxModel availableFuels;\r
+       private DefaultComboBoxModel availableFuels = new DefaultComboBoxModel();\r
+       \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
        private static final int CASING_TAB = 0;\r
@@ -90,43 +118,14 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                grainTypes.add(RodAndTubeGrain.class);\r
                grainTypes.add(CSlot.class);\r
                grainTypes.add(EndBurner.class);\r
+               grainTypes.add(MultiPort.class);\r
        }\r
-\r
-       private abstract class Chooser<T> extends JPanel {\r
-               private static final long serialVersionUID = 1L;\r
-               private List<Class<? extends T>> types;\r
-               private Map<Class<? extends T>, T> old = new HashMap<Class<? extends T>, T>();\r
-\r
-               @SuppressWarnings("unchecked")\r
-               public Chooser(T initial, List<Class<? extends T>> ts) {\r
-                       types = ts;\r
-                       if ( initial != null )\r
-                               old.put((Class<? extends T>)initial.getClass(), initial);\r
-                       setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));\r
-                       for (final Class<? extends T> c : types) {\r
-                               JButton b = new JButton(c.getSimpleName());\r
-                               add(b);\r
-                               b.addActionListener(new ActionListener() {\r
-                                       public void actionPerformed(ActionEvent e) {\r
-                                               try {\r
-                                                       T val = old.get(c);\r
-                                                       if ( val == null ){\r
-                                                               System.err.println("CREATED NEW =========================");\r
-                                                               val = c.newInstance();\r
-                                                               old.put(c, val);\r
-                                                       }\r
-                                                       choiceMade(val);\r
-                                               } catch (InstantiationException e1) {\r
-                                                       e1.printStackTrace();\r
-                                               } catch (IllegalAccessException e1) {\r
-                                                       e1.printStackTrace();\r
-                                               }\r
-                                       }\r
-                               });\r
-                       }\r
-               }\r
-\r
-               protected abstract void choiceMade(T o);\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
@@ -145,50 +144,64 @@ public class MotorEditor extends JTabbedPane 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
-                                       final JProgressBar bar = new JProgressBar(0, 100);\r
-                                       add(bar, BorderLayout.NORTH);\r
-                                       final JLabel progress = new JLabel();\r
-                                       add(progress, BorderLayout.CENTER);\r
-                                       try {\r
-                                               final Burn b = new Burn(motor,\r
+                                       try {                                           \r
+                                               final Burn b = new Burn(motor);\r
+                                               b.addBurnProgressListener(\r
                                                                new Burn.BurnProgressListener() {\r
+                                                                       @Override\r
+                                                                       public void burnComplete(){};\r
                                                                        @Override\r
                                                                        public void setProgress(float f) {\r
-                                                                               int pct = (int)(f*100);\r
-                                                                               bar.setValue(pct);\r
-                                                                               Amount<Length> web = motor.getGrain().webThickness();\r
-                                                                               Amount<Length> remaining = web.times(1.0 - f);\r
-                                                                               \r
-                                                                               progress.setText("Progress: " + pct + "% (" + RocketScience.ammountToRoundedString(remaining) + " web thickness remaining)");\r
                                                                                if ( currentThread != me ){\r
                                                                                        throw new BurnCanceled();\r
                                                                                }\r
                                                                        }\r
                                                                });\r
 \r
+                                               MotorEditor.this.add(sp = new SummaryPanel(b), BorderLayout.NORTH);\r
+                                               revalidate();\r
+                                               b.burn();\r
+\r
                                                final BurnPanel bp = new BurnPanel(b);\r
                                                SwingUtilities.invokeLater(new Thread() {\r
                                                        public void run() {\r
-                                                               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
                                        } catch (BurnCanceled c){\r
                                                log.info("Burn Canceled!");\r
-                                       } catch (Exception e) {\r
-                                               remove(bar);\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
@@ -206,14 +219,33 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                        if (g instanceof Grain.Composite) {\r
                                final JPanel p = new JPanel();\r
                                p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));\r
-                               p.add(new Editor(g));\r
+                               \r
+                               Editor grainEditor = new Editor(g);\r
+                               grainEditor.setAlignmentX(LEFT_ALIGNMENT);\r
+                               p.add(grainEditor);\r
+                               \r
                                for (Grain gg : ((Grain.Composite) g).getGrains()) {\r
-                                       final int grainEditorIndex = p.getComponentCount() + 1;\r
-                                       p.add(new Chooser<Grain>(gg, grainTypes) {\r
+                                       final int grainEditorIndex = p.getComponentCount() + 2;\r
+                                       \r
+                                       JLabel l = new JLabel("Grain Type:");\r
+                                       l.setAlignmentX(LEFT_ALIGNMENT);\r
+                                       p.add(l);\r
+                                       \r
+                                       p.add(new ClassChooser<Grain>(grainTypes, gg) {\r
                                                private static final long serialVersionUID = 1L;\r
-\r
+                                               {setAlignmentX(LEFT_ALIGNMENT);}\r
                                                @Override\r
-                                               protected void choiceMade(Grain ng) {\r
+                                               protected Grain classSelected(\r
+                                                               Class<? extends Grain> clazz, Grain ng) {\r
+                                                       if ( ng == null ){\r
+                                                               try {\r
+                                                                       ng = clazz.newInstance();\r
+                                                               } catch (InstantiationException e) {\r
+                                                                       e.printStackTrace();\r
+                                                               } catch (IllegalAccessException e) {\r
+                                                                       e.printStackTrace();\r
+                                                               }\r
+                                                       }\r
                                                        if (g instanceof MultiGrain) {\r
                                                                ((MultiGrain) g).setGrain(ng);\r
                                                                p.remove(grainEditorIndex);\r
@@ -221,9 +253,15 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                                                                p.remove(0);\r
                                                                p.add(new Editor(g), 0);\r
                                                        }\r
+                                                       return ng;\r
+\r
                                                }\r
                                        });\r
-                                       p.add(new Editor(gg));\r
+                                       \r
+                                       Editor ggEditor = new Editor(gg);\r
+                                       ggEditor.setAlignmentX(LEFT_ALIGNMENT);\r
+                                       p.add(ggEditor);\r
+                                       \r
                                        if (gg instanceof ChangeListening.Subject) {\r
                                                ((ChangeListening.Subject) gg)\r
                                                                .addPropertyChangeListener(MotorEditor.this);\r
@@ -242,25 +280,64 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                }\r
        }\r
 \r
-       private class CaseEditor extends JSplitPane {\r
+       private class CaseEditor extends JSplitPane implements ComponentListener {\r
                private static final long serialVersionUID = 1L;\r
+               \r
+               private HardwarePanel hp;\r
+               private JPanel casing;\r
+               private JPanel nozzle;\r
+               private Editor casingEditor;\r
+               private Editor nozzleEditor;\r
+               \r
+               private void setup() {\r
+                       if (casingEditor != null)\r
+                               casing.remove(casingEditor);\r
+                       casingEditor = new Editor(motor.getChamber());\r
+                       casingEditor.setAlignmentX(LEFT_ALIGNMENT);\r
+                       casing.add(casingEditor);\r
+                       \r
+                       if (nozzleEditor != null)\r
+                               nozzle.remove(nozzleEditor);\r
+                       nozzleEditor = new Editor(motor.getNozzle());\r
+                       nozzleEditor.setAlignmentX(LEFT_ALIGNMENT);\r
+                       nozzle.add(nozzleEditor);\r
+                       \r
+                       if (hp != null)\r
+                               remove(hp);\r
+                       setBottomComponent(hp = new HardwarePanel(motor));\r
+                       if (motor.getNozzle() instanceof ChangeListening.Subject) {\r
+                               ((ChangeListening.Subject) motor.getNozzle())\r
+                                               .addPropertyChangeListener(MotorEditor.this);\r
+                       }\r
+                       if (motor.getChamber() instanceof ChangeListening.Subject) {\r
+                               ((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(Nozzle n, Chamber c) {\r
+               public CaseEditor() {\r
                        super(JSplitPane.VERTICAL_SPLIT);\r
                        setName("General Parameters");\r
+                       this.addComponentListener(this);\r
                        \r
                        JPanel parts = new JPanel();\r
                        parts.setLayout(new BoxLayout(parts, BoxLayout.X_AXIS));\r
                        setTopComponent(parts);\r
-                       setBottomComponent(new HardwarePanel(n, c));\r
                        \r
                        JPanel nameAndFuel = new JPanel();\r
                        nameAndFuel.setLayout(new BoxLayout(nameAndFuel, BoxLayout.Y_AXIS));\r
 \r
-                       nameAndFuel.add(new JLabel("Name:"));\r
+                       JLabel l = new JLabel("Name:");\r
+                       l.setAlignmentX(LEFT_ALIGNMENT);\r
+                       nameAndFuel.add(l);\r
                        nameAndFuel.add(new JTextField(motor.getName()) {\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
@@ -284,13 +361,16 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
 \r
                                }\r
                        });\r
-                       nameAndFuel.add(new JLabel("Fuel:"));\r
+                       \r
+                       l = new JLabel("Fuel:");\r
+                       l.setAlignmentX(LEFT_ALIGNMENT);\r
+                       nameAndFuel.add(l);\r
+                       \r
                        nameAndFuel.add( new JComboBox(availableFuels){\r
-                               {\r
-                                       this.setSelectedItem(motor.getFuel());\r
-                               }\r
                                private static final long serialVersionUID = 1L;\r
                                {\r
+                                       setAlignmentX(LEFT_ALIGNMENT);\r
+                                       this.setSelectedItem(motor.getFuel());\r
                                        setMinimumSize(new Dimension(200, 20));\r
                                        setMaximumSize(new Dimension(Short.MAX_VALUE, 20));\r
                                        addActionListener(new ActionListener(){\r
@@ -301,98 +381,142 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                                                }});\r
                                }\r
                        });\r
+                       \r
+                       l = new JLabel("Casing:");\r
+                       l.setAlignmentX(LEFT_ALIGNMENT);\r
+                       nameAndFuel.add(l);\r
+                       \r
+                       nameAndFuel.add(new ClassChooser<Chamber>(chamberTypes, motor.getChamber()) {\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
+                               }\r
+                               @Override\r
+                               protected Chamber classSelected(Class<? extends Chamber> clazz, Chamber c) {\r
+                                       try {\r
+                                               if ( c != null ){\r
+                                                       motor.setChamber(c);\r
+                                               } else {\r
+                                                       motor.setChamber(clazz.newInstance());\r
+                                               }\r
+                                               return motor.getChamber();\r
+                                       } catch (InstantiationException e) {\r
+                                               log.error(e);\r
+                                       } catch (IllegalAccessException e) {\r
+                                               log.error(e);\r
+                                       }\r
+                                       return null;\r
+                               }\r
+                       });\r
+                       \r
+                       \r
                        nameAndFuel.add(Box.createVerticalGlue());\r
                        parts.add(nameAndFuel);\r
                        \r
-                       JPanel casing = new JPanel();\r
+                       casing = new JPanel();\r
                        casing.setLayout(new BoxLayout(casing, BoxLayout.Y_AXIS));\r
-                       casing.add(new JLabel("Casing:"));\r
-                       casing.add(new Editor(c));\r
+                       l = new JLabel("Casing:");\r
+                       l.setAlignmentX(LEFT_ALIGNMENT);\r
+                       casing.add(l);\r
                        parts.add(casing);\r
                        \r
-                       JPanel nozzle = new JPanel();\r
+                       nozzle = new JPanel();\r
                        nozzle.setLayout(new BoxLayout(nozzle, BoxLayout.Y_AXIS));\r
-                       nozzle.add(new JLabel("Nozzle:"));\r
-                       nozzle.add(new Editor(n));\r
+                       l = new JLabel("Nozzle:");\r
+                       l.setAlignmentX(LEFT_ALIGNMENT);\r
+                       nozzle.add(l);\r
                        parts.add(nozzle);\r
+                       \r
+                       motor.addPropertyChangeListener(new PropertyChangeListener() {\r
+                               @Override\r
+                               public void propertyChange(PropertyChangeEvent arg0) {\r
+                                       setup();\r
+                                       setResizeWeight(.5);\r
+                                       setDividerLocation(.5);\r
+                               }\r
+                       });\r
+                       \r
+                       setup();\r
+               }\r
+\r
+               @Override\r
+               public void componentHidden(ComponentEvent arg0) {\r
 \r
-                       if (n instanceof ChangeListening.Subject) {\r
-                               ((ChangeListening.Subject) n)\r
-                                               .addPropertyChangeListener(MotorEditor.this);\r
-                       }\r
-                       if (c instanceof ChangeListening.Subject) {\r
-                               ((ChangeListening.Subject) c)\r
-                                               .addPropertyChangeListener(MotorEditor.this);\r
-                       }\r
                }\r
-       }\r
 \r
-       {\r
-               text.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);\r
+               @Override\r
+               public void componentMoved(ComponentEvent arg0) {\r
 \r
-       }\r
+               }\r
 \r
-       public MotorEditor(Motor m, ComboBoxModel fuels) {\r
-               super(JTabbedPane.BOTTOM);\r
-               this.availableFuels = fuels;\r
-               text.setName("XML");\r
-               text.setEditable(false);\r
-               //add(text, XML_TAB);\r
-               setMotor(m, true);\r
+               @Override\r
+               public void componentResized(ComponentEvent arg0) {\r
+                       setResizeWeight(.5);\r
+                       setDividerLocation(.5);\r
+               }\r
+\r
+               @Override\r
+               public void componentShown(ComponentEvent arg0) {\r
+\r
+               }\r
        }\r
 \r
+\r
+\r
+\r
        public Motor getMotor() {\r
                return motor;\r
        }\r
 \r
-       private void reText() {\r
-               try {\r
-                       text.setText(MotorIO.writeMotor(motor));\r
-               } catch (IOException e) {\r
-                       throw new Error(e);\r
-               }\r
-       }\r
 \r
-       private void setMotor(Motor m, boolean retext) {\r
+       private void setMotor(Motor m) {\r
                if (motor != null)\r
                        motor.removePropertyChangeListener(this);\r
                motor = m;\r
                motor.addPropertyChangeListener(this);\r
-               if (retext)\r
-                       reText();\r
                if (grainEditor != null)\r
                        remove(grainEditor);\r
-               while (getTabCount() > 1)\r
-                       removeTabAt(1);\r
-               add(new CaseEditor(motor.getNozzle(), motor.getChamber()), CASING_TAB);\r
-               add(new GrainEditor(motor.getGrain()), GRAIN_TAB);\r
-               add(bt = new BurnTab(), BURN_TAB);\r
+               while (tabs.getTabCount() > 1)\r
+                       tabs.removeTabAt(1);\r
+               tabs.add(new CaseEditor(), CASING_TAB);\r
+               tabs.add(new GrainEditor(motor.getGrain()), GRAIN_TAB);\r
+               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
                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
-               m.setGrain(new MultiGrain(g, 2));\r
+               \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
@@ -401,9 +525,9 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
 \r
        public void focusOnObject(Object o) {\r
                if (o instanceof Grain)\r
-                       setSelectedIndex(GRAIN_TAB);\r
+                       tabs.setSelectedIndex(GRAIN_TAB);\r
                if (o instanceof Chamber || o instanceof Nozzle)\r
-                       setSelectedIndex(CASING_TAB);\r
+                       tabs.setSelectedIndex(CASING_TAB);\r
        }\r
 \r
        public void addBurnWatcher(BurnWatcher bw) {\r
@@ -431,7 +555,6 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
        }\r
 \r
        public void propertyChange(PropertyChangeEvent evt) {\r
-               reText();\r
                // Dont re-burn for a name change!\r
                if (!evt.getPropertyName().equals("Name")){\r
                        bt.reBurn();\r
@@ -441,4 +564,5 @@ public class MotorEditor extends JTabbedPane implements PropertyChangeListener {
                }\r
        }\r
 \r
+\r
 }\r