]> git.gag.com Git - sw/motorsim/commitdiff
First rev of graphical motor editor
authorBill Kuker <bkuker@billkuker.com>
Thu, 2 Jul 2009 01:51:54 +0000 (01:51 +0000)
committerBill Kuker <bkuker@billkuker.com>
Thu, 2 Jul 2009 01:51:54 +0000 (01:51 +0000)
src/com/billkuker/rocketry/motorsim/visual/MotorEditor.java [new file with mode: 0644]

diff --git a/src/com/billkuker/rocketry/motorsim/visual/MotorEditor.java b/src/com/billkuker/rocketry/motorsim/visual/MotorEditor.java
new file mode 100644 (file)
index 0000000..297f2e7
--- /dev/null
@@ -0,0 +1,281 @@
+package com.billkuker.rocketry.motorsim.visual;\r
+\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.awt.event.TextEvent;\r
+import java.awt.event.TextListener;\r
+import java.beans.PropertyChangeEvent;\r
+import java.beans.PropertyChangeListener;\r
+import java.beans.PropertyVetoException;\r
+import java.io.IOException;\r
+\r
+import javax.measure.quantity.Pressure;\r
+import javax.measure.quantity.Velocity;\r
+import javax.measure.unit.SI;\r
+import javax.swing.BoxLayout;\r
+import javax.swing.JButton;\r
+import javax.swing.JFrame;\r
+import javax.swing.JPanel;\r
+import javax.swing.JSplitPane;\r
+import javax.swing.JTabbedPane;\r
+import javax.swing.SwingUtilities;\r
+import javax.swing.UIManager;\r
+import javax.swing.WindowConstants;\r
+import javax.swing.event.DocumentEvent;\r
+import javax.swing.event.DocumentListener;\r
+\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.Chamber;\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.MotorPart;\r
+import com.billkuker.rocketry.motorsim.Nozzle;\r
+import com.billkuker.rocketry.motorsim.fuel.KNSU;\r
+import com.billkuker.rocketry.motorsim.grain.CoredCylindricalGrain;\r
+import com.billkuker.rocketry.motorsim.grain.Finocyl;\r
+import com.billkuker.rocketry.motorsim.grain.GrainSet;\r
+import com.billkuker.rocketry.motorsim.grain.Moonburner;\r
+import com.billkuker.rocketry.motorsim.grain.MultiGrain;\r
+import com.billkuker.rocketry.motorsim.grain.RodAndTubeGrain;\r
+import com.billkuker.rocketry.motorsim.io.MotorIO;\r
+import com.billkuker.rocketry.motorsim.visual.Chart.IntervalDomain;\r
+\r
+public class MotorEditor extends JTabbedPane implements PropertyChangeListener, DocumentListener{\r
+       RSyntaxTextArea text = new RSyntaxTextArea();\r
+       Motor motor;\r
+       GrainEditor grainEditor;\r
+       \r
+       private class GrainChooser extends JPanel{\r
+               private Class[] types = {\r
+                                       CoredCylindricalGrain.class,\r
+                                       Finocyl.class,\r
+                                       Moonburner.class,\r
+                                       RodAndTubeGrain.class\r
+                               };\r
+               public GrainChooser(){\r
+                       setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));\r
+                       for ( final Class 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
+                                                       grainChosen((Grain)c.newInstance());\r
+                                               } catch (InstantiationException e1) {\r
+                                                       e1.printStackTrace();\r
+                                               } catch (IllegalAccessException e1) {\r
+                                                       e1.printStackTrace();\r
+                                               }\r
+                                       }\r
+                               });\r
+                       }\r
+               }\r
+               protected void grainChosen(Grain g){\r
+                       System.out.println(g);\r
+               }\r
+       }\r
+       \r
+       private class GrainEditor extends JSplitPane{\r
+               public GrainEditor(final Grain g){\r
+                       super(JSplitPane.HORIZONTAL_SPLIT);\r
+                       setRightComponent(new GrainPanel(g));\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
+                               for ( Grain gg : ((Grain.Composite)g).getGrains() ){\r
+                                       final int grainEditorIndex = p.getComponentCount() + 1;\r
+                                       p.add(new GrainChooser(){\r
+                                               @Override\r
+                                               protected void grainChosen(Grain ng){\r
+                                                       if ( g instanceof MultiGrain ){\r
+                                                               ((MultiGrain) g).setGrain(ng);\r
+                                                               p.remove(grainEditorIndex);\r
+                                                               p.add(new Editor(ng), grainEditorIndex);\r
+                                                               System.out.println("Chose new grain");\r
+                                                       }\r
+                                               }\r
+                                       });\r
+                                       p.add(new Editor(gg));\r
+                                       if ( gg instanceof MotorPart ){\r
+                                               ((MotorPart)gg).addPropertyChangeListener(MotorEditor.this);\r
+                                       }\r
+                               }\r
+                               setLeftComponent(p);\r
+                       } else {\r
+                               setLeftComponent(new Editor(g));\r
+                       }\r
+                       setDividerLocation(.25);\r
+                       setResizeWeight(.25);\r
+                       if ( g instanceof MotorPart ){\r
+                               ((MotorPart)g).addPropertyChangeListener(MotorEditor.this);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       private class FuelEditor extends JSplitPane{\r
+               public FuelEditor(Fuel f){\r
+                       super(JSplitPane.HORIZONTAL_SPLIT);\r
+                       Chart<Pressure, Velocity> burnRate;\r
+                       try {\r
+                               burnRate = new Chart<Pressure, Velocity>(\r
+                                               SI.MEGA(SI.PASCAL),\r
+                                               SI.METERS_PER_SECOND,\r
+                                               f,\r
+                                               "burnRate");\r
+                       } catch (NoSuchMethodException e) {\r
+                               throw new Error(e);\r
+                       }\r
+                       burnRate.setDomain(\r
+                                       burnRate.new IntervalDomain(\r
+                                                       Amount.valueOf(0, SI.MEGA(SI.PASCAL)),\r
+                                                       Amount.valueOf(11, SI.MEGA(SI.PASCAL)),\r
+                                                       20\r
+                                                       ));\r
+\r
+                       setLeftComponent(new Editor(f));\r
+                       setRightComponent(burnRate);\r
+                       setDividerLocation(.25);\r
+                       setResizeWeight(.25);\r
+                       if ( f instanceof MotorPart ){\r
+                               ((MotorPart)f).addPropertyChangeListener(MotorEditor.this);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       private class CaseEditor extends JSplitPane{\r
+\r
+               public CaseEditor(Nozzle n, Chamber c){\r
+                       super(JSplitPane.HORIZONTAL_SPLIT, \r
+                                       new JSplitPane(JSplitPane.VERTICAL_SPLIT,\r
+                                                       new Editor(n), new Editor(c)), new NozzlePanel(n));\r
+                       JSplitPane parts = (JSplitPane)getLeftComponent();\r
+                       parts.setDividerLocation(.5);\r
+                       parts.setResizeWeight(.5);\r
+                       setDividerLocation(.25);\r
+                       setResizeWeight(.25);\r
+\r
+                       if ( n instanceof MotorPart ){\r
+                               ((MotorPart)n).addPropertyChangeListener(MotorEditor.this);\r
+                       }\r
+                       if ( c instanceof MotorPart ){\r
+                               ((MotorPart)c).addPropertyChangeListener(MotorEditor.this);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       {\r
+               text.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);\r
+\r
+       }\r
+       \r
+       public MotorEditor(Motor m){\r
+               super(JTabbedPane.BOTTOM);\r
+               text.getDocument().addDocumentListener(this);\r
+               addTab("XML", text);\r
+               setMotor(m, true);\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
+               motor = m;\r
+               if ( retext )\r
+                       reText();\r
+               if ( grainEditor != null)\r
+                       remove(grainEditor);\r
+       while ( getTabCount() > 1       )\r
+               removeTabAt(1);\r
+               add("Casing", new CaseEditor(motor.getNozzle(), motor.getChamber()));\r
+               add("Grain", new GrainEditor(motor.getGrain()));\r
+               add("Fuel", new FuelEditor(motor.getFuel()));\r
+       }\r
+       \r
+       @Deprecated\r
+       private static Motor defaultMotor() {\r
+               Motor m = new Motor();\r
+               m.setName("Example Motor");\r
+               m.setFuel(new KNSU());\r
+\r
+               CylindricalChamber c = new CylindricalChamber();\r
+               c.setLength(Amount.valueOf(200, SI.MILLIMETER));\r
+               c.setID(Amount.valueOf(25, 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(23.5, SI.MILLIMETER));\r
+                       g.setID(Amount.valueOf(7.9375, SI.MILLIMETER));\r
+               } catch (PropertyVetoException v) {\r
+                       throw new Error(v);\r
+               }\r
+\r
+               m.setGrain(new MultiGrain(g,2));\r
+\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.setEfficiency(.85);\r
+               m.setNozzle(n);\r
+\r
+               return m;\r
+       }\r
+       \r
+       @Deprecated\r
+       public void showAsWindow(){\r
+               JFrame f = new JFrame();\r
+               f.setSize(1024,768);\r
+               f.setContentPane(this);\r
+               f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);\r
+               f.setVisible(true);\r
+       }\r
+       \r
+       public static void main(String args[]) throws Exception{\r
+               try {\r
+                       UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());\r
+               } catch (Exception e1) {\r
+                       e1.printStackTrace();\r
+               }\r
+               new MotorEditor(defaultMotor()).showAsWindow();\r
+       }\r
+\r
+       public void propertyChange(PropertyChangeEvent evt) {\r
+               reText();\r
+       }\r
+\r
+\r
+       public void changedUpdate(DocumentEvent e) {\r
+               try {\r
+                       final Motor m = MotorIO.readMotor(text.getText());\r
+                       SwingUtilities.invokeLater(new Runnable(){\r
+                               public void run() {\r
+                                       setMotor(m, false);\r
+                               }});\r
+                       System.out.println("Motor Updated");\r
+               } catch (Throwable e1) {\r
+                       //Leave blank, motor might be broken\r
+               }\r
+       }\r
+\r
+       public void insertUpdate(DocumentEvent e) {\r
+               // TODO Auto-generated method stub\r
+       }\r
+\r
+       public void removeUpdate(DocumentEvent e) {\r
+               // TODO Auto-generated method stub\r
+       }\r
+}\r