Initial GUI for editing and saving component presets. See ComponentPresetPanel.main() for standalone execution.
This commit is contained in:
parent
0a199d73c3
commit
3d73e9d9eb
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
229
core/src/net/sf/openrocket/gui/preset/ComponentPresetPanel.java
Normal file
229
core/src/net/sf/openrocket/gui/preset/ComponentPresetPanel.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
105
core/src/net/sf/openrocket/gui/preset/ImagePreviewPanel.java
Normal file
105
core/src/net/sf/openrocket/gui/preset/ImagePreviewPanel.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
120
core/src/net/sf/openrocket/gui/preset/MaterialModel.java
Normal file
120
core/src/net/sf/openrocket/gui/preset/MaterialModel.java
Normal 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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1636
core/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java
Normal file
1636
core/src/net/sf/openrocket/gui/preset/PresetEditorDialog.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
package net.sf.openrocket.gui.preset;
|
||||||
|
|
||||||
|
import net.sf.openrocket.preset.ComponentPreset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
public interface PresetResultListener {
|
||||||
|
|
||||||
|
void notifyResult(ComponentPreset preset);
|
||||||
|
}
|
@ -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;
|
||||||
/**
|
/**
|
||||||
|
@ -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");
|
||||||
|
@ -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,
|
||||||
|
@ -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) {
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user