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
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
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
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
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
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
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
@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
});\r
} catch (BurnCanceled c){\r
log.info("Burn Canceled!");\r
- } catch (Exception e) {\r
- if ( sp != null )\r
- MotorEditor.this.remove(sp);\r
- JTextArea t = new JTextArea(e.getMessage());\r
- t.setBackground(Colors.RED);\r
- t.setForeground(Color.WHITE);\r
- t.setEditable(false);\r
- MotorEditor.this.add(t, BorderLayout.NORTH);\r
- revalidate();\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
((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
@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
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
}\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
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
}\r
}\r
\r
+\r
}\r