001 /* Copyright 2004, David R. Cok
002 Originally generated as part of a GUI interface to the
003 Esc/Java2 application.
004 */
005
006 package escjava.gui;
007
008 import java.lang.reflect.Field;
009 import javax.swing.*;
010 import java.awt.*;
011 import java.awt.event.FocusAdapter;
012 import java.awt.event.FocusEvent;
013 import java.awt.event.ActionEvent;
014 import java.awt.event.ActionListener;
015
016 import escjava.translate.NoWarn;
017 import escjava.ast.TagConstants;
018
019 /** This class creates and maintains a JPanel containing components for
020 controlling the various options that affect the running of the Esc/Java2
021 tool.
022 */
023 public class EscOptions extends JPanel implements ActionListener {
024
025 /** A reference to the Options structure in the ESC tool,
026 which serves as the document for this GUI.
027 */
028 protected escjava.Options doc;
029
030 /** A reference to the Class object of escjava.Options.
031 */
032 static final public /*@non_null*/ Class escoptions = escjava.Options.class;
033
034 /** These are the options that are actually portrayed in the
035 GUI. The array contains the text string, field name and the tooltip.
036 */
037 static /*@non_null*/ String[][] optionsShown = {
038 {"Control of Input:", null, null},
039 {"source 1.4", "assertIsKeyword",
040 "When enabled, Java 1.4 source (including assert statements)\n"+
041 "is parsed; when disabled 'assert' is treated as a nomal identifier" },
042
043 {"enableassertions", "assertionsEnabled",
044 "When enabled, Java assert statements are enabled;\n"+
045 "when disabled, Java assert statements are ignored." },
046 //{"jmlAssertions",
047 // "When enabled, Java assert statements are\n"+
048 // "treated like JML assert statements." },
049 {"parsePlus", "parsePlus",
050 "When enabled, JML annotations in '//@' and\n"+
051 "/*@' comments are parsed by the ESC/Java2 tool" },
052 {"Control of Output:",null,null},
053 {"noCautions", "noCautions",
054 "When enabled, no Caution messages are output" },
055 {"noSemicolonWarnings", "noSemicolonWarnings",
056 "When enabled, no warnings about missing semicolons\n"+
057 "are issued (JML requires terminating semicolons)" },
058 {"noNotCheckedWarnings", "noNotCheckedWarnings",
059 "When enabled, no warnings about JML features that\n"+
060 "are not implemented in ESC/Java2 are issued" },
061
062 {"Debugging:", null, null},
063 {"verbose", "v", "Shows lots of tracing output" },
064 {"showErrorLocation", "showErrorLocation", "TBD description" },
065 {"showDesugaredSpecs", "desugaredSpecs", "TBD description" },
066 //{"pxLog log", "TBD description" },
067 {"pgc", "pgc", "TBD description" },
068 {"pdsa", "pdsa", "TBD description" },
069 {"pvc", "pvc", "TBD description" },
070 //{"testMode", "testMode", "TBD description" },
071 };
072
073 public EscOptions(escjava.Options doc) {
074 build(doc);
075 }
076
077 public void init(escjava.Options doc) {
078 // FIXME - change this so it does not rebuild the GUI every time
079 build(doc);
080 }
081
082 public void build(escjava.Options doc) {
083 this.doc = doc;
084 removeAll();
085 JButton jb;
086 setLayout(new BoxLayout(this,BoxLayout.LINE_AXIS));
087
088 JPanel misc = new JPanel();
089 misc.setLayout(new BoxLayout(misc,BoxLayout.PAGE_AXIS));
090 add(misc);
091 JPanel warningsB = new JPanel();
092 warningsB.setLayout(new BoxLayout(warningsB,BoxLayout.PAGE_AXIS));
093 add(warningsB);
094
095 JPanel warningsHeader = new JPanel();
096 warningsHeader.setLayout(new BoxLayout(warningsHeader,BoxLayout.LINE_AXIS));
097 warningsHeader.setAlignmentX(Component.LEFT_ALIGNMENT);
098 warningsB.add(warningsHeader);
099
100 JPanel warnings = new JPanel(new GridLayout(0,2));
101 warnings.setAlignmentX(Component.LEFT_ALIGNMENT);
102 warningsB.add(warnings);
103
104 warningsB.add(Box.createVerticalGlue());
105
106 warningsHeader.add(new JLabel(" Warning Types: "));
107 //warningsHeader.add(Box.createHorizontalGlue());
108 warningsHeader.add(jb = new JButton("Disable All"));
109 jb.addActionListener( new ActionListener() {
110 public void actionPerformed(/*@non_null*/ActionEvent e) {
111 NoWarn.setAllChkStatus(TagConstants.CHK_AS_ASSUME);
112 init(GUI.gui.options());
113 }
114 });
115 warningsHeader.add(jb = new JButton("Enable All"));
116 jb.addActionListener( new ActionListener() {
117 public void actionPerformed(/*@non_null*/ActionEvent e) {
118 NoWarn.setAllChkStatus(TagConstants.CHK_AS_ASSERT);
119 init(GUI.gui.options());
120 }
121 });
122
123 final JTextField simplify = new JTextField(System.getProperty("simplify"));
124 JPanel simplifyHeader = new JPanel();
125 simplifyHeader.setLayout(new BoxLayout(simplifyHeader,BoxLayout.LINE_AXIS));
126 simplifyHeader.add(new JLabel("Path to SIMPLIFY executable: "));
127 //simplifyHeader.add(Box.createHorizontalGlue());
128 simplifyHeader.add(jb = new JButton("Browse"));
129 jb.addActionListener( new ActionListener() {
130 public void actionPerformed(/*@non_null*/ActionEvent e) {
131 JFileChooser fc = new JFileChooser();
132 fc.setApproveButtonText("Select");
133 int returnVal = fc.showOpenDialog(EscOptions.this);
134 if (returnVal == JFileChooser.APPROVE_OPTION) {
135 java.io.File file = fc.getSelectedFile();
136 String name = file.getAbsolutePath();
137 simplify.setText(name);
138 System.setProperty("simplify",name);
139 }
140 }
141 });
142 simplifyHeader.setAlignmentX(Component.LEFT_ALIGNMENT);
143
144 misc.add(simplifyHeader);
145
146 // For some reason the maximum height of a JTextField is very large,
147 // so it does not behave well in a Boxlayout.
148 simplify.setColumns(30);
149 simplify.setMaximumSize(simplify.getPreferredSize());
150 misc.add(simplify);
151 simplify.addActionListener(
152 new ActionListener() {
153 public void actionPerformed(/*@non_null*/ActionEvent e) {
154 System.setProperty("simplify",simplify.getText());
155 }
156 });
157 simplify.addFocusListener(
158 new FocusAdapter() {
159 public void focusLost(FocusEvent e) {
160 System.setProperty("simplify",simplify.getText());
161 }
162 });
163 simplify.setAlignmentX(Component.LEFT_ALIGNMENT);
164
165 JCheckBox cb;
166 for (int i = 0; i<optionsShown.length; ++i) {
167 String[] opttext = optionsShown[i];
168 if (opttext[1] == null) {
169 misc.add(new JLabel(opttext[0]));
170 } else {
171 try {
172 boolean b = false;
173 try {
174 Field f = escoptions.getField(opttext[1]);
175 b = f.getBoolean(escjava.Main.options());
176 } catch (Exception e) {
177 // Some options do not have fields. These are special
178 // cases and are ok. We presume they are false by
179 // default.
180 }
181 cb = new JCheckBox(opttext[0],b);
182 cb.setAlignmentX(Component.LEFT_ALIGNMENT);
183 cb.setToolTipText(opttext[2]);
184 cb.addActionListener(this);
185 misc.add(cb);
186 } catch (Exception e) {
187 JOptionPane.showMessageDialog(this,
188 "Please report an INTERNAL ERROR: " + Project.eol +
189 "An exception occurred while building the GUI " +
190 "component with label " + opttext[0] + Project.eol +
191 e);
192 }
193 }
194 }
195 misc.add(Box.createVerticalGlue());
196
197 ActionListener a = new MListener();
198 String[] wnames = escjava.ast.TagConstants.escchecks;
199 int n = wnames.length-4;
200 int nn = n/2;
201 int np =n-nn;
202 for (int i=0; i<nn; ++i) {
203 makeWarningOpt(wnames[i],warnings,a);
204 makeWarningOpt(wnames[i+np],warnings,a);
205 }
206 if (n%2 == 1) {
207 makeWarningOpt(wnames[nn],warnings,a);
208 }
209 }
210
211 public void makeWarningOpt(/*@non_null*/ String name,
212 /*@non_null*/ JPanel warnings,
213 /*@non_null*/ ActionListener a) {
214 int tag = NoWarn.toNoWarnTag(name);
215 boolean b = NoWarn.getChkStatus(tag) != TagConstants.CHK_AS_ASSUME;
216 JCheckBox cb = new JCheckBox(name,b);
217 warnings.add(cb);
218 cb.addActionListener(a);
219 //cb.setToolTipText(opttext[2]);
220 }
221
222 //@ also
223 //@ requires e != null;
224 public void actionPerformed(/*@non_null*/ActionEvent e) {
225 // write back out to the Options structure
226
227 Object source = e.getSource();
228 String name = null;
229 if (source instanceof JCheckBox) {
230 String fname = null;
231 name = ((JCheckBox)source).getText();
232 for (int i=0; i<optionsShown.length; ++i) {
233 if (name.equals(optionsShown[i][0])) {
234 fname = optionsShown[i][1];
235 break;
236 }
237 }
238 boolean value = ((JCheckBox)source).isSelected();
239 if (fname == null) {
240 JOptionPane.showMessageDialog(this,
241 "Please report an INTERNAL ERROR: " + Project.eol +
242 "GUI references an unlisted option - " + name);
243 } else if (fname.equals("v")) {
244 javafe.util.Info.on = value;
245 } else try {
246 Field f = escoptions.getField(fname);
247 f.setBoolean(escjava.Main.options(),value);
248 } catch (Exception ee) {
249 JOptionPane.showMessageDialog(this,
250 "Please report an INTERNAL ERROR: " + Project.eol +
251 "GUI failed to find an option " + fname +
252 " for checkbox labeled " + name);
253 }
254 } else {
255 JOptionPane.showMessageDialog(this,
256 "Please report an INTERNAL ERROR: " + Project.eol +
257 "GUI named " + name +
258 " is an unsupported component of type " + source.getClass());
259 }
260 }
261
262 static public class MListener implements ActionListener {
263 static private /*@non_null*/ String[] temp = new String[1];
264 //@ also
265 //@ requires e != null;
266 public void actionPerformed(/*@non_null*/ActionEvent e) {
267 Object o = e.getSource();
268 if (o instanceof JCheckBox) {
269 JCheckBox cb = (JCheckBox)o;
270 boolean b = cb.isSelected();
271 temp[0] = cb.getText();
272 try {
273 GUI.gui.options.processOption(
274 b ? "-warn" : "-nowarn", temp, 0);
275 } catch (javafe.util.UsageError ee) {
276 // FIXME - internal error if this happens
277 }
278 }
279 }
280 }
281
282 }