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.OpenRocketDocument;
23 import net.sf.openrocket.document.Simulation;
24 import net.sf.openrocket.gui.util.Icons;
25 import net.sf.openrocket.l10n.Translator;
26 import net.sf.openrocket.logging.LogHelper;
27 import net.sf.openrocket.rocketcomponent.Rocket;
28 import net.sf.openrocket.simulation.customexpression.CustomExpression;
29 import net.sf.openrocket.startup.Application;
32 * Dialog box for making a custom expression
33 * @author Richard Graham
37 public class ExpressionBuilderDialog extends JDialog {
39 private static final Translator trans = Application.getTranslator();
40 private static final LogHelper log = Application.getLogger();
42 private static final ImageIcon GreenIcon = Icons.loadImageIcon("pix/spheres/green-16x16.png", "OK");
43 private static final ImageIcon RedIcon = Icons.loadImageIcon("pix/spheres/red-16x16.png", "Bad");
45 private CustomExpression expression;
46 private CustomExpression previousExpressionCopy;
48 private final Window parentWindow;
49 private final OpenRocketDocument doc;
51 // Define these check indicators to show if fields are OK
52 private final JLabel nameCheck = new JLabel(RedIcon);
53 private final JLabel expressionCheck = new JLabel(RedIcon);
54 private final JLabel unitCheck = new JLabel(RedIcon);
55 private final JButton okButton = new JButton(trans.get("dlg.but.ok"));
56 private final JTextField expressionField = new JTextField(20);
58 public ExpressionBuilderDialog(Window parent, OpenRocketDocument doc){
59 this(parent, doc, new CustomExpression(doc));
62 public ExpressionBuilderDialog(Window parent, final OpenRocketDocument doc, final CustomExpression previousExpression){
64 super(parent, trans.get("ExpressionBuilderDialog.title"), JDialog.ModalityType.DOCUMENT_MODAL);
67 this.parentWindow = parent;
68 this.previousExpressionCopy = (CustomExpression) previousExpression.clone();
69 this.expression = previousExpression;
71 //// Name box -- Check input when focus changes and transfer focus to next box on enter key
72 JLabel nameLabel = new JLabel(trans.get("customExpression.Name"));
73 final JTextField nameField = new JTextField(20);
74 nameField.setText(expression.getName());
75 nameField.setFocusTraversalKeysEnabled(true);
76 nameField.addFocusListener(new FocusListener() {
78 public void focusGained(FocusEvent e) { }
81 public void focusLost(FocusEvent e) {
82 expression.setName(nameField.getText());
83 ExpressionBuilderDialog.this.updateOK();
86 nameField.addActionListener(new ActionListener() {
88 public void actionPerformed(ActionEvent arg0) {
89 nameField.transferFocus();
93 //// Expression box -- for this one we check after each keypress using a keyListener. Enter transfers to next field
94 JLabel expressionLabel = new JLabel(trans.get("customExpression.Expression"));
95 expressionField.setText(expression.getExpressionString());
96 expressionField.addKeyListener(new KeyListener() {
98 public void keyReleased(KeyEvent arg0) {
99 expression.setExpression( expressionField.getText() );
100 ExpressionBuilderDialog.this.updateOK();
104 public void keyPressed(KeyEvent e) {}
107 public void keyTyped(KeyEvent e) {}
109 expressionField.addActionListener(new ActionListener(){
111 public void actionPerformed(ActionEvent e) {
112 expressionField.transferFocus();
116 //// Units box -- with action listeners checking input after change in focus or enter press
117 JLabel unitLabel = new JLabel(trans.get("customExpression.Units"));
118 final JTextField unitField = new JTextField(5);
119 unitField.setText(expression.getUnit());
120 unitField.addFocusListener(new FocusListener(){
122 public void focusLost(FocusEvent arg0) {
123 expression.setUnit(unitField.getText()) ;
124 ExpressionBuilderDialog.this.updateOK();
127 public void focusGained(FocusEvent arg0) {}
129 unitField.addActionListener(new ActionListener() {
131 public void actionPerformed(ActionEvent e) {
132 unitField.transferFocus();
137 JLabel symbolLabel = new JLabel(trans.get("customExpression.Symbol"));
138 final JTextField symbolField = new JTextField(5);
139 symbolField.setText(expression.getSymbol());
140 symbolField.addFocusListener(new FocusListener(){
142 public void focusLost(FocusEvent arg0) {
143 expression.setSymbol(symbolField.getText()) ;
144 ExpressionBuilderDialog.this.updateOK();
147 public void focusGained(FocusEvent arg0) {}
149 symbolField.addActionListener(new ActionListener() {
151 public void actionPerformed(ActionEvent e) {
152 symbolField.transferFocus();
157 //// Insert variable button
158 final JButton insertVariableButton = new JButton(trans.get("ExpressionBuilderDialog.InsertVariable"));
159 insertVariableButton.addActionListener(new ActionListener() {
161 public void actionPerformed(ActionEvent e) {
162 log.debug("Opening insert variable window");
163 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
164 new VariableSelector(parentWindow, ExpressionBuilderDialog.this, doc).setVisible(true);
168 //// Insert operator button
169 final JButton insertOperatorButton = new JButton(trans.get("ExpressionBuilderDialog.InsertOperator"));
170 insertOperatorButton.addActionListener(new ActionListener() {
172 public void actionPerformed(ActionEvent e) {
173 log.debug("Opening insert operator window");
174 Window parentWindow = SwingUtilities.getWindowAncestor(ExpressionBuilderDialog.this);
175 new OperatorSelector(parentWindow, ExpressionBuilderDialog.this).setVisible(true);
180 okButton.setEnabled(false);
181 okButton.addActionListener(new ActionListener() {
183 public void actionPerformed(ActionEvent e) {
184 // add to this simulation
185 expression.addToDocument();
188 ExpressionBuilderDialog.this.dispose();
193 final JButton cancelButton = new JButton(trans.get("dlg.but.cancel"));
194 cancelButton.addActionListener(new ActionListener() {
196 public void actionPerformed(ActionEvent e) {
197 expression.overwrite(previousExpressionCopy);
198 ExpressionBuilderDialog.this.dispose();
203 nameCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Name"));
204 unitCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Symbol"));
205 expressionCheck.setToolTipText(trans.get("ExpressionBuilderDialog.led.ttip.Expression"));
208 JPanel mainPanel = new JPanel(new MigLayout());
209 mainPanel.add(nameLabel);
210 mainPanel.add(nameField);
211 mainPanel.add(nameCheck, "wrap, center");
212 mainPanel.add(symbolLabel);
213 mainPanel.add(symbolField, "split 4, growx");
214 mainPanel.add(new JPanel());
215 mainPanel.add(unitLabel, "right");
216 mainPanel.add(unitField, "right, growx");
217 mainPanel.add(unitCheck, "wrap, center");
218 mainPanel.add(expressionLabel);
219 mainPanel.add(expressionField);
220 mainPanel.add(expressionCheck, "wrap, center");
221 mainPanel.add(insertOperatorButton, "span 2, right, split 2");
222 mainPanel.add(insertVariableButton, "right, wrap");
223 mainPanel.add(cancelButton, "span 2, right, width :50:100");
224 mainPanel.add(okButton, "right, width :50:100, wrap");
229 this.setLocationByPlatform(true);
235 * Enable OK button only if all the fields are ok
238 protected void updateOK() {
240 boolean nameOK = expression.checkName();
241 boolean unitOK = expression.checkUnit();
242 boolean symbolOK = expression.checkSymbol();
243 boolean expressionOK = expression.checkExpression();
245 if (nameOK) { nameCheck.setIcon(GreenIcon); } else { nameCheck.setIcon(RedIcon); }
246 if (unitOK && symbolOK) { unitCheck.setIcon(GreenIcon); } else { unitCheck.setIcon(RedIcon); }
247 if (expressionOK) { expressionCheck.setIcon(GreenIcon); } else { expressionCheck.setIcon(RedIcon); }
249 okButton.setEnabled( nameOK && unitOK && symbolOK && expressionOK );
253 * Inserts a string into the expression box at the position of the cursor.
254 * String will be padded with spaces either side
255 * Expression box will be focused after this is called.
256 * For strings containing an ( , cursor will be moved to the point after that, otherwise, cursor will move to the end of the inserted string.
259 public void pasteIntoExpression(String str) {
260 int pos = expressionField.getCaretPosition();
261 String current = expressionField.getText();
262 expressionField.setText(current.subSequence(0, pos) + " " + str + " " + current.subSequence(pos, current.length()));
263 expressionField.requestFocus();
264 int bracketPos = str.indexOf("(");
265 if (bracketPos != -1){
266 expressionField.setCaretPosition(pos+2+bracketPos);
269 expressionField.setCaretPosition(pos+2+str.length());