1 package net.sf.openrocket.gui.customexpression;
4 import java.awt.Window;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
8 import java.util.ArrayList;
9 import java.util.Collections;
11 import javax.swing.BorderFactory;
12 import javax.swing.JButton;
13 import javax.swing.JDialog;
14 import javax.swing.JFileChooser;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17 import javax.swing.JScrollPane;
18 import javax.swing.SwingUtilities;
19 import javax.swing.border.Border;
20 import javax.swing.filechooser.FileFilter;
21 import javax.swing.filechooser.FileNameExtensionFilter;
23 import net.miginfocom.swing.MigLayout;
24 import net.sf.openrocket.document.OpenRocketDocument;
25 import net.sf.openrocket.file.DatabaseMotorFinder;
26 import net.sf.openrocket.file.GeneralRocketLoader;
27 import net.sf.openrocket.file.MotorFinder;
28 import net.sf.openrocket.file.RocketLoadException;
29 import net.sf.openrocket.document.Simulation;
30 import net.sf.openrocket.gui.components.DescriptionArea;
31 import net.sf.openrocket.gui.components.UnitSelector;
32 import net.sf.openrocket.gui.customexpression.ExpressionBuilderDialog;
33 import net.sf.openrocket.gui.util.Icons;
34 import net.sf.openrocket.l10n.Translator;
35 import net.sf.openrocket.logging.LogHelper;
36 import net.sf.openrocket.rocketcomponent.Rocket;
37 import net.sf.openrocket.simulation.customexpression.CustomExpression;
38 import net.sf.openrocket.startup.Application;
40 public class CustomExpressionPanel extends JPanel {
42 private static final LogHelper log = Application.getLogger();
43 private static final Translator trans = Application.getTranslator();
45 private JPanel expressionSelectorPanel;
46 private OpenRocketDocument doc;
48 public CustomExpressionPanel(final OpenRocketDocument doc, final JDialog parentDialog) {
49 super(new MigLayout("fill"));
52 expressionSelectorPanel = new JPanel(new MigLayout("gapy rel"));
53 expressionSelectorPanel.setToolTipText(trans.get("customExpressionPanel.lbl.CalcNote"));
55 JScrollPane scroll = new JScrollPane();
56 Border bdr = BorderFactory.createTitledBorder(trans.get("customExpressionPanel.lbl.CustomExpressions"));
58 expressionSelectorPanel.setBorder(bdr);
59 expressionSelectorPanel.add(scroll);
61 //this.add(expressionSelectorPanel, "spany 1, height 10px, wmin 600lp, grow 100, gapright para");
62 this.add(expressionSelectorPanel, "hmin 200lp, wmin 700lp, grow 100, wrap");
64 //DescriptionArea desc = new DescriptionArea(trans.get("customExpressionPanel.lbl.UpdateNote")+"\n\n"+trans.get("customExpressionPanel.lbl.CalcNote"), 8, -2f);
65 //desc.setViewportBorder(BorderFactory.createEmptyBorder());
66 //this.add(desc, "width 1px, growx 1, wrap unrel, wrap");
69 JButton button = new JButton(trans.get("customExpressionPanel.but.NewExpression"));
70 button.setToolTipText(trans.get("customExpressionPanel.but.ttip.NewExpression"));
71 button.addActionListener(new ActionListener() {
73 public void actionPerformed(ActionEvent e) {
74 // Open window to configure expression
75 log.info("Opening window to configure new expression");
76 Window parent = SwingUtilities.getWindowAncestor(CustomExpressionPanel.this);
77 new ExpressionBuilderDialog(parent, doc).setVisible(true);
81 this.add(button, "split 4, width :100:200");
84 final JButton importButton = new JButton(trans.get("customExpressionPanel.but.Import"));
85 importButton.setToolTipText(trans.get("customExpressionPanel.but.ttip.Import"));
86 importButton.addActionListener(new ActionListener() {
88 public void actionPerformed(ActionEvent e) {
90 //Create a file chooser
91 final JFileChooser fc = new JFileChooser();
92 if (doc.getFile() != null){
93 fc.setCurrentDirectory(doc.getFile().getParentFile());
95 fc.setFileFilter(new FileNameExtensionFilter("Openrocket file", "ork"));
96 fc.setAcceptAllFileFilterUsed(false);
98 int returnVal = fc.showOpenDialog(CustomExpressionPanel.this);
99 if (returnVal == JFileChooser.APPROVE_OPTION){
100 File importFile = fc.getSelectedFile();
101 log.info("User selected a file to import expressions from "+fc.getSelectedFile().toString());
103 //TODO: This should probably be somewhere else and ideally we would use an alternative minimal rocket loader. Still, it doesn't seem particularly slow this way.
105 // Load expressions from selected document
106 GeneralRocketLoader loader = new GeneralRocketLoader();
108 OpenRocketDocument importedDocument = loader.load(importFile, new DatabaseMotorFinder());
109 for (CustomExpression exp : importedDocument.getCustomExpressions()){
110 doc.addCustomExpression(exp);
112 } catch (RocketLoadException e1) {
113 log.user("Error opening document to import expressions from.");
119 this.add(importButton, "width :100:200");
122 final JButton closeButton = new JButton(trans.get("dlg.but.close"));
123 closeButton.addActionListener(new ActionListener() {
125 public void actionPerformed(ActionEvent e) {
126 parentDialog.dispose();
129 this.add(new JPanel(), "growx");
130 this.add(closeButton, "width :100:200");
136 * Update the expressionSelectorPanel
138 private void updateExpressions(){
140 expressionSelectorPanel.removeAll();
141 int totalExpressions = doc.getCustomExpressions().size();
142 for (int i=0; i<totalExpressions; i++){
143 SingleExpression se = new SingleExpression(doc.getCustomExpressions().get(i), i != 0, i != totalExpressions-1);
144 expressionSelectorPanel.add(se, "wrap");
147 expressionSelectorPanel.revalidate();
148 expressionSelectorPanel.repaint();
151 private void deleteExpression(CustomExpression expression){
152 doc.getCustomExpressions().remove(expression);
156 * Moves an expression up or down in the expression list
158 * @param move integer - +1 to move down, -1 to move up
160 private void moveExpression(CustomExpression expression, int move){
161 ArrayList<CustomExpression> expressions = doc.getCustomExpressions();
162 int i = expressions.indexOf(expression);
163 if (i+move == expressions.size() || i+move < 0)
166 Collections.swap(expressions, i, i+move);
171 * A JPanel which configures a single expression
173 private class SingleExpression extends JPanel {
175 // Convenience method to make the labels consistent
176 private JLabel setLabelStyle(JLabel l){
177 l.setBackground(Color.WHITE);
179 l.setBorder(BorderFactory.createRaisedBevelBorder() );
180 l.setText(" " + l.getText() + " ");
184 private SingleExpression(final CustomExpression expression, boolean showUp, boolean showDown) {
185 super(new MigLayout("ins 0"));
186 // name: aName symbol: a Unit: m/s
187 //super(new MigLayout("","[::100][:200:400][::100][:100:200][::100][:100:200]",""));
189 JLabel nameLabel = new JLabel( trans.get("customExpression.Name")+ " :");
190 JLabel name = new JLabel ( expression.getName() );
191 name = setLabelStyle(name);
192 JLabel symbolLabel = new JLabel( trans.get("customExpression.Symbol")+ " :" );
193 JLabel symbol = new JLabel ( expression.getSymbol());
194 symbol = setLabelStyle(symbol);
195 symbol.setBackground(Color.WHITE);
197 JLabel unitLabel = new JLabel( trans.get("customExpression.Units")+ " :");
198 UnitSelector unitSelector = new UnitSelector(expression.getType().getUnitGroup());
199 //JLabel unitSelector = new JLabel ( expression.getUnit() );
200 //unitSelector = setLabelStyle(unitSelector);
201 //unitSelector.setBackground(Color.WHITE);
203 JButton editButton = new JButton(Icons.EDIT);
204 editButton.setToolTipText(trans.get("customExpression.Units.but.ttip.Edit"));
205 editButton.setBorderPainted(false);
206 editButton.addActionListener( new ActionListener() {
208 public void actionPerformed(ActionEvent e){
209 Window parent = SwingUtilities.getWindowAncestor(CustomExpressionPanel.this);
210 new ExpressionBuilderDialog(parent, doc, expression).setVisible(true);
215 JButton upButton = new JButton(Icons.UP);
216 upButton.setToolTipText(trans.get("customExpression.Units.but.ttip.MoveUp"));
217 upButton.setBorderPainted(false);
218 upButton.setVisible(showUp);
219 upButton.addActionListener( new ActionListener() {
221 public void actionPerformed(ActionEvent e) {
222 moveExpression(expression, -1);
227 JButton downButton = new JButton(Icons.DOWN);
228 downButton.setToolTipText(trans.get("customExpression.Units.but.ttip.MoveDown"));
229 downButton.setBorderPainted(false);
230 downButton.setVisible(showDown);
231 downButton.addActionListener( new ActionListener() {
233 public void actionPerformed(ActionEvent e) {
234 moveExpression(expression, 1);
240 JButton deleteButton = new JButton(Icons.DELETE);
241 //// Remove this expression
242 deleteButton.setToolTipText(trans.get("customExpression.Units.but.ttip.Remove"));
243 deleteButton.setBorderPainted(false);
244 deleteButton.addActionListener(new ActionListener() {
246 public void actionPerformed(ActionEvent e) {
247 deleteExpression(expression);
253 this.add(name, "width 200:200:400, growx");
254 this.add(new JPanel());
255 this.add(symbolLabel);
256 this.add(symbol, "width :50:200");
257 this.add(new JPanel());
259 this.add(unitSelector, "width :50:100");
260 this.add(new JPanel(), "growx");
261 this.add(upButton, "right");
262 this.add(downButton, "right");
263 this.add(editButton, "right");
264 this.add(deleteButton, "right");