From b92070d9ad05a537fe1c3395feb97a4cd1ee670c Mon Sep 17 00:00:00 2001 From: Bill Kuker Date: Fri, 12 Nov 2010 01:36:52 +0000 Subject: [PATCH] Make fuel editors take fuel in ctor --- .../motorsim/visual/MultiObjectEditor.java | 260 ++++++++++++++++++ .../visual/workbench/FuelsEditor.java | 64 +++++ .../visual/workbench/LinearFuelEditor.java | 11 +- .../visual/workbench/MotorWorkbench.java | 7 +- .../visual/workbench/SRFuelEditor.java | 8 +- 5 files changed, 337 insertions(+), 13 deletions(-) create mode 100644 gui/com/billkuker/rocketry/motorsim/visual/MultiObjectEditor.java create mode 100644 gui/com/billkuker/rocketry/motorsim/visual/workbench/FuelsEditor.java diff --git a/gui/com/billkuker/rocketry/motorsim/visual/MultiObjectEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/MultiObjectEditor.java new file mode 100644 index 0000000..ec9e839 --- /dev/null +++ b/gui/com/billkuker/rocketry/motorsim/visual/MultiObjectEditor.java @@ -0,0 +1,260 @@ +package com.billkuker.rocketry.motorsim.visual; +import java.awt.Component; +import java.awt.FileDialog; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JOptionPane; +import javax.swing.JTabbedPane; + +import org.apache.log4j.Logger; + + +public abstract class MultiObjectEditor extends JTabbedPane { + + private static final long serialVersionUID = 1L; + + private static final Logger log = Logger.getLogger(MultiObjectEditor.class); + + private final Frame frame; + + private final String noun; + + private final Map objectToEditor = new HashMap(); + private final Map editorToObject = new HashMap(); + private final Map fileToEditor = new HashMap(); + private final Map editorToFile = new HashMap(); + + private final Set dirty = new HashSet(); + + public MultiObjectEditor(final Frame frame, final String noun){ + this.frame = frame; + this.noun = " " + noun.trim(); + } + + public final void dirty(final OBJECT o){ + if ( !dirty.contains(o) ) + setTitleAt(indexOfComponent(objectToEditor.get(o)), "*" + getTitleAt(indexOfComponent(objectToEditor.get(o)))); + dirty.add(o); + } + + public final void dirty(final EDITOR e){ + dirty(editorToObject.get(e)); + } + + private final void undirty(final OBJECT o){ + if ( dirty.contains(o) ) + setTitleAt(indexOfComponent(objectToEditor.get(o)), getTitleAt(indexOfComponent(objectToEditor.get(o))).replaceAll("^\\*", "")); + dirty.remove(o); + } + + public final JMenu getMenu(){ + JMenu ret = new JMenu("File"); + for ( JMenuItem i : getMenuItems() ) + ret.add(i); + return ret; + } + + private void menuNew(){ + add(newObject()); + } + + @SuppressWarnings("unchecked") + @Override + public EDITOR getSelectedComponent(){ + return (EDITOR)super.getSelectedComponent(); + } + + private void close(){ + EDITOR e = getSelectedComponent(); + OBJECT o = editorToObject.get(e); + File f = editorToFile.get(e); + + if ( dirty.contains(o) ){ + int response = JOptionPane.showConfirmDialog(this, "Object is unsaved. Save Before Closing?", "Confirm", JOptionPane.YES_NO_CANCEL_OPTION); + if ( response == JOptionPane.YES_OPTION ){ + saveDialog(); + } else if ( response == JOptionPane.CANCEL_OPTION ){ + return; + } + } + + objectToEditor.remove(o); + editorToObject.remove(e); + fileToEditor.remove(f); + editorToFile.remove(e); + remove(e); + } + + private void saveDialog(){ + EDITOR e = getSelectedComponent(); + if ( !editorToFile.containsKey(e) ){ + log.debug("Editor has no file, saving as..."); + saveAsDialog(); + return; + } + File file = editorToFile.get(e); + log.debug("Saving to " + file.getAbsolutePath()); + try { + saveToFile(editorToObject.get(e), file); + undirty(editorToObject.get(e)); + } catch (IOException e1) { + errorDialog(e1); + } + } + private void saveAsDialog(){ + EDITOR e = getSelectedComponent(); + final FileDialog fd = new FileDialog(frame, "Save" + noun + " As", FileDialog.SAVE); + fd.setVisible(true); + if (fd.getFile() != null ) { + File file = new File(fd.getDirectory() + fd.getFile()); + try { + OBJECT o = editorToObject.get(e); + saveToFile(o, file); + undirty(o); + objectToEditor.put(o, e); + editorToObject.put(e, o); + fileToEditor.put(file, e); + editorToFile.put(e, file); + setTitleAt( + getSelectedIndex(), + file.getName()); + } catch (Exception e1) { + errorDialog(e1); + } + } + } + + private void openDialog(){ + final FileDialog fd = new FileDialog(frame, "Open" + noun + "...", FileDialog.LOAD); + fd.setVisible(true); + if ( fd.getFile() != null ) { + File file = new File(fd.getDirectory() + fd.getFile()); + log.debug("Opening File " + file.getAbsolutePath()); + if ( fileToEditor.containsKey(file) ){ + log.debug("File " + file.getAbsolutePath() + "Already open, focusing"); + setSelectedComponent(fileToEditor.get(file)); + return; + } + try { + OBJECT o = loadFromFile(file); + EDITOR e = createEditor(o); + objectToEditor.put(o, e); + editorToObject.put(e, o); + fileToEditor.put(file, e); + editorToFile.put(e, file); + addTab(file.getName(), e); + } catch (Exception e) { + errorDialog(e); + } + } + } + + public final List getMenuItems(){ + List ret = new Vector(); + ret.add(new JMenuItem("New" + noun){ + private static final long serialVersionUID = 1L; + { + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + log.debug("New"); + menuNew(); + } + }); + } + }); + ret.add(new JMenuItem("Open" + noun + "..."){ + private static final long serialVersionUID = 1L; + { + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + log.debug("Open..."); + openDialog(); + } + }); + } + }); + ret.add(new JMenuItem("Close" + noun){ + private static final long serialVersionUID = 1L; + { + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + log.debug("Close"); + close(); + } + }); + } + }); + ret.add(new JMenuItem("Save" + noun){ + private static final long serialVersionUID = 1L; + { + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + log.debug("Save"); + saveDialog(); + } + }); + } + }); + ret.add(new JMenuItem("Save" + noun + " As..."){ + private static final long serialVersionUID = 1L; + { + addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent ae) { + log.debug("Save As..."); + saveAsDialog(); + } + }); + } + }); + return ret; + } + + protected final void add(final OBJECT o){ + EDITOR e = createEditor(o); + objectToEditor.put(o, e); + editorToObject.put(e, o); + addTab("new", e); + dirty(o); + } + + public final void load(final File f) throws IOException{ + OBJECT o = loadFromFile(f); + EDITOR e = createEditor(o); + objectToEditor.put(o, e); + editorToObject.put(e, o); + fileToEditor.put(f, e); + editorToFile.put(e, f); + addTab(f.getName(), e); + } + + public abstract EDITOR createEditor(final OBJECT o); + + public abstract OBJECT newObject(); + + protected abstract OBJECT loadFromFile(final File f) throws IOException; + + protected abstract void saveToFile(final OBJECT o, final File f) throws IOException; + + + private final void errorDialog(final Throwable t){ + t.printStackTrace(); + JOptionPane.showMessageDialog(MultiObjectEditor.this, t.getClass().getSimpleName() + ": " + t.getMessage()); + } +} diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/FuelsEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/FuelsEditor.java new file mode 100644 index 0000000..61f7ca8 --- /dev/null +++ b/gui/com/billkuker/rocketry/motorsim/visual/workbench/FuelsEditor.java @@ -0,0 +1,64 @@ +package com.billkuker.rocketry.motorsim.visual.workbench; + +import java.awt.Frame; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import javax.swing.JFrame; +import javax.swing.JMenuBar; + +import com.billkuker.rocketry.motorsim.Fuel; +import com.billkuker.rocketry.motorsim.fuel.EditableFuel; +import com.billkuker.rocketry.motorsim.fuel.PiecewiseLinearFuel; +import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel; +import com.billkuker.rocketry.motorsim.io.MotorIO; +import com.billkuker.rocketry.motorsim.visual.FuelPanel; +import com.billkuker.rocketry.motorsim.visual.MultiObjectEditor; +import com.billkuker.rocketry.motorsim.visual.workbench.AbstractFuelEditor.EditablePSRFuel; + +public class FuelsEditor extends MultiObjectEditor { + + public FuelsEditor(Frame frame) { + super(frame, "Fuel"); + } + + @Override + public AbstractFuelEditor createEditor(Fuel o) { + if ( o instanceof PiecewiseLinearFuel ){ + return new LinearFuelEditor((PiecewiseLinearFuel)o); + } else if ( o instanceof EditableFuel ){ + return new SRFuelEditor(new EditablePSRFuel(SaintRobertFuel.Type.SI)); + } + return null; + } + + @Override + public Fuel newObject() { + return new PiecewiseLinearFuel(); + } + + @Override + protected Fuel loadFromFile(File f) throws IOException { + return MotorIO.readFuel(new FileInputStream(f)); + } + + @Override + protected void saveToFile(Fuel o, File f) throws IOException { + MotorIO.writeFuel(o, new FileOutputStream(f)); + } + + public static void main(String args[]){ + JFrame f = new JFrame(); + f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + FuelsEditor fe; + f.add(fe = new FuelsEditor(f)); + JMenuBar b; + f.setJMenuBar(b = new JMenuBar()); + b.add(fe.getMenu()); + f.setSize(1024, 768); + f.show(); + } + +} diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/LinearFuelEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/LinearFuelEditor.java index 3a317c8..65a255a 100644 --- a/gui/com/billkuker/rocketry/motorsim/visual/workbench/LinearFuelEditor.java +++ b/gui/com/billkuker/rocketry/motorsim/visual/workbench/LinearFuelEditor.java @@ -137,12 +137,9 @@ public class LinearFuelEditor extends AbstractFuelEditor { JPanel controls; final PiecewiseLinearFuel f; - public LinearFuelEditor() { - - super( new PiecewiseLinearFuel() ); - - this.f = (PiecewiseLinearFuel)getFuel(); - + public LinearFuelEditor(PiecewiseLinearFuel f) { + super( f ); + this.f = f; } protected Component getBurnrateEditComponent(){ @@ -183,7 +180,7 @@ public class LinearFuelEditor extends AbstractFuelEditor { public static void main(String args[]) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - f.setContentPane(new LinearFuelEditor()); + f.setContentPane(new LinearFuelEditor(new PiecewiseLinearFuel())); f.setSize(800, 600); f.setVisible(true); diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/MotorWorkbench.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/MotorWorkbench.java index fa7aa8e..9c58d6e 100644 --- a/gui/com/billkuker/rocketry/motorsim/visual/workbench/MotorWorkbench.java +++ b/gui/com/billkuker/rocketry/motorsim/visual/workbench/MotorWorkbench.java @@ -37,9 +37,12 @@ import com.billkuker.rocketry.motorsim.Fuel; import com.billkuker.rocketry.motorsim.Motor; import com.billkuker.rocketry.motorsim.RocketScience.UnitPreference; import com.billkuker.rocketry.motorsim.fuel.FuelResolver; +import com.billkuker.rocketry.motorsim.fuel.PiecewiseLinearFuel; +import com.billkuker.rocketry.motorsim.fuel.SaintRobertFuel; import com.billkuker.rocketry.motorsim.io.ENGExporter; import com.billkuker.rocketry.motorsim.io.MotorIO; import com.billkuker.rocketry.motorsim.visual.FuelPanel; +import com.billkuker.rocketry.motorsim.visual.workbench.AbstractFuelEditor.EditablePSRFuel; import com.billkuker.rocketry.motorsim.visual.workbench.WorkbenchTreeModel.FuelEditNode; import com.billkuker.rocketry.motorsim.visual.workbench.WorkbenchTreeModel.FuelNode; @@ -239,7 +242,7 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener { addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { - newFuel(new SRFuelEditor()); + newFuel(new SRFuelEditor(new EditablePSRFuel(SaintRobertFuel.Type.SI))); } }); @@ -251,7 +254,7 @@ public class MotorWorkbench extends JFrame implements TreeSelectionListener { addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { - newFuel(new LinearFuelEditor()); + newFuel(new LinearFuelEditor(new PiecewiseLinearFuel())); } }); diff --git a/gui/com/billkuker/rocketry/motorsim/visual/workbench/SRFuelEditor.java b/gui/com/billkuker/rocketry/motorsim/visual/workbench/SRFuelEditor.java index 66ded6a..d4aa6d0 100644 --- a/gui/com/billkuker/rocketry/motorsim/visual/workbench/SRFuelEditor.java +++ b/gui/com/billkuker/rocketry/motorsim/visual/workbench/SRFuelEditor.java @@ -137,11 +137,11 @@ public class SRFuelEditor extends AbstractFuelEditor { JPanel controls; final EditablePSRFuel f; - public SRFuelEditor() { + public SRFuelEditor(EditablePSRFuel f) { - super( new EditablePSRFuel(SaintRobertFuel.Type.SI) ); + super( f); - this.f = (EditablePSRFuel)getFuel(); + this.f = f; } @@ -208,7 +208,7 @@ public class SRFuelEditor extends AbstractFuelEditor { public static void main(String args[]) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - f.setContentPane(new SRFuelEditor()); + f.setContentPane(new SRFuelEditor(new EditablePSRFuel(SaintRobertFuel.Type.SI))); f.setSize(800, 600); f.setVisible(true); -- 2.47.2