1 package net.sf.openrocket.gui.customexpression;
3 import java.awt.Window;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.awt.event.FocusEvent;
7 import java.awt.event.FocusListener;
8 import java.awt.event.KeyEvent;
9 import java.awt.event.KeyListener;
11 import javax.swing.ImageIcon;
12 import javax.swing.JButton;
13 import javax.swing.JDialog;
14 import javax.swing.JLabel;
15 import javax.swing.JPanel;
16 import javax.swing.JTextField;
17 import javax.swing.SwingUtilities;
19 import net.miginfocom.swing.MigLayout;
20 import net.sf.openrocket.document.Simulation;
21 import net.sf.openrocket.gui.util.Icons;
22 import net.sf.openrocket.l10n.Translator;
23 import net.sf.openrocket.logging.LogHelper;
24 import net.sf.openrocket.simulation.CustomExpression;
25 import net.sf.openrocket.startup.Application;
28 * Dialog box for making a custom expression
29 * @author Richard Graham
33 public class ExpressionBuilderDialog extends JDialog {
35 private static final Translator trans = Application.getTranslator();
36 private static final LogHelper log = Application.getLogger();
38 private static final ImageIcon GreenIcon = Icons.loadImageIcon("pix/spheres/green-16x16.png", "OK");
39 private static final ImageIcon RedIcon = Icons.loadImageIcon("pix/spheres/red-16x16.png", "Bad");
41 private CustomExpression expression;
42 private CustomExpression previousExpressionCopy;
44 private final Window parentWindow;
45 private final Simulation simulation;
47 // Define these check indicators to show if fields are OK
48 private final JLabel nameCheck = new JLabel(RedIcon);
49 private final JLabel expressionCheck = new JLabel(RedIcon);
50 private final JLabel unitCheck = new JLabel(RedIcon);
51 private final JButton okButton = new JButton(trans.get("dlg.but.ok"));
52 private final JTextField expressionField = new JTextField(20);
54 public ExpressionBuilderDialog(Window parent, Simulation simulation){
55 this(parent, simulation, new CustomExpression(simulation));
58 public ExpressionBuilderDialog(Window parent, final Simulation simulation, final CustomExpression previousExpression){
60 super(parent, trans.get("ExpressionBuilderDialog.title"), JDialog.ModalityType.DOCUMENT_MODAL);
62 this.parentWindow = parent;
63 this.simulation = simulation;
64 this.previousExpressionCopy = (CustomExpression) previousExpression.clone();
65 this.expression = previousExpression;
67 //// Name box -- Check input when focus changes and transfer focus to next box on enter key
68 JLabel nameLabel = new JLabel(trans.get("customExpression.Name"));
69 final JTextField nameField = new JTextField(20);
70 nameField.setText(expression.getName());
71 nameField.setFocusTraversalKeysEnabled(true);
72 nameField.addFocusListener(new FocusListener() {
74 public void focusGained(FocusEvent e) { }
77 public void focusLost(FocusEvent e) {
78 expression.setName(nameField.getText());
79 ExpressionBuilderDialog.this.updateOK();
82 nameField.addActionListener(new ActionListener() {
84 public void actionPerformed(ActionEvent arg0) {
85 nameField.transferFocus();
89 //// Expression box -- for this one we check after each keypress using a keyListener. Enter transfers to next field
90 JLabel expressionLabel = new JLabel(trans.get("customExpression.Expression"));
91 expressionField.setText(expression.getExpressionString());
92 expressionField.addKeyListener(new KeyListener() {
94 public void keyReleased(KeyEvent arg0) {
95 expression.setExpression( expressionField.getText() );
96 ExpressionBuilderDialog.this.updateOK();
100 public void keyPressed(KeyEvent e) {}
103 public void keyTyped(KeyEvent e) {}
105 expressionField.addActionListener(new ActionListener(){
107 public void actionPerformed(ActionEvent e) {
108 expressionField.transferFocus();
112 //// Units box -- with action listeners checking input after change in focus or enter press
113 JLabel unitLabel = new JLabel(trans.get("customExpression.Units"));
114 final JTextField unitField = new JTextField(5);
115 unitField.setText(expression.getUnit());
116 unitField.addFocusListener(new FocusListener(){
118 public void focusLost(FocusEvent arg0) {
119 expression.setUnit(unitField.getText()) ;
120 ExpressionBuilderDialog.this.updateOK();
123 public void focusGained(FocusEvent arg0) {}
125 unitField.addActionListener(new ActionListener() {
127 public void actionPerformed(ActionEvent e) {
128 unitField.transferFocus();
133 JLabel symbolLabel = new JLabel(trans.get("customExpression.Symbol"));
134 final JTextField symbolField = new JTextField(5);
135 symbolField.setText(expression.getSymbol());
136 symbolField.addFocusListener(new FocusListener(){
138 public void focusLost(FocusEvent arg0) {
139 expression.setSymbol(symbolField.getText()) ;
140 ExpressionBuilderDialog.this.updateOK();
143 public void focusGained(FocusEvent arg0) {}
145 symbolField.addActionListener(new ActionListener() {
147 public void actionPerformed(ActionEvent e) {
148 symbolField.transferFocus();
153 //// Insert variable button
154 final JButton insertVariableButton = new JButton(trans.get("ExpressionBuilderDialog.InsertVariable"));
155 insertVariableButton.addActionListener(new ActionListener() {
157 public void actionPerformed(ActionEvent e) {
158 log.debug("Opening insert variable window");
159 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
160 new VariableSelector(parentWindow, ExpressionBuilderDialog.this, simulation).setVisible(true);
164 //// Insert operator button
165 final JButton insertOperatorButton = new JButton(trans.get("ExpressionBuilderDialog.InsertOperator"));
166 insertOperatorButton.addActionListener(new ActionListener() {
168 public void actionPerformed(ActionEvent e) {
169 log.debug("Opening insert operator window");
170 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
171 new OperatorSelector(parentWindow, ExpressionBuilderDialog.this).setVisible(true);
177 okButton.setEnabled(false);
178 okButton.addActionListener(new ActionListener() {
180 public void actionPerformed(ActionEvent e) {
181 expression.addToSimulation();
182 ExpressionBuilderDialog.this.dispose();
187 final JButton cancelButton = new JButton(trans.get("dlg.but.cancel"));
188 cancelButton.addActionListener(new ActionListener() {
190 public void actionPerformed(ActionEvent e) {
191 expression.overwrite(previousExpressionCopy);
192 ExpressionBuilderDialog.this.dispose();
197 nameCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Name"));
198 unitCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Symbol"));
199 expressionCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Expression"));
202 JPanel mainPanel = new JPanel(new MigLayout());
203 mainPanel.add(nameLabel);
204 mainPanel.add(nameField);
205 mainPanel.add(nameCheck, "wrap, center");
206 mainPanel.add(symbolLabel);
207 mainPanel.add(symbolField, "split 4, growx");
208 mainPanel.add(new JPanel());
209 mainPanel.add(unitLabel, "right");
210 mainPanel.add(unitField, "right, growx");
211 mainPanel.add(unitCheck, "wrap, center");
212 mainPanel.add(expressionLabel);
213 mainPanel.add(expressionField);
214 mainPanel.add(expressionCheck, "wrap, center");
215 mainPanel.add(insertOperatorButton, "span 2, right, split 2");
216 mainPanel.add(insertVariableButton, "right, wrap");
217 mainPanel.add(cancelButton, "span 2, right, width :50:100");
218 mainPanel.add(okButton, "right, width :50:100, wrap");
223 this.setLocationByPlatform(true);
229 * Enable OK button only if all the fields are ok
232 protected void updateOK() {
234 boolean nameOK = expression.checkName();
235 boolean unitOK = expression.checkUnit();
236 boolean symbolOK = expression.checkSymbol();
237 boolean expressionOK = expression.checkExpression();
239 if (nameOK) { nameCheck.setIcon(GreenIcon); } else { nameCheck.setIcon(RedIcon); }
240 if (unitOK && symbolOK) { unitCheck.setIcon(GreenIcon); } else { unitCheck.setIcon(RedIcon); }
241 if (expressionOK) { expressionCheck.setIcon(GreenIcon); } else { expressionCheck.setIcon(RedIcon); }
243 okButton.setEnabled( nameOK && unitOK && symbolOK && expressionOK );
247 * Inserts a string into the expression box at the position of the cursor.
248 * String will be padded with spaces either side
249 * Expression box will be focused after this is called.
250 * For strings containing an ( , cursor will be moved to the point after that, otherwise, cursor will move to the end of the inserted string.
253 public void pasteIntoExpression(String str) {
254 int pos = expressionField.getCaretPosition();
255 String current = expressionField.getText();
256 expressionField.setText(current.subSequence(0, pos) + " " + str + " " + current.subSequence(pos, current.length()));
257 expressionField.requestFocus();
258 int bracketPos = str.indexOf("(");
259 if (bracketPos != -1){
260 expressionField.setCaretPosition(pos+2+bracketPos);
263 expressionField.setCaretPosition(pos+2+str.length());