Initial GUI for editing and saving component presets. See ComponentPresetPanel.main() for standalone execution.

This commit is contained in:
Doug Pedrick 2012-05-05 02:23:14 +00:00
parent 0a199d73c3
commit 3d73e9d9eb
12 changed files with 2376 additions and 227 deletions

View File

@ -95,6 +95,7 @@ filetypes.pdf = PDF files (*.pdf)
BasicFrame.SimpleFileFilter1 = All rocket designs (*.ork; *.rkt) BasicFrame.SimpleFileFilter1 = All rocket designs (*.ork; *.rkt)
BasicFrame.SimpleFileFilter2 = OpenRocket designs (*.ork) BasicFrame.SimpleFileFilter2 = OpenRocket designs (*.ork)
BasicFrame.SimpleFileFilter3 = RockSim designs (*.rkt) BasicFrame.SimpleFileFilter3 = RockSim designs (*.rkt)
BasicFrame.SimpleFileFilter4 = OpenRocket presets (*.orc)
filetypes.images = Image files filetypes.images = Image files

View File

@ -0,0 +1,229 @@
package net.sf.openrocket.gui.preset;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.util.FileHelper;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.ResourceBundleTranslator;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.xml.OpenRocketComponentSaver;
import net.sf.openrocket.startup.Application;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.xml.bind.JAXBException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* A UI for editing component presets. Currently this is a standalone application - run the main within this class.
* TODO: Full I18n
* TODO: Delete component
* TODO: Open .orc for editing
* TODO: Import .csv
* TODO: Export .csv
* TODO: proper mass unit conversion
*/
public class ComponentPresetPanel extends JPanel implements PresetResultListener {
private static final LogHelper log = Application.getLogger();
private static ResourceBundleTranslator trans = null;
static {
trans = new ResourceBundleTranslator("l10n.messages");
net.sf.openrocket.startup.Application.setBaseTranslator(trans);
}
private JTable table;
private DataTableModel model;
private boolean editingSelected = false;
/**
* Create the panel.
*/
public ComponentPresetPanel() {
setLayout(new MigLayout("", "[82.00px][168.00px][84px][117.00px][][222px]", "[346.00px][29px]"));
model = new DataTableModel(new String[]{"Manufacturer", "Type", "Part No", "Description"});
table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);
table.setFillsViewportHeight(true);
table.setAutoCreateRowSorter(true);
add(scrollPane, "cell 0 0 6 1,grow");
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
JTable target = (JTable) e.getSource();
int row = target.getSelectedRow();
editingSelected = true;
new PresetEditorDialog(ComponentPresetPanel.this, (ComponentPreset) model.getAssociatedObject(row)).setVisible(true);
}
}
});
JButton addBtn = new JButton("Add");
addBtn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
editingSelected = false;
new PresetEditorDialog(ComponentPresetPanel.this).setVisible(true);
}
});
add(addBtn, "cell 0 1,alignx left,aligny top");
JButton saveBtn = new JButton("Save...");
saveBtn.setHorizontalAlignment(SwingConstants.RIGHT);
add(saveBtn, "flowx,cell 5 1,alignx right,aligny center");
saveBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
try {
saveAsORC();
}
catch (JAXBException e1) {
//TODO
e1.printStackTrace();
}
catch (IOException e1) {
//TODO
e1.printStackTrace();
}
}
});
JButton cancelBtn = new JButton("Cancel");
cancelBtn.setHorizontalAlignment(SwingConstants.RIGHT);
add(cancelBtn, "cell 5 1,alignx right,aligny top");
cancelBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
System.exit(0);
}
});
}
@Override
public void notifyResult(final ComponentPreset preset) {
if (preset != null) {
DataTableModel model = (DataTableModel) table.getModel();
if (!editingSelected) {
model.addRow(new String[]{preset.getManufacturer().getDisplayName(), preset.getType().name(), preset.getPartNo(), preset.get(ComponentPreset.DESCRIPTION)},
preset);
}
else {
int row = table.getSelectedRow();
model.setValueAt(preset.getManufacturer().getDisplayName(), row, 0);
model.setValueAt(preset.getType().name(), row, 1);
model.setValueAt(preset.getPartNo(), row, 2);
model.setValueAt(preset.get(ComponentPreset.DESCRIPTION), row, 3);
model.associated.set(row, preset);
}
}
editingSelected = false;
}
/**
* Launch the test main.
*/
public static void main(String[] args) {
try {
Application.setPreferences(new SwingPreferences());
JFrame dialog = new JFrame();
dialog.getContentPane().add(new ComponentPresetPanel());
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.pack();
dialog.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
class DataTableModel extends DefaultTableModel {
private List<Object> associated = new ArrayList<Object>();
/**
* Constructs a <code>DefaultTableModel</code> with as many columns as there are elements in
* <code>columnNames</code> and <code>rowCount</code> of <code>null</code> object values. Each column's name
* will be taken from the <code>columnNames</code> array.
*
* @param columnNames <code>array</code> containing the names of the new columns; if this is <code>null</code>
* then the model has no columns
*
* @see #setDataVector
* @see #setValueAt
*/
DataTableModel(final Object[] columnNames) {
super(columnNames, 0);
}
public void addRow(Object[] data, Object associatedData) {
super.addRow(data);
associated.add(getRowCount() - 1, associatedData);
}
public void removeRow(int row) {
super.removeRow(row);
associated.remove(row);
}
public Object getAssociatedObject(int row) {
return associated.get(row);
}
public boolean isCellEditable(int rowIndex, int mColIndex) {
return false;
}
}
private boolean saveAsORC() throws JAXBException, IOException {
File file = null;
final JFileChooser chooser = new JFileChooser();
chooser.addChoosableFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
chooser.setFileFilter(FileHelper.OPEN_ROCKET_COMPONENT_FILTER);
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
int option = chooser.showSaveDialog(ComponentPresetPanel.this);
if (option != JFileChooser.APPROVE_OPTION) {
log.user("User decided not to save, option=" + option);
return false;
}
file = chooser.getSelectedFile();
if (file == null) {
log.user("User did not select a file");
return false;
}
((SwingPreferences) Application.getPreferences()).setDefaultDirectory(chooser.getCurrentDirectory());
file = FileHelper.forceExtension(file, "orc");
List<Material> materials = new ArrayList<Material>();
List<ComponentPreset> presets = new ArrayList<ComponentPreset>();
for (int x = 0; x< model.getRowCount(); x++) {
ComponentPreset preset = (ComponentPreset)model.getAssociatedObject(x);
if (!materials.contains(preset.get(ComponentPreset.MATERIAL))) {
materials.add(preset.get(ComponentPreset.MATERIAL));
}
presets.add(preset);
}
return FileHelper.confirmWrite(file, this) && new OpenRocketComponentSaver().save(file, materials, presets);
}
}

View File

@ -0,0 +1,105 @@
package net.sf.openrocket.gui.preset;
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
/**
* From a JavaLobby article by Michael Urban: http://www.javalobby.org/java/forums/t49462.html
*/
public class ImagePreviewPanel extends JPanel
implements PropertyChangeListener {
private int width, height;
private ImageIcon icon;
private Image image;
private static final int ACCSIZE = 155;
private Color bg;
public ImagePreviewPanel() {
setPreferredSize(new Dimension(ACCSIZE, -1));
bg = getBackground();
}
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
// Make sure we are responding to the right event.
if (propertyName.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY)) {
File selection = (File)e.getNewValue();
String name;
if (selection == null)
return;
else
name = selection.getAbsolutePath();
/*
* Make reasonably sure we have an image format that AWT can
* handle so we don't try to draw something silly.
*/
if ((name != null) &&
name.toLowerCase().endsWith(".jpg") ||
name.toLowerCase().endsWith(".jpeg") ||
name.toLowerCase().endsWith(".gif") ||
name.toLowerCase().endsWith(".png")) {
icon = new ImageIcon(name);
image = icon.getImage();
scaleImage();
repaint();
}
}
}
private void scaleImage() {
width = image.getWidth(this);
height = image.getHeight(this);
double ratio = 1.0;
/*
* Determine how to scale the image. Since the accessory can expand
* vertically make sure we don't go larger than 150 when scaling
* vertically.
*/
if (width >= height) {
ratio = (double)(ACCSIZE-5) / width;
width = ACCSIZE-5;
height = (int)(height * ratio);
}
else {
if (getHeight() > 150) {
ratio = (double)(ACCSIZE-5) / height;
height = ACCSIZE-5;
width = (int)(width * ratio);
}
else {
ratio = (double)getHeight() / height;
height = getHeight();
width = (int)(width * ratio);
}
}
image = image.getScaledInstance(width, height, Image.SCALE_DEFAULT);
}
public void paintComponent(Graphics g) {
g.setColor(bg);
/*
* If we don't do this, we will end up with garbage from previous
* images if they have larger sizes than the one we are currently
* drawing. Also, it seems that the file list can paint outside
* of its rectangle, and will cause odd behavior if we don't clear
* or fill the rectangle for the accessory before drawing. This might
* be a bug in JFileChooser.
*/
g.fillRect(0, 0, ACCSIZE, getHeight());
g.drawImage(image, getWidth() / 2 - width / 2 + 5,
getHeight() / 2 - height / 2, this);
}
}

View File

@ -0,0 +1,120 @@
package net.sf.openrocket.gui.preset;
import net.sf.openrocket.database.Database;
import net.sf.openrocket.database.DatabaseListener;
import net.sf.openrocket.database.Databases;
import net.sf.openrocket.gui.dialogs.CustomMaterialDialog;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.startup.Application;
import javax.swing.*;
import java.awt.*;
/**
* A material model specifically for presets.
*/
public class MaterialModel extends DefaultComboBoxModel implements DatabaseListener<Material> {
private static final String CUSTOM = "Custom";
private final Database<Material> database;
private static final Translator trans = Application.getTranslator();
private Component parent;
public MaterialModel(Component theParent, Material.Type type) {
parent = theParent;
switch (type) {
case LINE:
this.database = Databases.LINE_MATERIAL;
break;
case BULK:
this.database = Databases.BULK_MATERIAL;
break;
case SURFACE:
this.database = Databases.SURFACE_MATERIAL;
break;
default:
throw new IllegalArgumentException("Unknown material type:" + type);
}
database.addDatabaseListener(this);
}
@Override
public void setSelectedItem(Object item) {
if (item == null) {
// Clear selection - huh?
return;
}
if (item == CUSTOM) {
// Open custom material dialog in the future, after combo box has closed
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
CustomMaterialDialog dialog = new CustomMaterialDialog(
SwingUtilities.getWindowAncestor(parent),
(Material) getSelectedItem(), true,
//// Define custom material
trans.get("MaterialModel.title.Defcustmat"));
dialog.setVisible(true);
if (!dialog.getOkClicked()) {
return;
}
Material material = dialog.getMaterial();
MaterialModel.super.setSelectedItem(material);
if (dialog.isAddSelected()) {
database.add(material);
}
}
});
}
else if (item instanceof Material) {
super.setSelectedItem(item);
}
else {
throw new IllegalArgumentException("Illegal item class " + item.getClass() +
" item=" + item);
}
}
@Override
public Object getElementAt(int index) {
if (index == database.size()) {
return CUSTOM;
}
else if (index >= database.size() + 1) {
return null;
}
return database.get(index);
}
@Override
public int getSize() {
return database.size() + 1;
}
//////// Change listeners
@Override
public void elementAdded(Material element, Database<Material> source) {
this.fireContentsChanged(this, 0, database.size());
}
@Override
public void elementRemoved(Material element, Database<Material> source) {
this.fireContentsChanged(this, 0, database.size());
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
package net.sf.openrocket.gui.preset;
import net.sf.openrocket.preset.ComponentPreset;
/**
*/
public interface PresetResultListener {
void notifyResult(ComponentPreset preset);
}

View File

@ -7,6 +7,14 @@ package net.sf.openrocket.gui.print;
* Utilities for print units. * Utilities for print units.
*/ */
public enum PrintUnit { public enum PrintUnit {
FOOT {
public double toInches(double d) { return d*12; }
public double toMillis(double d) { return d/FEET_PER_MM; }
public double toCentis(double d) { return d/(FEET_PER_MM*TEN); }
public double toMeters(double d) { return d/(FEET_PER_MM*TEN*TEN*TEN); }
public long toPoints(double d) { return (long)(d * POINTS_PER_INCH * 12); }
public double convert(double d, PrintUnit u) { return u.toInches(d)/12; }
},
INCHES { INCHES {
public double toInches(double d) { return d; } public double toInches(double d) { return d; }
public double toMillis(double d) { return d/INCHES_PER_MM; } public double toMillis(double d) { return d/INCHES_PER_MM; }
@ -50,6 +58,7 @@ public enum PrintUnit {
// Handy constants for conversion methods // Handy constants for conversion methods
public static final double INCHES_PER_MM = 0.0393700787d; public static final double INCHES_PER_MM = 0.0393700787d;
public static final double FEET_PER_MM = INCHES_PER_MM /12;
public static final double MM_PER_INCH = 1.0d/INCHES_PER_MM; public static final double MM_PER_INCH = 1.0d/INCHES_PER_MM;
public static final long TEN = 10; public static final long TEN = 10;
/** /**

View File

@ -1,20 +1,19 @@
package net.sf.openrocket.gui.util; package net.sf.openrocket.gui.util;
import java.awt.Component;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import javax.imageio.ImageIO;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import net.sf.openrocket.l10n.L10N; import net.sf.openrocket.l10n.L10N;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
/** /**
* Helper methods related to user-initiated file manipulation. * Helper methods related to user-initiated file manipulation.
* <p> * <p>
@ -42,6 +41,10 @@ public final class FileHelper {
public static final FileFilter ROCKSIM_DESIGN_FILTER = public static final FileFilter ROCKSIM_DESIGN_FILTER =
new SimpleFileFilter(trans.get("BasicFrame.SimpleFileFilter3"), ".rkt", ".rkt.gz"); new SimpleFileFilter(trans.get("BasicFrame.SimpleFileFilter3"), ".rkt", ".rkt.gz");
/** File filter for OpenRocket components and presets (*.orc) */
public static final FileFilter OPEN_ROCKET_COMPONENT_FILTER =
new SimpleFileFilter(trans.get("BasicFrame.SimpleFileFilter4"), ".orc", ".orc.gz");
/** File filter for PDF files (*.pdf) */ /** File filter for PDF files (*.pdf) */
public static final FileFilter PDF_FILTER = public static final FileFilter PDF_FILTER =
new SimpleFileFilter(trans.get("filetypes.pdf"), ".pdf"); new SimpleFileFilter(trans.get("filetypes.pdf"), ".pdf");

View File

@ -52,6 +52,7 @@ public class ComponentPreset implements Comparable<ComponentPreset> {
ComponentPreset.SHAPE, ComponentPreset.SHAPE,
ComponentPreset.AFT_OUTER_DIAMETER, ComponentPreset.AFT_OUTER_DIAMETER,
ComponentPreset.AFT_SHOULDER_DIAMETER, ComponentPreset.AFT_SHOULDER_DIAMETER,
ComponentPreset.AFT_SHOULDER_LENGTH,
ComponentPreset.LENGTH} ), ComponentPreset.LENGTH} ),
TRANSITION( new TypedKey<?>[] { TRANSITION( new TypedKey<?>[] {
@ -177,7 +178,7 @@ public class ComponentPreset implements Comparable<ComponentPreset> {
public final static TypedKey<Integer> LINE_COUNT = new TypedKey<Integer>("LineCount", Integer.class); public final static TypedKey<Integer> LINE_COUNT = new TypedKey<Integer>("LineCount", Integer.class);
public final static TypedKey<Double> LINE_LENGTH = new TypedKey<Double>("LineLength", Double.class, UnitGroup.UNITS_LENGTH); public final static TypedKey<Double> LINE_LENGTH = new TypedKey<Double>("LineLength", Double.class, UnitGroup.UNITS_LENGTH);
public final static TypedKey<Material> LINE_MATERIAL = new TypedKey<Material>("LineMaterial", Material.class); public final static TypedKey<Material> LINE_MATERIAL = new TypedKey<Material>("LineMaterial", Material.class);
public final static TypedKey<byte[]> IMAGE = new TypedKey<byte[]>("Image", byte[].class);
public final static List<TypedKey<?>> orderedKeyList = Arrays.<TypedKey<?>>asList( public final static List<TypedKey<?>> orderedKeyList = Arrays.<TypedKey<?>>asList(
MANUFACTURER, MANUFACTURER,

View File

@ -1,7 +1,6 @@
package net.sf.openrocket.preset.xml; package net.sf.openrocket.preset.xml;
import net.sf.openrocket.database.Databases;
import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material;
import net.sf.openrocket.motor.Manufacturer; import net.sf.openrocket.motor.Manufacturer;
import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPreset;
@ -76,6 +75,9 @@ public abstract class BaseComponentDTO {
if ( preset.has(ComponentPreset.FILLED) ) { if ( preset.has(ComponentPreset.FILLED) ) {
setFilled( preset.get(ComponentPreset.FILLED)); setFilled( preset.get(ComponentPreset.FILLED));
} }
if (preset.has(ComponentPreset.IMAGE) ) {
setImageData(preset.get(ComponentPreset.IMAGE));
}
} }
public String getManufacturer() { public String getManufacturer() {
@ -171,6 +173,9 @@ public abstract class BaseComponentDTO {
if ( filled != null ) { if ( filled != null ) {
props.put(ComponentPreset.FILLED, getFilled()); props.put(ComponentPreset.FILLED, getFilled());
} }
if (image != null) {
props.put(ComponentPreset.IMAGE, image);
}
} }
protected Material find(List<MaterialDTO> materialList, AnnotatedMaterialDTO dto) { protected Material find(List<MaterialDTO> materialList, AnnotatedMaterialDTO dto) {

View File

@ -1,6 +1,17 @@
package net.sf.openrocket.preset.xml; package net.sf.openrocket.preset.xml;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.InvalidComponentPresetException;
import net.sf.openrocket.startup.Application;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.BufferedWriter; import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
@ -10,16 +21,6 @@ import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.InvalidComponentPresetException;
import net.sf.openrocket.startup.Application;
/** /**
* The active manager class that is the entry point for reading and writing *.orc files. * The active manager class that is the entry point for reading and writing *.orc files.
*/ */
@ -39,6 +40,16 @@ public class OpenRocketComponentSaver {
} }
} }
public boolean save(File file, List<Material> theMaterialList, List<ComponentPreset> thePresetList) throws
JAXBException,
IOException {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
writer.write(marshalToOpenRocketComponent(theMaterialList, thePresetList));
writer.flush();
writer.close();
return true;
}
/** /**
* This method marshals a list of materials and ComponentPresets into an .orc formatted XML string. * This method marshals a list of materials and ComponentPresets into an .orc formatted XML string.
* *
@ -90,8 +101,8 @@ public class OpenRocketComponentSaver {
/** /**
* This method unmarshals from a Reader that is presumed to be open on an XML file in .orc format. * This method unmarshals from a Reader that is presumed to be open on an XML file in .orc format.
* *
* @param is an open reader; StringBufferInputStream could not be used because it's deprecated and does not handle UTF * @param is an open reader; StringBufferInputStream could not be used because it's deprecated and does not handle
* characters correctly * UTF characters correctly
* *
* @return a list of ComponentPresets * @return a list of ComponentPresets
* *
@ -127,13 +138,13 @@ public class OpenRocketComponentSaver {
* *
* @param is an open Reader; assumed to be opened on a file of XML in .orc format * @param is an open Reader; assumed to be opened on a file of XML in .orc format
* *
* @return the OpenRocketComponentDTO that is a POJO representation of the XML; null if the data could not be read or * @return the OpenRocketComponentDTO that is a POJO representation of the XML; null if the data could not be read
* was in an invalid format * or was in an invalid format
*/ */
private OpenRocketComponentDTO fromOpenRocketComponent(Reader is) throws JAXBException { private OpenRocketComponentDTO fromOpenRocketComponent(Reader is) throws JAXBException {
/** The context is thread-safe, but unmarshallers are not. Create a local one. */ /** The context is thread-safe, but unmarshallers are not. Create a local one. */
Unmarshaller unmarshaller = context.createUnmarshaller(); Unmarshaller unmarshaller = context.createUnmarshaller();
return (OpenRocketComponentDTO) unmarshaller.unmarshal(is); return (OpenRocketComponentDTO) unmarshaller.unmarshal(is); //new StreamSource(is));
} }
/** /**

View File

@ -1,10 +1,5 @@
package net.sf.openrocket.rocketcomponent; package net.sf.openrocket.rocketcomponent;
import static java.lang.Math.sin;
import static net.sf.openrocket.util.MathUtil.*;
import java.util.Collection;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.ComponentPreset.Type; import net.sf.openrocket.preset.ComponentPreset.Type;
@ -12,6 +7,12 @@ import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
import java.util.Collection;
import static java.lang.Math.sin;
import static net.sf.openrocket.util.MathUtil.pow2;
import static net.sf.openrocket.util.MathUtil.pow3;
public class Transition extends SymmetricComponent { public class Transition extends SymmetricComponent {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
@ -913,5 +914,22 @@ public class Transition extends SymmetricComponent {
public String toString() { public String toString() {
return name; return name;
} }
/**
* Lookup the Shape given the localized name. This differs from the standard valueOf as that looks up
* based on the canonical name, not the localized name which is an instance var.
*
* @param localizedName
* @return
*/
public static Shape toShape(String localizedName) {
Shape[] values = Shape.values();
for (Shape value : values) {
if (value.getName().equals(localizedName)) {
return value;
}
}
return null;
}
} }
} }