+++ /dev/null
-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
+++ /dev/null
-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
+++ /dev/null
-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);
-
- }
-
-}
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
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
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
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
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
});\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
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
});\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
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
}\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
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
+++ /dev/null
-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);
-
- }
-
-}
+++ /dev/null
-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;
- }
-}
+++ /dev/null
-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);
- }
- }
- }
- }
-
-}
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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);
+
+ }
+
+}
--- /dev/null
+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);
+
+ }
+
+}