Removed stupid tree
authorBill Kuker <bkuker@billkuker.com>
Fri, 12 Nov 2010 14:39:47 +0000 (14:39 +0000)
committerBill Kuker <bkuker@billkuker.com>
Fri, 12 Nov 2010 14:39:47 +0000 (14:39 +0000)
Removed fuel editing from main window
Added fuel edit window

Still need to plumb fuel editor and FuelResolver

12 files changed:
gui/com/billkuker/rocketry/motorsim/visual/workbench/AbstractFuelEditor.java [deleted file]
gui/com/billkuker/rocketry/motorsim/visual/workbench/FuelsEditor.java [deleted file]
gui/com/billkuker/rocketry/motorsim/visual/workbench/LinearFuelEditor.java [deleted file]
gui/com/billkuker/rocketry/motorsim/visual/workbench/MotorEditor.java
gui/com/billkuker/rocketry/motorsim/visual/workbench/MotorWorkbench.java
gui/com/billkuker/rocketry/motorsim/visual/workbench/SRFuelEditor.java [deleted file]
gui/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeCellRenderer.java [deleted file]
gui/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeModel.java [deleted file]
gui/fuel/AbstractFuelEditor.java [new file with mode: 0644]
gui/fuel/FuelsEditor.java [new file with mode: 0644]
gui/fuel/LinearFuelEditor.java [new file with mode: 0644]
gui/fuel/SRFuelEditor.java [new file with mode: 0644]

diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/AbstractFuelEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/AbstractFuelEditor.java
deleted file mode 100644 (file)
index af3fa26..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-package com.billkuker.rocketry.motorsim.visual.workbench;\r
-\r
-import java.awt.Component;\r
-\r
-import javax.measure.quantity.Pressure;\r
-import javax.measure.quantity.Velocity;\r
-import javax.measure.quantity.VolumetricDensity;\r
-import javax.measure.unit.SI;\r
-import javax.swing.JSplitPane;\r
-import javax.swing.SwingUtilities;\r
-\r
-import org.jscience.physics.amount.Amount;\r
-\r
-import com.billkuker.rocketry.motorsim.Fuel;\r
-import com.billkuker.rocketry.motorsim.fuel.EditableCombustionProduct;\r
-import com.billkuker.rocketry.motorsim.fuel.PiecewiseSaintRobertFuel;\r
-import com.billkuker.rocketry.motorsim.visual.Chart;\r
-import com.billkuker.rocketry.motorsim.visual.Editor;\r
-\r
-public abstract class AbstractFuelEditor  extends JSplitPane {\r
-       private static final long serialVersionUID = 1L;\r
-\r
-       protected static class EditablePSRFuel extends PiecewiseSaintRobertFuel {\r
-\r
-               @SuppressWarnings("unchecked")\r
-               private Amount<VolumetricDensity> idealDensity = (Amount<VolumetricDensity>) Amount\r
-                               .valueOf("1 g/mm^3");\r
-               \r
-               private double combustionEfficiency = 1;\r
-               private double densityRatio = 1;\r
-               private EditableCombustionProduct cp;\r
-               private String name = "New Fuel";\r
-\r
-               public EditablePSRFuel(Type t) {\r
-                       super(t);\r
-                       cp = new EditableCombustionProduct();\r
-               }\r
-               \r
-               public void clear(){\r
-                       super.clear();\r
-               }\r
-               \r
-               public void setType(Type t){\r
-                       super.setType(t);\r
-               }\r
-\r
-               public void add(Amount<Pressure> p, final double _a, final double _n) {\r
-                       super.add(p, _a, _n);\r
-\r
-               }\r
-\r
-               public Amount<VolumetricDensity> getIdealDensity() {\r
-                       return idealDensity;\r
-               }\r
-\r
-               public void setIdealDensity(Amount<VolumetricDensity> idealDensity) {\r
-                       this.idealDensity = idealDensity;\r
-               }\r
-\r
-               public double getCombustionEfficiency() {\r
-                       return combustionEfficiency;\r
-               }\r
-\r
-               public void setCombustionEfficiency(double combustionEfficiency) {\r
-                       this.combustionEfficiency = combustionEfficiency;\r
-               }\r
-\r
-               public double getDensityRatio() {\r
-                       return densityRatio;\r
-               }\r
-\r
-               public void setDensityRatio(double densityRatio) {\r
-                       this.densityRatio = densityRatio;\r
-               }\r
-\r
-               @Override\r
-               public CombustionProduct getCombustionProduct() {\r
-                       return cp;\r
-               }\r
-\r
-               public String getName() {\r
-                       return name;\r
-               }\r
-\r
-               public void setName(String name) {\r
-                       this.name = name;\r
-               }\r
-\r
-       }\r
-       \r
-       private final JSplitPane editParent;\r
-       private final JSplitPane editTop;\r
-       private final Fuel f;\r
-       private Chart<Pressure, Velocity> burnRate;\r
-       \r
-       public AbstractFuelEditor(Fuel f){\r
-               super(HORIZONTAL_SPLIT);\r
-               this.f = f;\r
-               \r
-               editTop = new JSplitPane(JSplitPane.VERTICAL_SPLIT);\r
-               editTop.setTopComponent(new Editor(f));\r
-               editTop.setBottomComponent(new Editor(f.getCombustionProduct()));\r
-               \r
-               editParent = new JSplitPane(JSplitPane.VERTICAL_SPLIT);\r
-               setLeftComponent(editParent);\r
-               editParent.setTopComponent(editTop);\r
-               editParent.setBottomComponent(getBurnrateEditComponent());\r
-               \r
-               setResizeWeight(0);\r
-               setDividerLocation(.3);\r
-               editParent.setDividerLocation(.5);\r
-               editTop.setDividerLocation(.5);\r
-               editParent.resetToPreferredSizes();\r
-               revalidate();\r
-\r
-               update();\r
-       }\r
-       \r
-       protected abstract Component getBurnrateEditComponent();\r
-       \r
-       public Fuel getFuel(){\r
-               return f;\r
-       }\r
-       \r
-\r
-\r
-       protected void update() {\r
-               SwingUtilities.invokeLater(new Runnable() {\r
-\r
-                       @Override\r
-                       public void run() {\r
-                               editTop.setTopComponent(new Editor(f));\r
-                               editTop.setBottomComponent(new Editor(f.getCombustionProduct()));\r
-                               if (burnRate != null)\r
-                                       AbstractFuelEditor.this.remove(burnRate);\r
-                               try {\r
-                                       burnRate = new Chart<Pressure, Velocity>(\r
-                                                       SI.MEGA(SI.PASCAL), SI.MILLIMETER.divide(SI.SECOND)\r
-                                                                       .asType(Velocity.class), f, "burnRate");\r
-                               } catch (NoSuchMethodException e) {\r
-                                       throw new Error(e);\r
-                               }\r
-                               burnRate.setDomain(burnRate.new IntervalDomain(Amount.valueOf(\r
-                                               0, SI.MEGA(SI.PASCAL)), Amount.valueOf(11, SI\r
-                                               .MEGA(SI.PASCAL)), 50));\r
-                               AbstractFuelEditor.this.setRightComponent(burnRate);\r
-                               AbstractFuelEditor.this.revalidate();\r
-                       }\r
-               });\r
-       }\r
-       \r
-}\r
diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/FuelsEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/FuelsEditor.java
deleted file mode 100644 (file)
index 61f7ca8..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.billkuker.rocketry.motorsim.visual.workbench;\r
-\r
-import java.awt.Frame;\r
-import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-\r
-import javax.swing.JFrame;\r
-import javax.swing.JMenuBar;\r
-\r
-import com.billkuker.rocketry.motorsim.Fuel;\r
-import com.billkuker.rocketry.motorsim.fuel.EditableFuel;\r
-import com.billkuker.rocketry.motorsim.fuel.PiecewiseLinearFuel;\r
-import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel;\r
-import com.billkuker.rocketry.motorsim.io.MotorIO;\r
-import com.billkuker.rocketry.motorsim.visual.FuelPanel;\r
-import com.billkuker.rocketry.motorsim.visual.MultiObjectEditor;\r
-import com.billkuker.rocketry.motorsim.visual.workbench.AbstractFuelEditor.EditablePSRFuel;\r
-\r
-public class FuelsEditor extends MultiObjectEditor<Fuel, AbstractFuelEditor> {\r
-\r
-       public FuelsEditor(Frame frame) {\r
-               super(frame, "Fuel");\r
-       }\r
-\r
-       @Override\r
-       public AbstractFuelEditor createEditor(Fuel o) {\r
-               if ( o instanceof PiecewiseLinearFuel ){\r
-                       return new LinearFuelEditor((PiecewiseLinearFuel)o);\r
-               } else if ( o instanceof EditableFuel ){\r
-                       return new SRFuelEditor(new EditablePSRFuel(SaintRobertFuel.Type.SI));\r
-               }\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-       public Fuel newObject() {\r
-               return new PiecewiseLinearFuel();\r
-       }\r
-\r
-       @Override\r
-       protected Fuel loadFromFile(File f) throws IOException {\r
-               return MotorIO.readFuel(new FileInputStream(f));\r
-       }\r
-\r
-       @Override\r
-       protected void saveToFile(Fuel o, File f) throws IOException {\r
-               MotorIO.writeFuel(o, new FileOutputStream(f));\r
-       }\r
-       \r
-       public static void main(String args[]){\r
-               JFrame f = new JFrame();\r
-               f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\r
-               FuelsEditor fe;\r
-               f.add(fe = new FuelsEditor(f));\r
-               JMenuBar b;\r
-               f.setJMenuBar(b = new JMenuBar());\r
-               b.add(fe.getMenu());\r
-               f.setSize(1024, 768);\r
-               f.show();\r
-       }\r
-\r
-}\r
diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/LinearFuelEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/LinearFuelEditor.java
deleted file mode 100644 (file)
index 65a255a..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-package com.billkuker.rocketry.motorsim.visual.workbench;
-
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.beans.PropertyChangeEvent;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Collections;
-import java.util.Vector;
-
-import javax.measure.quantity.Pressure;
-import javax.measure.quantity.Velocity;
-import javax.measure.unit.SI;
-import javax.swing.ButtonGroup;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.table.AbstractTableModel;
-
-import org.jscience.physics.amount.Amount;
-
-import com.billkuker.rocketry.motorsim.RocketScience;
-import com.billkuker.rocketry.motorsim.fuel.PiecewiseLinearFuel;
-import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel;
-import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel.Type;
-
-public class LinearFuelEditor extends AbstractFuelEditor {
-       private static final long serialVersionUID = 1L;
-
-       private static final NumberFormat nf = new DecimalFormat("##########.###");
-
-       private class Entry implements Comparable<Entry> {
-               Amount<Pressure> p = Amount.valueOf(0, RocketScience.UnitPreference.getUnitPreference().getPreferredUnit(RocketScience.PSI));
-               Amount<Velocity> v = Amount.valueOf(0, RocketScience.UnitPreference.getUnitPreference().getPreferredUnit(SI.METERS_PER_SECOND));
-
-               @Override
-               public int compareTo(Entry o) {
-                       return p.compareTo(o.p);
-               }
-       }
-
-       private class TM extends AbstractTableModel {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               public int getColumnCount() {
-                       return 2;
-               }
-
-               @Override
-               public int getRowCount() {
-                       return entries.size();
-               }
-
-               @Override
-               public String getColumnName(int col) {
-                       switch (col) {
-                       case 0:
-                               return "Pressure";
-                       case 1:
-                               return "Burn Rate";
-                       }
-                       return null;
-               }
-
-               @Override
-               public Object getValueAt(int rowIndex, int columnIndex) {
-                       Entry e = entries.get(rowIndex);
-                       switch (columnIndex) {
-                       case 0:
-                               return RocketScience.ammountToString(e.p);
-                       case 1:
-                               return RocketScience.ammountToString(e.v);
-                       }
-                       return null;
-               }
-
-               public boolean isCellEditable(int row, int col) {
-                       return true;
-               }
-
-               @SuppressWarnings("unchecked")
-               public void setValueAt(Object value, int row, int col) {
-                       Entry e = entries.get(row);
-                       try {
-                               switch (col) {
-                               case 0:
-                                       try {
-                                               e.p = (Amount<Pressure>) Amount.valueOf((String) value);
-                                       } catch ( Exception ee ){
-                                               double d = Double.parseDouble((String)value);
-                                               e.p = (Amount<Pressure>)Amount.valueOf(d, e.p.getUnit());
-                                       }
-                                       break;
-                               case 1:
-                                       try {
-                                               e.v = (Amount<Velocity>) Amount.valueOf((String) value);
-                                       } catch ( Exception ee ){
-                                               double d = Double.parseDouble((String)value);
-                                               e.v = (Amount<Velocity>)Amount.valueOf(d, e.v.getUnit());
-                                       }
-                                       break;
-                               }
-                       } catch (Exception ex) {
-                               ex.printStackTrace();
-                       }
-                       Collections.sort(entries);
-                       fireTableDataChanged();
-                       //f = new EditablePSRFuel(SaintRobertFuel.Type.NONSI);
-                       f.clear();
-                       for (Entry en : entries) {
-                               f.add(en.p, en.v);
-                       }
-                       f.firePropertyChange(new PropertyChangeEvent(f,"entries", null, null));
-
-                       update();
-
-               }
-
-               @Override
-               public void fireTableDataChanged() {
-                       super.fireTableDataChanged();
-               }
-
-       };
-       
-       private Vector<Entry> entries = new Vector<Entry>();
-       JPanel controls;
-       final PiecewiseLinearFuel f;
-
-       public LinearFuelEditor(PiecewiseLinearFuel f) {
-               super( f );
-               this.f = f;
-       }
-       
-       protected  Component getBurnrateEditComponent(){
-               final TM tm = new TM();
-
-               JSplitPane editBottom = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-               
-
-               JTable table = new JTable(tm);
-               JScrollPane scrollpane = new JScrollPane(table);
-               scrollpane.setMinimumSize(new Dimension(200, 200));
-               editBottom.setTopComponent(scrollpane);
-
-               
-               JButton add = new JButton("Add Data");
-               add.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               entries.add(new Entry());
-                               tm.fireTableDataChanged();
-                       }
-               });
-               controls = new JPanel();
-               controls.setPreferredSize(new Dimension(200, 50));
-               controls.setLayout(new FlowLayout());
-                       
-               controls.add(add);
-               
-               editBottom.setBottomComponent(controls);
-               
-               
-
-               editBottom.setDividerLocation(.8);
-               
-               return editBottom;
-       }
-
-       public static void main(String args[]) {
-               JFrame f = new JFrame();
-               f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-               f.setContentPane(new LinearFuelEditor(new PiecewiseLinearFuel()));
-               f.setSize(800, 600);
-               f.setVisible(true);
-
-       }
-
-}
index ad2ecf7e39023d56512da361502120498886f693..2dd251a3dd8cea55a8b7e184b03517cf90fb5d10 100644 (file)
@@ -427,7 +427,7 @@ public class MotorEditor extends JPanel implements PropertyChangeListener {
        public MotorEditor(Motor m, Collection<Fuel> fuels) {\r
                \r
                setLayout( new BorderLayout());\r
-               tabs = new JTabbedPane(JTabbedPane.BOTTOM);\r
+               tabs = new JTabbedPane(JTabbedPane.TOP);\r
                add(tabs, BorderLayout.CENTER);\r
 \r
                for ( Fuel f : fuels )\r
index 9c58d6e1a0992022451c1751575089385b54d950..5e9652f1ed4f4e59a07ce53cddc8059fb8180297 100644 (file)
@@ -1,12 +1,9 @@
 package com.billkuker.rocketry.motorsim.visual.workbench;\r
 \r
 import java.awt.BorderLayout;\r
-import java.awt.Dimension;\r
 import java.awt.FileDialog;\r
 import java.awt.event.ActionEvent;\r
 import java.awt.event.ActionListener;\r
-import java.beans.PropertyChangeEvent;\r
-import java.beans.PropertyChangeListener;\r
 import java.io.File;\r
 import java.io.FileInputStream;\r
 import java.io.FileOutputStream;\r
@@ -22,48 +19,44 @@ import javax.swing.JOptionPane;
 import javax.swing.JPanel;\r
 import javax.swing.JRadioButtonMenuItem;\r
 import javax.swing.JSeparator;\r
-import javax.swing.JSplitPane;\r
 import javax.swing.JTabbedPane;\r
-import javax.swing.JTree;\r
 import javax.swing.WindowConstants;\r
-import javax.swing.event.TreeSelectionEvent;\r
-import javax.swing.event.TreeSelectionListener;\r
-import javax.swing.tree.DefaultMutableTreeNode;\r
-import javax.swing.tree.TreePath;\r
-import javax.swing.tree.TreeSelectionModel;\r
 \r
 import com.billkuker.rocketry.motorsim.Burn;\r
 import com.billkuker.rocketry.motorsim.Fuel;\r
 import com.billkuker.rocketry.motorsim.Motor;\r
 import com.billkuker.rocketry.motorsim.RocketScience.UnitPreference;\r
 import com.billkuker.rocketry.motorsim.fuel.FuelResolver;\r
-import com.billkuker.rocketry.motorsim.fuel.PiecewiseLinearFuel;\r
-import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel;\r
 import com.billkuker.rocketry.motorsim.io.ENGExporter;\r
 import com.billkuker.rocketry.motorsim.io.MotorIO;\r
-import com.billkuker.rocketry.motorsim.visual.FuelPanel;\r
-import com.billkuker.rocketry.motorsim.visual.workbench.AbstractFuelEditor.EditablePSRFuel;\r
-import com.billkuker.rocketry.motorsim.visual.workbench.WorkbenchTreeModel.FuelEditNode;\r
-import com.billkuker.rocketry.motorsim.visual.workbench.WorkbenchTreeModel.FuelNode;\r
 \r
-public class MotorWorkbench extends JFrame implements TreeSelectionListener {\r
+import fuel.FuelsEditor;\r
+\r
+public class MotorWorkbench extends JFrame {\r
        private static final long serialVersionUID = 1L;\r
        \r
        private JPanel top;\r
-       private JSplitPane split;\r
-       private JTree tree;\r
        private JTabbedPane motors;\r
-       private JTabbedPane fuels;\r
-       private WorkbenchTreeModel tm;\r
        private MultiBurnChart mb;\r
        private JFrame allBurns;\r
+       \r
+       private JFrame fuelEditorFrame = new JFrame(){\r
+               private static final long serialVersionUID = 1L;\r
+               {\r
+                       setSize(1024, 768);\r
+                       add(fuelEditor = new FuelsEditor(this));\r
+                       JMenuBar b;\r
+                       setJMenuBar(b = new JMenuBar());\r
+                       b.add(fuelEditor.getMenu());\r
+                       setTitle("MotorSim - Fuel Editor");\r
+               }\r
+       };\r
+       private FuelsEditor fuelEditor;\r
 \r
        private HashMap<MotorEditor, File> e2f = new HashMap<MotorEditor, File>();\r
        private HashMap<File, MotorEditor> f2e = new HashMap<File, MotorEditor>();\r
 \r
        private HashMap<Motor, MotorEditor> m2e = new HashMap<Motor, MotorEditor>();\r
-\r
-       private static final int TREE_WIDTH = 200;\r
        \r
        public MotorWorkbench() {\r
                setTitle("MotorSim 1.0 RC1");\r
@@ -80,23 +73,8 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                allBurns.add(mb);\r
 \r
                motors = new JTabbedPane();\r
-               fuels = new JTabbedPane();\r
-\r
-               tree = new JTree(tm = new WorkbenchTreeModel());\r
-               tree.setCellRenderer(new WorkbenchTreeCellRenderer());\r
-               tree.getSelectionModel().setSelectionMode(\r
-                               TreeSelectionModel.SINGLE_TREE_SELECTION);\r
-               tree.setMinimumSize(new Dimension(TREE_WIDTH, 100));\r
-\r
-               // Listen for when the selection changes.\r
-               tree.addTreeSelectionListener(this);\r
-\r
-               split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, \r
-                               tree, motors);\r
-               split.setDividerLocation(TREE_WIDTH);\r
-               split.revalidate();\r
                \r
-               top.add(split, BorderLayout.CENTER);\r
+               top.add(motors, BorderLayout.CENTER);\r
                \r
                for ( Fuel f : FuelResolver.getFuelMap().values() ){\r
                        addFuel(f);\r
@@ -172,7 +150,6 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                                                                        public void actionPerformed(ActionEvent ev) {\r
                                                                                MotorEditor e = (MotorEditor) motors\r
                                                                                                .getSelectedComponent();\r
-                                                                               tm.removeMotor(e.getMotor());\r
                                                                                motors.remove(e);\r
                                                                                f2e.remove(e2f.get(e));\r
                                                                                e2f.remove(e);\r
@@ -232,40 +209,6 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                                                });\r
                                                \r
 \r
-                                               add(new JSeparator());\r
-                                               add(new JMenu("New Fuel"){\r
-                                                       private static final long serialVersionUID = 1L;\r
-                                                       {\r
-                                                               add(new JMenuItem("Saint-Robert") {\r
-                                                                       private static final long serialVersionUID = 1L;\r
-                                                                       {\r
-                                                                               addActionListener(new ActionListener() {\r
-                                                                                       @Override\r
-                                                                                       public void actionPerformed(ActionEvent arg0) {\r
-                                                                                               newFuel(new SRFuelEditor(new EditablePSRFuel(SaintRobertFuel.Type.SI)));\r
-                                                                                       }\r
-                                                                               });\r
-\r
-                                                                       }\r
-                                                               });\r
-                                                               add(new JMenuItem("Linear"){\r
-                                                                       private static final long serialVersionUID = 1L;\r
-                                                                       {\r
-                                                                               addActionListener(new ActionListener() {\r
-                                                                                       @Override\r
-                                                                                       public void actionPerformed(ActionEvent arg0) {\r
-                                                                                               newFuel(new LinearFuelEditor(new PiecewiseLinearFuel()));\r
-                                                                                       }\r
-                                                                               });\r
-\r
-                                                                       }\r
-                                                               });\r
-                                                       }\r
-                                               });\r
-\r
-                                               add(new JMenuItem("Save Fuel") {\r
-                                                       private static final long serialVersionUID = 1L;\r
-                                               });\r
                                                add(new JSeparator());\r
                                                add(new JMenuItem("Export .ENG"){\r
                                                        private static final long serialVersionUID = 1L;\r
@@ -326,7 +269,7 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                                add(new JMenu("View") {\r
                                        private static final long serialVersionUID = 1L;\r
                                        {\r
-                                               add(new JMenuItem("Show All Motors Graph") {\r
+                                               add(new JMenuItem("All Motors Graph") {\r
                                                        private static final long serialVersionUID = 1L;\r
                                                        {\r
                                                                addActionListener(new ActionListener() {\r
@@ -338,6 +281,18 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                                                                });\r
                                                        }\r
                                                });\r
+                                               add(new JMenuItem("Fuel Editor") {\r
+                                                       private static final long serialVersionUID = 1L;\r
+                                                       {\r
+                                                               addActionListener(new ActionListener() {\r
+                                                                       @Override\r
+                                                                       public void actionPerformed(ActionEvent arg0) {\r
+                                                                               fuelEditorFrame.setVisible(true);\r
+                                                                               fuelEditorFrame.toFront();\r
+                                                                       }\r
+                                                               });\r
+                                                       }\r
+                                               });\r
                                        }\r
                                });\r
                        }\r
@@ -347,33 +302,8 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
        private void addFuel(Fuel f){\r
                for ( MotorEditor e : m2e.values() )\r
                        e.addFuel(f);\r
-               FuelPanel fp = new FuelPanel(f);\r
-               FuelNode fn = tm.new FuelNode(fp, f);\r
-               tm.getFuels().add(fn);\r
-               tm.nodeStructureChanged(tm.getFuels());\r
-               fuels.addTab(f.getName(), fp);\r
        }\r
        \r
-       private void newFuel(final AbstractFuelEditor ed){\r
-               for ( MotorEditor e : m2e.values() )\r
-                       e.addFuel(ed.getFuel());\r
-               final FuelEditNode node = tm.new FuelEditNode(ed);\r
-               tm.getFuels().add(node);\r
-               tm.nodeStructureChanged(tm.getFuels());\r
-               fuels.addTab(ed.getFuel().getName(), ed);\r
-               ed.getFuel().addPropertyChangeListener(new PropertyChangeListener(){\r
-                       @Override\r
-                       public void propertyChange(PropertyChangeEvent evt) {\r
-                               if ( evt.getPropertyName().equals("Name")){\r
-                                       for ( int i = 0; i < fuels.getTabCount(); i++ ){\r
-                                               if ( fuels.getComponent(i) == ed ){\r
-                                                       fuels.setTitleAt(i, ed.getFuel().getName());\r
-                                                       tm.nodeChanged(node);\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }});\r
-       }\r
 \r
        private void save(Motor m, File f) {\r
                try {\r
@@ -386,7 +316,6 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
        }\r
 \r
        public void addMotor(Motor m, File f) {\r
-               tm.addMotor(m);\r
                MotorEditor e = new MotorEditor(m, FuelResolver.getFuelMap().values());\r
                e.addBurnWatcher(mb);\r
                String title;\r
@@ -401,40 +330,5 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener {
                motors.addTab(title, e);\r
        }\r
 \r
-       @Override\r
-       public void valueChanged(TreeSelectionEvent e) {\r
-               if (e.getPath().getLastPathComponent() instanceof FuelNode) {\r
-                       FuelNode fen = ((FuelNode) e.getPath().getLastPathComponent());\r
-                       fuels.setSelectedComponent(fen.getUserObject());\r
-                       split.setRightComponent(fuels);\r
-                       split.setDividerLocation(TREE_WIDTH);\r
-                       split.revalidate();\r
-               }\r
-\r
-               Motor m = getMotor(e.getPath());\r
-\r
-               if (m == null)\r
-                       return;\r
-\r
-               split.setRightComponent(motors);\r
-               split.setDividerLocation(TREE_WIDTH);\r
-               split.revalidate();\r
-               motors.setSelectedComponent(m2e.get(m));\r
-\r
-               if (e.getPath().getLastPathComponent() instanceof DefaultMutableTreeNode) {\r
-                       Object o = ((DefaultMutableTreeNode) e.getPath()\r
-                                       .getLastPathComponent()).getUserObject();\r
-                       m2e.get(m).focusOnObject(o);\r
-               }\r
-\r
-       }\r
-\r
-       private Motor getMotor(TreePath p) {\r
-               if (p.getLastPathComponent() instanceof WorkbenchTreeModel.MotorNode) {\r
-                       return ((WorkbenchTreeModel.MotorNode) p.getLastPathComponent())\r
-                                       .getUserObject();\r
-               } else if (p.getPath().length > 1)\r
-                       return getMotor(p.getParentPath());\r
-               return null;\r
-       }\r
+       \r
 }\r
diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/SRFuelEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/SRFuelEditor.java
deleted file mode 100644 (file)
index d4aa6d0..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-package com.billkuker.rocketry.motorsim.visual.workbench;
-
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.beans.PropertyChangeEvent;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Collections;
-import java.util.Vector;
-
-import javax.measure.quantity.Pressure;
-import javax.swing.ButtonGroup;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.swing.table.AbstractTableModel;
-
-import org.jscience.physics.amount.Amount;
-
-import com.billkuker.rocketry.motorsim.RocketScience;
-import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel;
-import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel.Type;
-
-public class SRFuelEditor extends AbstractFuelEditor {
-       private static final long serialVersionUID = 1L;
-
-       private static final NumberFormat nf = new DecimalFormat("##########.###");
-
-       private class Entry implements Comparable<Entry> {
-               Amount<Pressure> p = Amount.valueOf(0, RocketScience.UnitPreference.getUnitPreference().getPreferredUnit(RocketScience.PSI));
-               double a;
-               double n;
-
-               @Override
-               public int compareTo(Entry o) {
-                       return p.compareTo(o.p);
-               }
-       }
-
-       private class TM extends AbstractTableModel {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               public int getColumnCount() {
-                       return 3;
-               }
-
-               @Override
-               public int getRowCount() {
-                       return entries.size();
-               }
-
-               @Override
-               public String getColumnName(int col) {
-                       switch (col) {
-                       case 0:
-                               return "Pressure";
-                       case 1:
-                               return "Coefficient (a)";
-                       case 2:
-                               return "Exponent (n)";
-                       }
-                       return null;
-               }
-
-               @Override
-               public Object getValueAt(int rowIndex, int columnIndex) {
-                       Entry e = entries.get(rowIndex);
-                       switch (columnIndex) {
-                       case 0:
-                               //Format like 100 psi or 4.8 Mpa
-                               return nf.format(e.p.doubleValue(e.p.getUnit())) + " " + e.p.getUnit();
-                       case 1:
-                               return e.a;
-                       case 2:
-                               return e.n;
-                       }
-                       return null;
-               }
-
-               public boolean isCellEditable(int row, int col) {
-                       return true;
-               }
-
-               @SuppressWarnings("unchecked")
-               public void setValueAt(Object value, int row, int col) {
-                       Entry e = entries.get(row);
-                       try {
-                               switch (col) {
-                               case 0:
-                                       try {
-                                               e.p = (Amount<Pressure>) Amount.valueOf((String) value);
-                                       } catch ( Exception ee ){
-                                               double d = Double.parseDouble((String)value);
-                                               e.p = (Amount<Pressure>)Amount.valueOf(d, e.p.getUnit());
-                                       }
-                                       break;
-                               case 1:
-                                       e.a = Double.valueOf((String) value);
-                                       break;
-                               case 2:
-                                       e.n = Double.valueOf((String) value);
-                               }
-                       } catch (Exception ex) {
-                               ex.printStackTrace();
-                       }
-                       Collections.sort(entries);
-                       fireTableDataChanged();
-                       //f = new EditablePSRFuel(SaintRobertFuel.Type.NONSI);
-                       f.clear();
-                       for (Entry en : entries) {
-                               f.add(en.p, en.a, en.n);
-                       }
-                       f.firePropertyChange(new PropertyChangeEvent(f,"entries", null, null));
-
-                       update();
-
-               }
-
-               @Override
-               public void fireTableDataChanged() {
-                       super.fireTableDataChanged();
-               }
-
-       };
-       
-       private Vector<Entry> entries = new Vector<Entry>();
-       JPanel controls;
-       final EditablePSRFuel f;
-
-       public SRFuelEditor(EditablePSRFuel f) {
-               
-               super( f);
-               
-               this.f = f;
-               
-       }
-       
-       protected  Component getBurnrateEditComponent(){
-               final TM tm = new TM();
-
-               JSplitPane editBottom = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
-               
-
-               JTable table = new JTable(tm);
-               JScrollPane scrollpane = new JScrollPane(table);
-               scrollpane.setMinimumSize(new Dimension(200, 200));
-               editBottom.setTopComponent(scrollpane);
-
-               
-               JButton add = new JButton("Add Data");
-               add.addActionListener(new ActionListener() {
-                       @Override
-                       public void actionPerformed(ActionEvent e) {
-                               entries.add(new Entry());
-                               tm.fireTableDataChanged();
-                       }
-               });
-               controls = new JPanel();
-               controls.setPreferredSize(new Dimension(200, 50));
-               controls.setLayout(new FlowLayout());
-                       
-               controls.add(add);
-
-               
-               final JRadioButton si, nonsi;
-               ButtonGroup type = new ButtonGroup();
-               JPanel radio = new JPanel();
-               radio.add(si = new JRadioButton("SI"));
-               radio.add(nonsi = new JRadioButton("NonSI"));
-               controls.add(radio);
-               type.add(si);
-               type.add(nonsi);
-
-               si.setSelected(true);
-               
-               si.addChangeListener(new ChangeListener(){
-                       @Override
-                       public void stateChanged(ChangeEvent e) {
-                               if ( si.isSelected() ){
-                                       System.err.println("SI");
-                                       f.setType(Type.SI);
-                               } else {
-                                       System.err.println("NONSI");
-                                       f.setType(Type.NONSI);
-                               }
-                               update();
-                       }});
-               
-               editBottom.setBottomComponent(controls);
-               
-               
-
-               editBottom.setDividerLocation(.8);
-               
-               return editBottom;
-       }
-
-       public static void main(String args[]) {
-               JFrame f = new JFrame();
-               f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-               f.setContentPane(new SRFuelEditor(new EditablePSRFuel(SaintRobertFuel.Type.SI)));
-               f.setSize(800, 600);
-               f.setVisible(true);
-
-       }
-
-}
diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeCellRenderer.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeCellRenderer.java
deleted file mode 100644 (file)
index ae3e3a6..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.billkuker.rocketry.motorsim.visual.workbench;
-
-import java.awt.Color;
-import java.awt.Component;
-
-import javax.swing.JTree;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeCellRenderer;
-
-import com.billkuker.rocketry.motorsim.Motor;
-import com.billkuker.rocketry.motorsim.Validating;
-import com.billkuker.rocketry.motorsim.Validating.ValidationException;
-import com.billkuker.rocketry.motorsim.visual.workbench.WorkbenchTreeModel.FuelNode;
-
-public class WorkbenchTreeCellRenderer extends DefaultTreeCellRenderer {
-       private static final long serialVersionUID = 1L;
-
-       @Override
-       public Component getTreeCellRendererComponent(JTree tree, final Object value,
-                       boolean sel, boolean expanded, boolean leaf, int row,
-                       boolean hasFocus) {
-
-               String tip = null;
-               setTextNonSelectionColor(Color.black);
-               setTextSelectionColor(Color.white);
-               
-               Object part = null;
-               if (value instanceof DefaultMutableTreeNode) {
-                       part = ((DefaultMutableTreeNode) value).getUserObject();
-               }
-               
-               if ( part instanceof Validating ){
-                               try {
-                                       ((Validating)part).validate();
-                               } catch (ValidationException e) {
-                                       setTextSelectionColor(Color.RED);
-                                       setTextNonSelectionColor(Color.RED);
-                                       setToolTipText(e.getMessage());
-                                       tip = e.getMessage();
-                               }
-               }
-               
-               super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
-                               row, hasFocus);
-
-               if (part instanceof Motor) {
-                       setText(((Motor) part).getName());
-               } else if ( value instanceof FuelNode ){
-                       setText(((FuelNode)value).getFuel().getName());
-               } else if ( part instanceof String ) {
-                       setText((String)part);
-               } else if ( part == null ) {
-                       setText("");
-               } else {
-                       setText(part.getClass().getSimpleName());
-               }
-               setToolTipText(tip);
-               
-
-
-               return this;
-       }
-}
diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeModel.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/WorkbenchTreeModel.java
deleted file mode 100644 (file)
index 1db767f..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-package com.billkuker.rocketry.motorsim.visual.workbench;
-
-import java.awt.Component;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.Enumeration;
-
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.TreeNode;
-
-import com.billkuker.rocketry.motorsim.ChangeListening;
-import com.billkuker.rocketry.motorsim.Fuel;
-import com.billkuker.rocketry.motorsim.Motor;
-import com.billkuker.rocketry.motorsim.grain.MultiGrain;
-
-public class WorkbenchTreeModel extends DefaultTreeModel {
-
-       private static final long serialVersionUID = 1L;
-       
-       //TreeNode root = new DefaultMutableTreeNode("Root");
-       DefaultMutableTreeNode motors = new DefaultMutableTreeNode("All Motors");
-       DefaultMutableTreeNode fuel = new DefaultMutableTreeNode("Fuels");
-       
-       public class MultiGrainNode extends PartNode{
-               private static final long serialVersionUID = 1L;
-               public MultiGrainNode(MultiGrain part) {
-                       super(part);
-                       setAllowsChildren(true);
-                       add(new PartNode(part.getGrain()));
-               }
-               @Override
-               public void propertyChange(PropertyChangeEvent e) {
-                       if ( e.getPropertyName().equals("Grain")){
-                               remove(0);
-                               add(new PartNode(((MultiGrain)getUserObject()).getGrain()));
-                               nodesChanged(this, new int[]{0});
-                       }
-                       super.propertyChange(e);
-               }
-       }
-       
-       public class FuelNode extends DefaultMutableTreeNode{
-               private static final long serialVersionUID = 1L;
-               Fuel f;
-               public FuelNode(Component c, Fuel f){
-                       super(c, false);
-                       this.f = f;
-               }
-               
-               @Override
-               public Component getUserObject(){
-                       return (Component)super.getUserObject();
-               }
-               
-               public Fuel getFuel(){
-                       return f;
-               }
-       }
-       
-       public class FuelEditNode extends FuelNode {
-               private static final long serialVersionUID = 1L;
-
-               public FuelEditNode(AbstractFuelEditor sr){
-                       super(sr, sr.getFuel());
-                       sr.getFuel().addPropertyChangeListener(new PropertyChangeListener(){
-
-                               @Override
-                               public void propertyChange(PropertyChangeEvent evt) {
-                                       nodeChanged(FuelEditNode.this);
-                               }});
-               }
-               
-               @Override
-               public AbstractFuelEditor getUserObject(){
-                       return (AbstractFuelEditor)super.getUserObject();
-               }
-
-       }
-
-       public class PartNode extends DefaultMutableTreeNode implements PropertyChangeListener {
-               private static final long serialVersionUID = 1L;
-
-               public PartNode(Object part) {
-                       super(part, false);
-                       if (part instanceof ChangeListening.Subject) {
-                               ((ChangeListening.Subject) part).addPropertyChangeListener(this);
-                       }
-               }
-       
-               @Override
-               public void propertyChange(PropertyChangeEvent e) {
-                       nodeChanged(this);
-               }
-       
-       }
-       
-       public class MotorNode extends PartNode implements PropertyChangeListener {
-               private static final long serialVersionUID = 1L;
-               Motor motor;
-               PartNode cn, nn, gn, fn;
-
-               public MotorNode(Motor m) {
-                       super(m);
-                       setAllowsChildren(true);
-                       motor = m;
-                       add( cn = new PartNode(m.getChamber()));
-                       add( nn = new PartNode(m.getNozzle()));
-                       if ( m.getGrain() instanceof MultiGrain ){
-                               gn = new MultiGrainNode(((MultiGrain)m.getGrain()));
-                       } else {
-                               gn = new PartNode(m.getGrain());
-                       }
-                       add(gn);
-                       if (m instanceof ChangeListening.Subject) {
-                               ((ChangeListening.Subject) m).addPropertyChangeListener(this);
-                       }
-               }
-               
-               @Override
-               public Motor getUserObject(){
-                       return (Motor)super.getUserObject();
-               }
-
-               @Override
-               public void propertyChange(PropertyChangeEvent e) {
-                               nodeChanged(this);
-                       super.propertyChange(e);
-               }
-
-       }
-
-       public WorkbenchTreeModel() {
-               super(new DefaultMutableTreeNode("Root"), true);
-               getRoot().add(motors);
-               getRoot().add(fuel);
-       }
-       
-       @Override
-       public DefaultMutableTreeNode getRoot(){
-               return (DefaultMutableTreeNode)super.getRoot();
-       }
-       
-       public DefaultMutableTreeNode getMotors(){
-               return motors;
-       }
-       
-       public DefaultMutableTreeNode getFuels(){
-               return fuel;
-       }
-       
-       public void addMotor(Motor m){
-               motors.add(new MotorNode(m));
-               nodesWereInserted(motors, new int[]{motors.getChildCount()-1});
-               
-       }
-       
-       @SuppressWarnings("unchecked")
-       public void removeMotor(Motor m){
-               Enumeration<TreeNode> e = motors.children();
-               while ( e.hasMoreElements() ){
-                       TreeNode n = e.nextElement();
-                       if ( n instanceof MotorNode ){
-                               if ( ((MotorNode)n).getUserObject() == m ){
-                                       removeNodeFromParent((MotorNode)n);
-                               }
-                       }
-               }
-       }
-
-}
diff --git a/gui/fuel/AbstractFuelEditor.java b/gui/fuel/AbstractFuelEditor.java
new file mode 100644 (file)
index 0000000..23da52a
--- /dev/null
@@ -0,0 +1,81 @@
+package fuel;\r
+\r
+import java.awt.Component;\r
+\r
+import javax.measure.quantity.Pressure;\r
+import javax.measure.quantity.Velocity;\r
+import javax.measure.unit.SI;\r
+import javax.swing.JSplitPane;\r
+import javax.swing.SwingUtilities;\r
+\r
+import org.jscience.physics.amount.Amount;\r
+\r
+import com.billkuker.rocketry.motorsim.Fuel;\r
+import com.billkuker.rocketry.motorsim.visual.Chart;\r
+import com.billkuker.rocketry.motorsim.visual.Editor;\r
+\r
+public abstract class AbstractFuelEditor  extends JSplitPane {\r
+       private static final long serialVersionUID = 1L;\r
+\r
+       private final JSplitPane editParent;\r
+       private final JSplitPane editTop;\r
+       private final Fuel f;\r
+       private Chart<Pressure, Velocity> burnRate;\r
+       \r
+       public AbstractFuelEditor(Fuel f){\r
+               super(HORIZONTAL_SPLIT);\r
+               this.f = f;\r
+               \r
+               editTop = new JSplitPane(JSplitPane.VERTICAL_SPLIT);\r
+               editTop.setTopComponent(new Editor(f));\r
+               editTop.setBottomComponent(new Editor(f.getCombustionProduct()));\r
+               \r
+               editParent = new JSplitPane(JSplitPane.VERTICAL_SPLIT);\r
+               setLeftComponent(editParent);\r
+               editParent.setTopComponent(editTop);\r
+               editParent.setBottomComponent(getBurnrateEditComponent());\r
+               \r
+               setResizeWeight(0);\r
+               setDividerLocation(.3);\r
+               editParent.setDividerLocation(.5);\r
+               editTop.setDividerLocation(.5);\r
+               editParent.resetToPreferredSizes();\r
+               revalidate();\r
+\r
+               update();\r
+       }\r
+       \r
+       protected abstract Component getBurnrateEditComponent();\r
+       \r
+       public Fuel getFuel(){\r
+               return f;\r
+       }\r
+       \r
+\r
+\r
+       protected void update() {\r
+               SwingUtilities.invokeLater(new Runnable() {\r
+\r
+                       @Override\r
+                       public void run() {\r
+                               editTop.setTopComponent(new Editor(f));\r
+                               editTop.setBottomComponent(new Editor(f.getCombustionProduct()));\r
+                               if (burnRate != null)\r
+                                       AbstractFuelEditor.this.remove(burnRate);\r
+                               try {\r
+                                       burnRate = new Chart<Pressure, Velocity>(\r
+                                                       SI.MEGA(SI.PASCAL), SI.MILLIMETER.divide(SI.SECOND)\r
+                                                                       .asType(Velocity.class), f, "burnRate");\r
+                               } catch (NoSuchMethodException e) {\r
+                                       throw new Error(e);\r
+                               }\r
+                               burnRate.setDomain(burnRate.new IntervalDomain(Amount.valueOf(\r
+                                               0, SI.MEGA(SI.PASCAL)), Amount.valueOf(11, SI\r
+                                               .MEGA(SI.PASCAL)), 50));\r
+                               AbstractFuelEditor.this.setRightComponent(burnRate);\r
+                               AbstractFuelEditor.this.revalidate();\r
+                       }\r
+               });\r
+       }\r
+       \r
+}\r
diff --git a/gui/fuel/FuelsEditor.java b/gui/fuel/FuelsEditor.java
new file mode 100644 (file)
index 0000000..4d599f6
--- /dev/null
@@ -0,0 +1,87 @@
+package fuel;\r
+\r
+import java.awt.Frame;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+import java.io.IOException;\r
+\r
+import javax.swing.JFrame;\r
+import javax.swing.JMenuBar;\r
+\r
+import com.billkuker.rocketry.motorsim.Fuel;\r
+import com.billkuker.rocketry.motorsim.fuel.editable.EditablePiecewiseLinearFuel;\r
+import com.billkuker.rocketry.motorsim.fuel.editable.EditablePiecewiseSaintRobertFuel;\r
+import com.billkuker.rocketry.motorsim.io.MotorIO;\r
+import com.billkuker.rocketry.motorsim.visual.MultiObjectEditor;\r
+\r
+public class FuelsEditor extends MultiObjectEditor<Fuel, AbstractFuelEditor> {\r
+\r
+       private static final long serialVersionUID = 1L;\r
+\r
+       public FuelsEditor(Frame frame) {\r
+               super(frame, "Fuel");\r
+               addCreator(new ObjectCreator() {\r
+                       @Override\r
+                       public Fuel newObject() {\r
+                               return new EditablePiecewiseLinearFuel();\r
+                       }\r
+\r
+                       @Override\r
+                       public String getName() {\r
+                               return "Linear Fuel";\r
+                       }\r
+               });\r
+               addCreator(new ObjectCreator() {\r
+                       @Override\r
+                       public Fuel newObject() {\r
+                               return new EditablePiecewiseSaintRobertFuel();\r
+                       }\r
+\r
+                       @Override\r
+                       public String getName() {\r
+                               return "Saint Robert Fuel";\r
+                       }\r
+               });\r
+       }\r
+\r
+       @Override\r
+       public AbstractFuelEditor createEditor(Fuel o) {\r
+               if ( o instanceof EditablePiecewiseLinearFuel ){\r
+                       return new LinearFuelEditor((EditablePiecewiseLinearFuel)o);\r
+               } else if ( o instanceof EditablePiecewiseSaintRobertFuel ){\r
+                       return new SRFuelEditor((EditablePiecewiseSaintRobertFuel)o);\r
+               }\r
+               return null;\r
+       }\r
+\r
+       @Override\r
+       public Fuel newObject() {\r
+               return new EditablePiecewiseLinearFuel();\r
+       }\r
+\r
+       @Override\r
+       protected Fuel loadFromFile(File f) throws IOException {\r
+               Fuel fuel =  MotorIO.readFuel(new FileInputStream(f));\r
+               return fuel;\r
+       }\r
+\r
+       @Override\r
+       protected void saveToFile(Fuel o, File f) throws IOException {\r
+               MotorIO.writeFuel(o, new FileOutputStream(f));\r
+       }\r
+       \r
+       @SuppressWarnings("deprecation")\r
+       public static void main(String args[]){\r
+               JFrame f = new JFrame();\r
+               f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);\r
+               FuelsEditor fe;\r
+               f.add(fe = new FuelsEditor(f));\r
+               JMenuBar b;\r
+               f.setJMenuBar(b = new JMenuBar());\r
+               b.add(fe.getMenu());\r
+               f.setSize(1024, 768);\r
+               f.show();\r
+       }\r
+\r
+}\r
diff --git a/gui/fuel/LinearFuelEditor.java b/gui/fuel/LinearFuelEditor.java
new file mode 100644 (file)
index 0000000..93aff74
--- /dev/null
@@ -0,0 +1,187 @@
+package fuel;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.measure.quantity.Pressure;
+import javax.measure.quantity.Velocity;
+import javax.measure.unit.SI;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.table.AbstractTableModel;
+
+import org.jscience.physics.amount.Amount;
+
+import com.billkuker.rocketry.motorsim.RocketScience;
+import com.billkuker.rocketry.motorsim.fuel.editable.EditablePiecewiseLinearFuel;
+
+public class LinearFuelEditor extends AbstractFuelEditor {
+       private static final long serialVersionUID = 1L;
+
+       private class Entry implements Comparable<Entry> {
+               Amount<Pressure> p = Amount.valueOf(0, RocketScience.UnitPreference.getUnitPreference().getPreferredUnit(RocketScience.PSI));
+               Amount<Velocity> v = Amount.valueOf(0, RocketScience.UnitPreference.getUnitPreference().getPreferredUnit(SI.METERS_PER_SECOND));
+
+               @Override
+               public int compareTo(Entry o) {
+                       return p.compareTo(o.p);
+               }
+       }
+
+       private class TM extends AbstractTableModel {
+               private static final long serialVersionUID = 1L;
+
+               @Override
+               public int getColumnCount() {
+                       return 2;
+               }
+
+               @Override
+               public int getRowCount() {
+                       return entries.size();
+               }
+
+               @Override
+               public String getColumnName(int col) {
+                       switch (col) {
+                       case 0:
+                               return "Pressure";
+                       case 1:
+                               return "Burn Rate";
+                       }
+                       return null;
+               }
+
+               @Override
+               public Object getValueAt(int rowIndex, int columnIndex) {
+                       Entry e = entries.get(rowIndex);
+                       switch (columnIndex) {
+                       case 0:
+                               return RocketScience.ammountToString(e.p);
+                       case 1:
+                               return RocketScience.ammountToString(e.v);
+                       }
+                       return null;
+               }
+
+               public boolean isCellEditable(int row, int col) {
+                       return true;
+               }
+
+               @SuppressWarnings("unchecked")
+               public void setValueAt(Object value, int row, int col) {
+                       Entry e = entries.get(row);
+                       try {
+                               switch (col) {
+                               case 0:
+                                       try {
+                                               e.p = (Amount<Pressure>) Amount.valueOf((String) value);
+                                       } catch ( Exception ee ){
+                                               double d = Double.parseDouble((String)value);
+                                               e.p = (Amount<Pressure>)Amount.valueOf(d, e.p.getUnit());
+                                       }
+                                       break;
+                               case 1:
+                                       try {
+                                               e.v = (Amount<Velocity>) Amount.valueOf((String) value);
+                                       } catch ( Exception ee ){
+                                               double d = Double.parseDouble((String)value);
+                                               e.v = (Amount<Velocity>)Amount.valueOf(d, e.v.getUnit());
+                                       }
+                                       break;
+                               }
+                       } catch (Exception ex) {
+                               ex.printStackTrace();
+                       }
+                       Collections.sort(entries);
+                       fireTableDataChanged();
+                       //f = new EditablePSRFuel(SaintRobertFuel.Type.NONSI);
+                       f.clear();
+                       for (Entry en : entries) {
+                               f.add(en.p, en.v);
+                       }
+                       f.firePropertyChange(new PropertyChangeEvent(f,"entries", null, null));
+
+                       update();
+
+               }
+
+               @Override
+               public void fireTableDataChanged() {
+                       super.fireTableDataChanged();
+               }
+
+       };
+       
+       private Vector<Entry> entries = new Vector<Entry>();
+       JPanel controls;
+       final EditablePiecewiseLinearFuel f;
+
+       public LinearFuelEditor(EditablePiecewiseLinearFuel f) {
+               super( f );
+               this.f = f;
+               for ( Map.Entry<Amount<Pressure>, Amount<Velocity>> e : f.getEntries().entrySet() ){
+                       Entry n = new Entry();
+                       n.p = e.getKey();
+                       n.v = e.getValue();
+                       entries.add(n);
+               }
+               Collections.sort(entries);
+       }
+       
+       protected  Component getBurnrateEditComponent(){
+               final TM tm = new TM();
+
+               JSplitPane editBottom = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+               
+
+               JTable table = new JTable(tm);
+               JScrollPane scrollpane = new JScrollPane(table);
+               scrollpane.setMinimumSize(new Dimension(200, 200));
+               editBottom.setTopComponent(scrollpane);
+
+               
+               JButton add = new JButton("Add Data");
+               add.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               entries.add(new Entry());
+                               tm.fireTableDataChanged();
+                       }
+               });
+               controls = new JPanel();
+               controls.setPreferredSize(new Dimension(200, 50));
+               controls.setLayout(new FlowLayout());
+                       
+               controls.add(add);
+               
+               editBottom.setBottomComponent(controls);
+               
+               
+
+               editBottom.setDividerLocation(.8);
+               
+               return editBottom;
+       }
+
+       public static void main(String args[]) {
+               JFrame f = new JFrame();
+               f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+               f.setContentPane(new LinearFuelEditor(new EditablePiecewiseLinearFuel()));
+               f.setSize(800, 600);
+               f.setVisible(true);
+
+       }
+
+}
diff --git a/gui/fuel/SRFuelEditor.java b/gui/fuel/SRFuelEditor.java
new file mode 100644 (file)
index 0000000..53e3dd4
--- /dev/null
@@ -0,0 +1,223 @@
+package fuel;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.Collections;
+import java.util.Vector;
+
+import javax.measure.quantity.Pressure;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.table.AbstractTableModel;
+
+import org.jscience.physics.amount.Amount;
+
+import com.billkuker.rocketry.motorsim.RocketScience;
+import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel.Type;
+import com.billkuker.rocketry.motorsim.fuel.editable.EditablePiecewiseSaintRobertFuel;
+
+public class SRFuelEditor extends AbstractFuelEditor {
+       private static final long serialVersionUID = 1L;
+
+       private static final NumberFormat nf = new DecimalFormat("##########.###");
+
+       private class Entry implements Comparable<Entry> {
+               Amount<Pressure> p = Amount.valueOf(0, RocketScience.UnitPreference.getUnitPreference().getPreferredUnit(RocketScience.PSI));
+               double a;
+               double n;
+
+               @Override
+               public int compareTo(Entry o) {
+                       return p.compareTo(o.p);
+               }
+       }
+
+       private class TM extends AbstractTableModel {
+               private static final long serialVersionUID = 1L;
+
+               @Override
+               public int getColumnCount() {
+                       return 3;
+               }
+
+               @Override
+               public int getRowCount() {
+                       return entries.size();
+               }
+
+               @Override
+               public String getColumnName(int col) {
+                       switch (col) {
+                       case 0:
+                               return "Pressure";
+                       case 1:
+                               return "Coefficient (a)";
+                       case 2:
+                               return "Exponent (n)";
+                       }
+                       return null;
+               }
+
+               @Override
+               public Object getValueAt(int rowIndex, int columnIndex) {
+                       Entry e = entries.get(rowIndex);
+                       switch (columnIndex) {
+                       case 0:
+                               //Format like 100 psi or 4.8 Mpa
+                               return nf.format(e.p.doubleValue(e.p.getUnit())) + " " + e.p.getUnit();
+                       case 1:
+                               return e.a;
+                       case 2:
+                               return e.n;
+                       }
+                       return null;
+               }
+
+               public boolean isCellEditable(int row, int col) {
+                       return true;
+               }
+
+               @SuppressWarnings("unchecked")
+               public void setValueAt(Object value, int row, int col) {
+                       Entry e = entries.get(row);
+                       try {
+                               switch (col) {
+                               case 0:
+                                       try {
+                                               e.p = (Amount<Pressure>) Amount.valueOf((String) value);
+                                       } catch ( Exception ee ){
+                                               double d = Double.parseDouble((String)value);
+                                               e.p = (Amount<Pressure>)Amount.valueOf(d, e.p.getUnit());
+                                       }
+                                       break;
+                               case 1:
+                                       e.a = Double.valueOf((String) value);
+                                       break;
+                               case 2:
+                                       e.n = Double.valueOf((String) value);
+                               }
+                       } catch (Exception ex) {
+                               ex.printStackTrace();
+                       }
+                       Collections.sort(entries);
+                       fireTableDataChanged();
+                       //f = new EditablePSRFuel(SaintRobertFuel.Type.NONSI);
+                       f.clear();
+                       for (Entry en : entries) {
+                               f.add(en.p, en.a, en.n);
+                       }
+                       f.firePropertyChange(new PropertyChangeEvent(f,"entries", null, null));
+
+                       update();
+
+               }
+
+               @Override
+               public void fireTableDataChanged() {
+                       super.fireTableDataChanged();
+               }
+
+       };
+       
+       private Vector<Entry> entries = new Vector<Entry>();
+       JPanel controls;
+       final EditablePiecewiseSaintRobertFuel f;
+
+       public SRFuelEditor(EditablePiecewiseSaintRobertFuel f) {
+               super( f);
+               this.f = f;
+               
+               for ( Amount<Pressure> p : f.getAMap().keySet() ){
+                       Entry e = new Entry();
+                       e.a = f.getAMap().get(p);
+                       e.n = f.getNMap().get(p);
+                       entries.add(e);
+               }
+               Collections.sort(entries);
+               
+       }
+       
+       protected  Component getBurnrateEditComponent(){
+               final TM tm = new TM();
+
+               JSplitPane editBottom = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
+               
+
+               JTable table = new JTable(tm);
+               JScrollPane scrollpane = new JScrollPane(table);
+               scrollpane.setMinimumSize(new Dimension(200, 200));
+               editBottom.setTopComponent(scrollpane);
+
+               
+               JButton add = new JButton("Add Data");
+               add.addActionListener(new ActionListener() {
+                       @Override
+                       public void actionPerformed(ActionEvent e) {
+                               entries.add(new Entry());
+                               tm.fireTableDataChanged();
+                       }
+               });
+               controls = new JPanel();
+               controls.setPreferredSize(new Dimension(200, 50));
+               controls.setLayout(new FlowLayout());
+                       
+               controls.add(add);
+
+               
+               final JRadioButton si, nonsi;
+               ButtonGroup type = new ButtonGroup();
+               JPanel radio = new JPanel();
+               radio.add(si = new JRadioButton("SI"));
+               radio.add(nonsi = new JRadioButton("NonSI"));
+               controls.add(radio);
+               type.add(si);
+               type.add(nonsi);
+
+               si.setSelected(true);
+               
+               si.addChangeListener(new ChangeListener(){
+                       @Override
+                       public void stateChanged(ChangeEvent e) {
+                               if ( si.isSelected() ){
+                                       System.err.println("SI");
+                                       f.setType(Type.SI);
+                               } else {
+                                       System.err.println("NONSI");
+                                       f.setType(Type.NONSI);
+                               }
+                               update();
+                       }});
+               
+               editBottom.setBottomComponent(controls);
+               
+               
+
+               editBottom.setDividerLocation(.8);
+               
+               return editBottom;
+       }
+
+       public static void main(String args[]) {
+               JFrame f = new JFrame();
+               f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+               f.setContentPane(new SRFuelEditor(new EditablePiecewiseSaintRobertFuel()));
+               f.setSize(800, 600);
+               f.setVisible(true);
+
+       }
+
+}