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.JCheckBox;
14 import javax.swing.JDialog;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17 import javax.swing.JTextField;
18 import javax.swing.SwingConstants;
19 import javax.swing.SwingUtilities;
21 import net.miginfocom.swing.MigLayout;
22 import net.sf.openrocket.document.Simulation;
23 import net.sf.openrocket.gui.util.Icons;
24 import net.sf.openrocket.l10n.Translator;
25 import net.sf.openrocket.logging.LogHelper;
26 import net.sf.openrocket.simulation.CustomExpression;
27 import net.sf.openrocket.startup.Application;
30 * Dialog box for making a custom expression
31 * @author Richard Graham
35 public class ExpressionBuilderDialog extends JDialog {
37 private static final Translator trans = Application.getTranslator();
38 private static final LogHelper log = Application.getLogger();
40 private static final ImageIcon GreenIcon = Icons.loadImageIcon("pix/spheres/green-16x16.png", "OK");
41 private static final ImageIcon RedIcon = Icons.loadImageIcon("pix/spheres/red-16x16.png", "Bad");
43 private CustomExpression expression;
44 private CustomExpression previousExpressionCopy;
46 private final Window parentWindow;
47 private final Simulation simulation;
49 // Define these check indicators to show if fields are OK
50 private final JLabel nameCheck = new JLabel(RedIcon);
51 private final JLabel expressionCheck = new JLabel(RedIcon);
52 private final JLabel unitCheck = new JLabel(RedIcon);
53 private final JButton okButton = new JButton(trans.get("dlg.but.ok"));
54 private final JTextField expressionField = new JTextField(20);
56 public ExpressionBuilderDialog(Window parent, Simulation simulation){
57 this(parent, simulation, new CustomExpression(simulation));
60 public ExpressionBuilderDialog(Window parent, final Simulation simulation, final CustomExpression previousExpression){
62 super(parent, trans.get("ExpressionBuilderDialog.title"), JDialog.ModalityType.DOCUMENT_MODAL);
64 this.parentWindow = parent;
65 this.simulation = simulation;
66 this.previousExpressionCopy = (CustomExpression) previousExpression.clone();
67 this.expression = previousExpression;
69 //// Name box -- Check input when focus changes and transfer focus to next box on enter key
70 JLabel nameLabel = new JLabel(trans.get("customExpression.Name"));
71 final JTextField nameField = new JTextField(20);
72 nameField.setText(expression.getName());
73 nameField.setFocusTraversalKeysEnabled(true);
74 nameField.addFocusListener(new FocusListener() {
76 public void focusGained(FocusEvent e) { }
79 public void focusLost(FocusEvent e) {
80 expression.setName(nameField.getText());
81 ExpressionBuilderDialog.this.updateOK();
84 nameField.addActionListener(new ActionListener() {
86 public void actionPerformed(ActionEvent arg0) {
87 nameField.transferFocus();
91 //// Expression box -- for this one we check after each keypress using a keyListener. Enter transfers to next field
92 JLabel expressionLabel = new JLabel(trans.get("customExpression.Expression"));
93 expressionField.setText(expression.getExpressionString());
94 expressionField.addKeyListener(new KeyListener() {
96 public void keyReleased(KeyEvent arg0) {
97 expression.setExpression( expressionField.getText() );
98 ExpressionBuilderDialog.this.updateOK();
102 public void keyPressed(KeyEvent e) {}
105 public void keyTyped(KeyEvent e) {}
107 expressionField.addActionListener(new ActionListener(){
109 public void actionPerformed(ActionEvent e) {
110 expressionField.transferFocus();
114 //// Units box -- with action listeners checking input after change in focus or enter press
115 JLabel unitLabel = new JLabel(trans.get("customExpression.Units"));
116 final JTextField unitField = new JTextField(5);
117 unitField.setText(expression.getUnit());
118 unitField.addFocusListener(new FocusListener(){
120 public void focusLost(FocusEvent arg0) {
121 expression.setUnit(unitField.getText()) ;
122 ExpressionBuilderDialog.this.updateOK();
125 public void focusGained(FocusEvent arg0) {}
127 unitField.addActionListener(new ActionListener() {
129 public void actionPerformed(ActionEvent e) {
130 unitField.transferFocus();
135 JLabel symbolLabel = new JLabel(trans.get("customExpression.Symbol"));
136 final JTextField symbolField = new JTextField(5);
137 symbolField.setText(expression.getSymbol());
138 symbolField.addFocusListener(new FocusListener(){
140 public void focusLost(FocusEvent arg0) {
141 expression.setSymbol(symbolField.getText()) ;
142 ExpressionBuilderDialog.this.updateOK();
145 public void focusGained(FocusEvent arg0) {}
147 symbolField.addActionListener(new ActionListener() {
149 public void actionPerformed(ActionEvent e) {
150 symbolField.transferFocus();
155 //// Insert variable button
156 final JButton insertVariableButton = new JButton(trans.get("ExpressionBuilderDialog.InsertVariable"));
157 insertVariableButton.addActionListener(new ActionListener() {
159 public void actionPerformed(ActionEvent e) {
160 log.debug("Opening insert variable window");
161 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
162 new VariableSelector(parentWindow, ExpressionBuilderDialog.this, simulation).setVisible(true);
166 //// Insert operator button
167 final JButton insertOperatorButton = new JButton(trans.get("ExpressionBuilderDialog.InsertOperator"));
168 insertOperatorButton.addActionListener(new ActionListener() {
170 public void actionPerformed(ActionEvent e) {
171 log.debug("Opening insert operator window");
172 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
173 new OperatorSelector(parentWindow, ExpressionBuilderDialog.this).setVisible(true);
177 //// Copy expression check box
178 final JCheckBox copyCheckBox = new JCheckBox(trans.get("ExpressionBuilderDialog.CopyToOtherSimulations"));
179 copyCheckBox.setHorizontalTextPosition(SwingConstants.LEFT);
180 copyCheckBox.setToolTipText(trans.get("ExpressionBuilderDialog.CopyToOtherSimulations.ttip"));
183 okButton.setEnabled(false);
184 okButton.addActionListener(new ActionListener() {
186 public void actionPerformed(ActionEvent e) {
187 // add to this simulation
188 expression.addToSimulation();
189 if (copyCheckBox.isSelected()){
190 expression.copyToOtherSimulations();
194 ExpressionBuilderDialog.this.dispose();
199 final JButton cancelButton = new JButton(trans.get("dlg.but.cancel"));
200 cancelButton.addActionListener(new ActionListener() {
202 public void actionPerformed(ActionEvent e) {
203 expression.overwrite(previousExpressionCopy);
204 ExpressionBuilderDialog.this.dispose();
209 nameCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Name"));
210 unitCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Symbol"));
211 expressionCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Expression"));
214 JPanel mainPanel = new JPanel(new MigLayout());
215 mainPanel.add(nameLabel);
216 mainPanel.add(nameField);
217 mainPanel.add(nameCheck, "wrap, center");
218 mainPanel.add(symbolLabel);
219 mainPanel.add(symbolField, "split 4, growx");
220 mainPanel.add(new JPanel());
221 mainPanel.add(unitLabel, "right");
222 mainPanel.add(unitField, "right, growx");
223 mainPanel.add(unitCheck, "wrap, center");
224 mainPanel.add(expressionLabel);
225 mainPanel.add(expressionField);
226 mainPanel.add(expressionCheck, "wrap, center");
227 mainPanel.add(insertOperatorButton, "span 2, right, split 2");
228 mainPanel.add(insertVariableButton, "right, wrap");
229 mainPanel.add(copyCheckBox, "span 2, right, wrap");
230 mainPanel.add(cancelButton, "span 2, right, width :50:100");
231 mainPanel.add(okButton, "right, width :50:100, wrap");
236 this.setLocationByPlatform(true);
242 * Enable OK button only if all the fields are ok
245 protected void updateOK() {
247 boolean nameOK = expression.checkName();
248 boolean unitOK = expression.checkUnit();
249 boolean symbolOK = expression.checkSymbol();
250 boolean expressionOK = expression.checkExpression();
252 if (nameOK) { nameCheck.setIcon(GreenIcon); } else { nameCheck.setIcon(RedIcon); }
253 if (unitOK && symbolOK) { unitCheck.setIcon(GreenIcon); } else { unitCheck.setIcon(RedIcon); }
254 if (expressionOK) { expressionCheck.setIcon(GreenIcon); } else { expressionCheck.setIcon(RedIcon); }
256 okButton.setEnabled( nameOK && unitOK && symbolOK && expressionOK );
260 * Inserts a string into the expression box at the position of the cursor.
261 * String will be padded with spaces either side
262 * Expression box will be focused after this is called.
263 * For strings containing an ( , cursor will be moved to the point after that, otherwise, cursor will move to the end of the inserted string.
266 public void pasteIntoExpression(String str) {
267 int pos = expressionField.getCaretPosition();
268 String current = expressionField.getText();
269 expressionField.setText(current.subSequence(0, pos) + " " + str + " " + current.subSequence(pos, current.length()));
270 expressionField.requestFocus();
271 int bracketPos = str.indexOf("(");
272 if (bracketPos != -1){
273 expressionField.setCaretPosition(pos+2+bracketPos);
276 expressionField.setCaretPosition(pos+2+str.length());