Fixed broken scrolling panel in custom expressions list.
[debian/openrocket] / core / src / net / sf / openrocket / gui / customexpression / CustomExpressionPanel.java
1 package net.sf.openrocket.gui.customexpression;
2
3 import java.awt.Color;
4 import java.awt.Window;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.io.File;
8 import java.util.Collections;
9 import java.util.List;
10
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.FileNameExtensionFilter;
21
22 import net.miginfocom.swing.MigLayout;
23 import net.sf.openrocket.document.OpenRocketDocument;
24 import net.sf.openrocket.file.DatabaseMotorFinder;
25 import net.sf.openrocket.file.GeneralRocketLoader;
26 import net.sf.openrocket.file.RocketLoadException;
27 import net.sf.openrocket.gui.components.UnitSelector;
28 import net.sf.openrocket.gui.util.Icons;
29 import net.sf.openrocket.l10n.Translator;
30 import net.sf.openrocket.logging.LogHelper;
31 import net.sf.openrocket.simulation.customexpression.CustomExpression;
32 import net.sf.openrocket.startup.Application;
33
34 public class CustomExpressionPanel extends JPanel {
35         
36         private static final LogHelper log = Application.getLogger();
37         private static final Translator trans = Application.getTranslator();
38         
39         private JPanel expressionSelectorPanel;
40         private OpenRocketDocument doc;
41         
42         public CustomExpressionPanel(final OpenRocketDocument doc, final JDialog parentDialog) {
43                 super(new MigLayout("fill"));
44                 this.doc = doc;
45
46                 expressionSelectorPanel = new JPanel(new MigLayout("gapy rel"));
47                 expressionSelectorPanel.setToolTipText(trans.get("customExpressionPanel.lbl.CalcNote"));
48                 
49                 JScrollPane scroll = new JScrollPane(expressionSelectorPanel);
50                 
51                 //Border bdr = BorderFactory.createTitledBorder(trans.get("customExpressionPanel.lbl.CustomExpressions"));
52                 //scroll.setBorder(bdr);
53                 //expressionSelectorPanel.add(scroll);
54                 
55                 //this.add(expressionSelectorPanel, "spany 1, height 10px, wmin 600lp, grow 100, gapright para");
56                 this.add(scroll, "hmin 200lp, wmin 700lp, grow 100, wrap");
57                 
58                 //DescriptionArea desc = new DescriptionArea(trans.get("customExpressionPanel.lbl.UpdateNote")+"\n\n"+trans.get("customExpressionPanel.lbl.CalcNote"), 8, -2f);
59                 //desc.setViewportBorder(BorderFactory.createEmptyBorder());
60                 //this.add(desc, "width 1px, growx 1, wrap unrel, wrap");
61                 
62                 //// New expression
63                 JButton button = new JButton(trans.get("customExpressionPanel.but.NewExpression"));
64                 button.setToolTipText(trans.get("customExpressionPanel.but.ttip.NewExpression"));
65                 button.addActionListener(new ActionListener() {
66                         @Override
67                         public void actionPerformed(ActionEvent e) {
68                                 // Open window to configure expression
69                                 log.info("Opening window to configure new expression");
70                                 Window parent = SwingUtilities.getWindowAncestor(CustomExpressionPanel.this);
71                                 new ExpressionBuilderDialog(parent, doc).setVisible(true);
72                                 updateExpressions();
73                         }
74                 });
75                 this.add(button, "split 4, width :100:200");
76                 
77                 //// Import
78                 final JButton importButton = new JButton(trans.get("customExpressionPanel.but.Import"));
79                 importButton.setToolTipText(trans.get("customExpressionPanel.but.ttip.Import"));
80                 importButton.addActionListener(new ActionListener() {
81                         @Override
82                         public void actionPerformed(ActionEvent e) {
83                                 
84                                 //Create a file chooser
85                                 final JFileChooser fc = new JFileChooser();
86                                 if (doc.getFile() != null){
87                                         fc.setCurrentDirectory(doc.getFile().getParentFile());
88                                 }
89                                 fc.setFileFilter(new FileNameExtensionFilter("Openrocket file", "ork"));
90                                 fc.setAcceptAllFileFilterUsed(false);
91                                 
92                                 int returnVal = fc.showOpenDialog(CustomExpressionPanel.this);
93                                 if (returnVal == JFileChooser.APPROVE_OPTION){
94                                         File importFile = fc.getSelectedFile();
95                                         log.info("User selected a file to import expressions from "+fc.getSelectedFile().toString());
96                                         
97                                         //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.
98                                         
99                                         // Load expressions from selected document
100                                         GeneralRocketLoader loader = new GeneralRocketLoader();
101                                         try {
102                                                 OpenRocketDocument importedDocument = loader.load(importFile, new DatabaseMotorFinder());
103                                                 for (CustomExpression exp : importedDocument.getCustomExpressions()){
104                                                         doc.addCustomExpression(exp);
105                                                 }
106                                         } catch (RocketLoadException e1) {
107                                                 log.user("Error opening document to import expressions from.");
108                                         }
109                                         updateExpressions();
110                                 }
111                         }
112                 });
113                 this.add(importButton, "width :100:200");
114                 
115                 //// Close button
116                 final JButton closeButton = new JButton(trans.get("dlg.but.close"));
117                 closeButton.addActionListener(new ActionListener() {
118                         @Override
119                         public void actionPerformed(ActionEvent e) {
120                                 parentDialog.dispose();
121                         }
122                 });
123                 this.add(new JPanel(), "growx");
124                 this.add(closeButton, "width :100:200");
125                 
126                 updateExpressions();
127         }
128         
129         /*
130          * Update the expressionSelectorPanel
131          */
132         private void updateExpressions(){
133                 
134                 expressionSelectorPanel.removeAll();
135                 int totalExpressions = doc.getCustomExpressions().size();
136                 for (int i=0; i<totalExpressions; i++){
137                         SingleExpression se = new SingleExpression(doc.getCustomExpressions().get(i), i != 0, i != totalExpressions-1);
138                         expressionSelectorPanel.add(se, "wrap");
139                 }
140
141                 expressionSelectorPanel.revalidate();
142                 expressionSelectorPanel.repaint();
143         }
144         
145         private void deleteExpression(CustomExpression expression){
146                 doc.getCustomExpressions().remove(expression);
147         }
148         
149         /**
150          * Moves an expression up or down in the expression list
151          * @param expression
152          * @param move integer - +1 to move down, -1 to move up
153          */
154         private void moveExpression(CustomExpression expression, int move){
155                 List<CustomExpression> expressions = doc.getCustomExpressions();
156                 int i = expressions.indexOf(expression);
157                 if (i+move == expressions.size() || i+move < 0)
158                         return;
159                 else
160                         Collections.swap(expressions, i, i+move);
161         }
162
163         
164         /*
165          * A JPanel which configures a single expression
166          */
167         private class SingleExpression extends JPanel {
168                 
169                 // Convenience method to make the labels consistent
170                 private JLabel setLabelStyle(JLabel l){
171                         l.setBackground(Color.WHITE);
172                         l.setOpaque(true);
173                         l.setBorder(BorderFactory.createRaisedBevelBorder() );
174                         l.setText(" " + l.getText() + " ");
175                         return l;
176                 }
177                 
178                 private SingleExpression(final CustomExpression expression, boolean showUp, boolean showDown) {
179                         super(new MigLayout("ins 0"));
180                         //                      name:    aName    symbol:  a      Unit:  m/s
181                         //super(new MigLayout("","[::100][:200:400][::100][:100:200][::100][:100:200]",""));
182                         
183                         JLabel nameLabel = new JLabel( trans.get("customExpression.Name")+ " :");
184                         JLabel name = new JLabel ( expression.getName() );
185                         name = setLabelStyle(name);
186                         JLabel symbolLabel = new JLabel( trans.get("customExpression.Symbol")+ " :" );
187                         JLabel symbol = new JLabel ( expression.getSymbol());
188                         symbol = setLabelStyle(symbol);
189                         symbol.setBackground(Color.WHITE);
190                         
191                         JLabel unitLabel = new JLabel( trans.get("customExpression.Units")+ " :");
192                         UnitSelector unitSelector = new UnitSelector(expression.getType().getUnitGroup());
193                         //JLabel unitSelector = new JLabel ( expression.getUnit() );
194                         //unitSelector = setLabelStyle(unitSelector);
195                         //unitSelector.setBackground(Color.WHITE);
196                         
197                         JButton editButton = new JButton(Icons.EDIT);
198                         editButton.setToolTipText(trans.get("customExpression.Units.but.ttip.Edit"));
199                         editButton.setBorderPainted(false);
200                         editButton.addActionListener( new ActionListener() {
201                                 @Override
202                                 public void actionPerformed(ActionEvent e){
203                                         Window parent = SwingUtilities.getWindowAncestor(CustomExpressionPanel.this);
204                                         new ExpressionBuilderDialog(parent, doc, expression).setVisible(true);
205                                         updateExpressions();
206                                 }
207                         });
208                         
209                         JButton upButton = new JButton(Icons.UP);
210                         upButton.setToolTipText(trans.get("customExpression.Units.but.ttip.MoveUp"));
211                         upButton.setBorderPainted(false);
212                         upButton.setVisible(showUp);
213                         upButton.addActionListener( new ActionListener() {
214                                 @Override
215                                 public void actionPerformed(ActionEvent e) {
216                                         moveExpression(expression, -1);
217                                         updateExpressions();
218                                 }
219                         });
220                         
221                         JButton downButton = new JButton(Icons.DOWN);
222                         downButton.setToolTipText(trans.get("customExpression.Units.but.ttip.MoveDown"));
223                         downButton.setBorderPainted(false);
224                         downButton.setVisible(showDown);
225                         downButton.addActionListener( new ActionListener() {
226                                 @Override
227                                 public void actionPerformed(ActionEvent e) {
228                                         moveExpression(expression, 1);
229                                         updateExpressions();
230                                 }
231                         });
232                         
233                         
234                         JButton deleteButton = new JButton(Icons.DELETE);
235                         //// Remove this expression
236                         deleteButton.setToolTipText(trans.get("customExpression.Units.but.ttip.Remove"));
237                         deleteButton.setBorderPainted(false);
238                         deleteButton.addActionListener(new ActionListener() {
239                                 @Override
240                                 public void actionPerformed(ActionEvent e) {
241                                         deleteExpression(expression);
242                                         updateExpressions();
243                                 }
244                         });
245                         
246                         this.add(nameLabel);
247                         this.add(name, "width 200:200:400, growx");
248                         this.add(new JPanel());
249                         this.add(symbolLabel);
250                         this.add(symbol, "width :50:200");
251                         this.add(new JPanel());
252                         this.add(unitLabel);
253                         this.add(unitSelector, "width :50:100");
254                         this.add(new JPanel(), "growx");
255                         this.add(upButton, "right");
256                         this.add(downButton, "right");
257                         this.add(editButton, "right");
258                         this.add(deleteButton, "right");
259                 }
260         }
261 }