    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    }