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.quantity.Duration;\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
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
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.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
+ boolean closed = false;\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
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 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
\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
+ 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
\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
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
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
}\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
\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
@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
+ \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
+ \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
- 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
+ @Override\r
+ public void componentResized(ComponentEvent arg0) {\r
+ setResizeWeight(.5);\r
+ setDividerLocation(.5);\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 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
\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
}\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
}\r
}\r
\r
+\r
}\r