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(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(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(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(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(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(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 }