Clover coverage report - DrJava Test Coverage (drjava-20120304-r5456)
Coverage timestamp: Sun Mar 4 2012 03:13:23 CST
file stats: LOC: 741   Methods: 42
NCLOC: 533   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
ProjectPropertiesFrame.java 0% 0% 0% 0%
coverage
 1    /*BEGIN_COPYRIGHT_BLOCK
 2    *
 3    * Copyright (c) 2001-2010, JavaPLT group at Rice University (drjava@rice.edu)
 4    * All rights reserved.
 5    *
 6    * Redistribution and use in source and binary forms, with or without
 7    * modification, are permitted provided that the following conditions are met:
 8    * * Redistributions of source code must retain the above copyright
 9    * notice, this list of conditions and the following disclaimer.
 10    * * Redistributions in binary form must reproduce the above copyright
 11    * notice, this list of conditions and the following disclaimer in the
 12    * documentation and/or other materials provided with the distribution.
 13    * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
 14    * names of its contributors may be used to endorse or promote products
 15    * derived from this software without specific prior written permission.
 16    *
 17    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 20    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 21    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 22    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 23    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 24    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 25    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 26    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 27    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 28    *
 29    * This software is Open Source Initiative approved Open Source Software.
 30    * Open Source Initative Approved is a trademark of the Open Source Initiative.
 31    *
 32    * This file is part of DrJava. Download the current version of this project
 33    * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
 34    *
 35    * END_COPYRIGHT_BLOCK*/
 36   
 37    package edu.rice.cs.drjava.ui;
 38   
 39    import java.awt.event.*;
 40    import java.awt.*;
 41    import java.io.IOException;
 42    import java.io.File;
 43    import java.util.ArrayList;
 44    import java.util.Vector;
 45    import java.util.Map;
 46    import java.util.HashMap;
 47    import javax.swing.*;
 48    import javax.swing.event.*;
 49    import javax.swing.border.EmptyBorder;
 50   
 51    import edu.rice.cs.drjava.model.SingleDisplayModel;
 52    import edu.rice.cs.drjava.config.Option;
 53    import edu.rice.cs.drjava.config.OptionParser;
 54    import edu.rice.cs.drjava.config.OptionConstants;
 55    import edu.rice.cs.drjava.config.OptionListener;
 56    import edu.rice.cs.drjava.config.OptionEvent;
 57    import edu.rice.cs.drjava.ui.config.*;
 58    import edu.rice.cs.drjava.DrJava;
 59   
 60    import edu.rice.cs.plt.iter.IterUtil;
 61    import edu.rice.cs.plt.collect.CollectUtil;
 62    import edu.rice.cs.plt.lambda.Runnable1;
 63    import edu.rice.cs.plt.lambda.LambdaUtil;
 64   
 65    import edu.rice.cs.util.FileOps;
 66    import edu.rice.cs.util.AbsRelFile;
 67    import edu.rice.cs.util.swing.FileSelectorComponent;
 68    import edu.rice.cs.util.swing.DirectorySelectorComponent;
 69    import edu.rice.cs.util.swing.DirectoryChooser;
 70    import edu.rice.cs.util.swing.FileChooser;
 71    import edu.rice.cs.util.swing.SwingFrame;
 72    import edu.rice.cs.util.swing.Utilities;
 73   
 74    import javax.swing.filechooser.FileFilter;
 75   
 76    /** A frame for setting Project Preferences */
 77    public class ProjectPropertiesFrame extends SwingFrame {
 78   
 79    private static final int FRAME_WIDTH = 503;
 80    private static final int FRAME_HEIGHT = 500;
 81   
 82    private MainFrame _mainFrame;
 83    private SingleDisplayModel _model;
 84   
 85    private final JButton _okButton;
 86    private final JButton _applyButton;
 87    private final JButton _cancelButton;
 88    private final JButton _advancedButton;
 89    // private JButton _saveSettingsButton;
 90    private JPanel _mainPanel;
 91   
 92    private DirectorySelectorComponent _projRootSelector;
 93    private DirectorySelectorComponent _buildDirSelector;
 94    private DirectorySelectorComponent _workDirSelector;
 95    private JTextField _mainDocumentSelector;
 96   
 97    private JCheckBox _autoRefreshComponent;
 98   
 99    private VectorAbsRelFileOptionComponent _extraClassPathList;
 100    private VectorFileOptionComponent _excludedFilesList;
 101    private Map<OptionParser<?>,String> _storedPreferences = new HashMap<OptionParser<?>,String>();
 102   
 103    /** Constructs project properties frame for a new project and displays it. Assumes that a project is active. */
 104  0 public ProjectPropertiesFrame(MainFrame mf) {
 105  0 super("Project Properties");
 106   
 107    // Utilities.show("ProjectPropertiesFrame(" + mf + ", " + projFile + ")");
 108   
 109  0 _mainFrame = mf;
 110  0 _model = _mainFrame.getModel();
 111  0 _mainPanel= new JPanel();
 112   
 113  0 Action okAction = new AbstractAction("OK") {
 114  0 public void actionPerformed(ActionEvent e) {
 115    // Always apply and save settings
 116  0 boolean successful = true;
 117  0 successful = saveSettings();
 118  0 if (successful) ProjectPropertiesFrame.this.setVisible(false);
 119  0 reset();
 120    }
 121    };
 122  0 _okButton = new JButton(okAction);
 123   
 124  0 Action advancedAction = new AbstractAction("Advanced") {
 125  0 public void actionPerformed(ActionEvent e) {
 126  0 advancedSettings();
 127    }
 128    };
 129  0 _advancedButton = new JButton(advancedAction);
 130   
 131  0 Action applyAction = new AbstractAction("Apply") {
 132  0 public void actionPerformed(ActionEvent e) {
 133    // Always save settings
 134  0 saveSettings();
 135  0 reset();
 136    }
 137    };
 138  0 _applyButton = new JButton(applyAction);
 139   
 140  0 Action cancelAction = new AbstractAction("Cancel") {
 141  0 public void actionPerformed(ActionEvent e) { cancel(); }
 142    };
 143  0 _cancelButton = new JButton(cancelAction);
 144   
 145  0 init();
 146  0 initDone(); // call mandated by SwingFrame contract
 147    }
 148   
 149    /** Initializes the components in this frame. */
 150  0 private void init() {
 151  0 _setupPanel(_mainPanel);
 152  0 JScrollPane scrollPane = new JScrollPane(_mainPanel);
 153  0 Container cp = getContentPane();
 154   
 155  0 GridBagLayout cpLayout = new GridBagLayout();
 156  0 GridBagConstraints c = new GridBagConstraints();
 157  0 cp.setLayout(cpLayout);
 158   
 159  0 c.fill = GridBagConstraints.BOTH;
 160  0 c.anchor = GridBagConstraints.NORTH;
 161  0 c.gridwidth = GridBagConstraints.REMAINDER;
 162  0 c.gridheight = GridBagConstraints.RELATIVE;
 163  0 c.weightx = 1.0;
 164  0 c.weighty = 1.0;
 165  0 cpLayout.setConstraints(scrollPane, c);
 166  0 cp.add(scrollPane);
 167   
 168    // Add buttons
 169  0 JPanel bottom = new JPanel();
 170  0 bottom.setBorder(new EmptyBorder(5,5,5,5));
 171  0 bottom.setLayout(new BoxLayout(bottom, BoxLayout.X_AXIS));
 172  0 bottom.add(Box.createHorizontalGlue());
 173  0 bottom.add(_advancedButton);
 174  0 bottom.add(_applyButton);
 175  0 bottom.add(_okButton);
 176  0 bottom.add(_cancelButton);
 177  0 bottom.add(Box.createHorizontalGlue());
 178   
 179  0 c.fill = GridBagConstraints.NONE;
 180  0 c.anchor = GridBagConstraints.SOUTH;
 181  0 c.gridheight = GridBagConstraints.REMAINDER;
 182  0 c.weighty = 0.0;
 183  0 cpLayout.setConstraints(bottom, c);
 184  0 cp.add(bottom);
 185   
 186    // Set all dimensions ----
 187  0 Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
 188  0 if (dim.width>FRAME_WIDTH) { dim.width = FRAME_WIDTH; }
 189  0 else { dim.width -= 80; }
 190  0 if (dim.height>FRAME_HEIGHT) { dim.height = FRAME_HEIGHT; }
 191  0 else { dim.height -= 80; }
 192  0 setSize(dim);
 193  0 Utilities.setPopupLoc(this, _mainFrame);
 194   
 195  0 reset();
 196    }
 197   
 198    /** Resets the frame and hides it. */
 199  0 public void cancel() {
 200  0 reset();
 201  0 _applyButton.setEnabled(false);
 202  0 ProjectPropertiesFrame.this.setVisible(false);
 203    }
 204   
 205  0 public void reset() { reset(_model.getProjectRoot()); }
 206   
 207  0 private void reset(File projRoot) {
 208    // Utilities.show("reset(" + projRoot + ")");
 209  0 _projRootSelector.setFileField(projRoot);
 210   
 211  0 final File bd = _model.getBuildDirectory();
 212  0 final JTextField bdTextField = _buildDirSelector.getFileField();
 213  0 if (bd == FileOps.NULL_FILE) bdTextField.setText("");
 214  0 else _buildDirSelector.setFileField(bd);
 215   
 216  0 final File wd = _model.getWorkingDirectory();
 217  0 final JTextField wdTextField = _workDirSelector.getFileField();
 218  0 if (wd == FileOps.NULL_FILE) wdTextField.setText("");
 219  0 else _workDirSelector.setFileField(wd);
 220   
 221  0 final String mc = _model.getMainClass();
 222  0 final JTextField mcTextField = _mainDocumentSelector;
 223  0 if (mc == null) mcTextField.setText("");
 224  0 else mcTextField.setText(mc);
 225   
 226  0 _autoRefreshComponent.setSelected(_getAutoRefreshStatus());
 227   
 228  0 ArrayList<AbsRelFile> cp = new ArrayList<AbsRelFile>(CollectUtil.makeList(_model.getExtraClassPath()));
 229  0 _extraClassPathList.setValue(cp);
 230   
 231  0 ArrayList<File> ef = new ArrayList<File>();
 232  0 for(File f: _model.getExclFiles()) { ef.add(f); }
 233  0 _excludedFilesList.setValue(ef);
 234   
 235  0 _storedPreferences.clear();
 236  0 _storedPreferences.putAll(_model.getPreferencesStoredInProject());
 237   
 238  0 _applyButton.setEnabled(false);
 239    }
 240   
 241    /** Caches the settings in the global model */
 242  0 public boolean saveSettings() {//throws IOException {
 243  0 boolean projRootChanged = false;
 244   
 245  0 File pr = _projRootSelector.getFileFromField();
 246    // if (_projRootSelector.getFileField().getText().equals("")) { pr = FileOps.NULL_FILE; } else {
 247  0 if (!pr.equals(_model.getProjectRoot())) {
 248  0 _model.setProjectRoot(pr);
 249  0 projRootChanged = true;
 250    }
 251    // }
 252   
 253  0 File bd = _buildDirSelector.getFileFromField();
 254  0 if (_buildDirSelector.getFileField().getText().equals("")) bd = FileOps.NULL_FILE;
 255  0 _model.setBuildDirectory(bd);
 256   
 257  0 File wd = _workDirSelector.getFileFromField();
 258  0 if (_workDirSelector.getFileField().getText().equals("")) wd = FileOps.NULL_FILE;
 259  0 _model.setWorkingDirectory(wd);
 260   
 261  0 String mc = _mainDocumentSelector.getText();
 262  0 if(mc == null) mc = "";
 263  0 _model.setMainClass(mc);
 264   
 265  0 Vector<AbsRelFile> extras = _extraClassPathList.getValue(); // Vector mandated by interface to VectorFileOptionComponent
 266  0 _model.setExtraClassPath(IterUtil.snapshot(extras));
 267   
 268  0 _model.setAutoRefreshStatus(_autoRefreshComponent.isSelected());
 269   
 270  0 _model.setExcludedFiles(_excludedFilesList.getValue().toArray(new File[0]));
 271   
 272    // _mainFrame.saveProject();
 273  0 if (projRootChanged) {
 274  0 try {
 275  0 _model.reloadProject(_mainFrame.getCurrentProject(), _mainFrame.gatherProjectDocInfo());
 276  0 } catch(IOException e) { throw new edu.rice.cs.util.UnexpectedException(e, "I/O error while reloading project"); }
 277    }
 278  0 _model.setPreferencesStoredInProject(_storedPreferences);
 279   
 280  0 return true;
 281    }
 282   
 283    /** Returns the current project root in the project profile. */
 284  0 private File _getProjRoot() {
 285  0 File projRoot = _model.getProjectRoot();
 286  0 if (projRoot != null) return projRoot;
 287  0 return FileOps.NULL_FILE;
 288    }
 289   
 290    /** Returns the current build directory in the project profile. */
 291  0 private File _getBuildDir() {
 292  0 File buildDir = _model.getBuildDirectory();
 293  0 if (buildDir != null) return buildDir;
 294  0 return FileOps.NULL_FILE;
 295    }
 296   
 297    /** Returns the current working directory in the project profile (FileOption.NULL_FILE if none is set) */
 298  0 private File _getWorkDir() {
 299  0 File workDir = _model.getWorkingDirectory();
 300  0 if (workDir != null) return workDir;
 301  0 return FileOps.NULL_FILE;
 302    }
 303   
 304    /** Returns the file contianing the main class in the project profile (FileOption.NULL_FILE if none is set) */
 305  0 private File _getMainFile() {
 306  0 File mainFile = _model.getMainClassContainingFile();
 307  0 if (mainFile != null) return mainFile;
 308  0 return FileOps.NULL_FILE;
 309    }
 310   
 311    /** Returns the fully-qualified name of the main class in the project profile ("" if none is set) */
 312  0 private String _getMainClass(){
 313  0 String mainClass = _model.getMainClass();
 314  0 if(mainClass == null) return "";
 315   
 316  0 return mainClass;
 317    }
 318   
 319    /** Returns whether the project is set to automatically open new source files */
 320  0 private boolean _getAutoRefreshStatus() {
 321  0 return _model.getAutoRefreshStatus();
 322    }
 323   
 324  0 private void _setupPanel(JPanel panel) {
 325  0 GridBagLayout gridbag = new GridBagLayout();
 326  0 GridBagConstraints c = new GridBagConstraints();
 327  0 panel.setLayout(gridbag);
 328  0 c.fill = GridBagConstraints.HORIZONTAL;
 329  0 Insets labelInsets = new Insets(5, 10, 0, 0);
 330  0 Insets compInsets = new Insets(5, 5, 0, 10);
 331   
 332    // Project Root
 333   
 334  0 c.weightx = 0.0;
 335  0 c.gridwidth = 1;
 336  0 c.insets = labelInsets;
 337   
 338  0 JLabel prLabel = new JLabel("Project Root");
 339  0 prLabel.setToolTipText("<html>The root directory for the project source files .<br>" +
 340    "If not specified, the parent directory of the project file.</html>");
 341  0 gridbag.setConstraints(prLabel, c);
 342   
 343  0 panel.add(prLabel);
 344  0 c.weightx = 1.0;
 345  0 c.gridwidth = GridBagConstraints.REMAINDER;
 346  0 c.insets = compInsets;
 347   
 348  0 JPanel prPanel = _projRootPanel();
 349  0 gridbag.setConstraints(prPanel, c);
 350  0 panel.add(prPanel);
 351   
 352    // Build Directory
 353   
 354  0 c.weightx = 0.0;
 355  0 c.gridwidth = 1;
 356  0 c.insets = labelInsets;
 357   
 358  0 JLabel bdLabel = new JLabel("Build Directory");
 359  0 bdLabel.setToolTipText("<html>The directory the class files will be compiled into.<br>" +
 360    "If not specified, the class files will be compiled into<br>" +
 361    "the same directory as their corresponding source files</html>");
 362  0 gridbag.setConstraints(bdLabel, c);
 363   
 364  0 panel.add(bdLabel);
 365  0 c.weightx = 1.0;
 366  0 c.gridwidth = GridBagConstraints.REMAINDER;
 367  0 c.insets = compInsets;
 368   
 369  0 JPanel bdPanel = _buildDirectoryPanel();
 370  0 gridbag.setConstraints(bdPanel, c);
 371  0 panel.add(bdPanel);
 372   
 373    // Working Directory
 374   
 375  0 c.weightx = 0.0;
 376  0 c.gridwidth = 1;
 377  0 c.insets = labelInsets;
 378   
 379  0 JLabel wdLabel = new JLabel("Working Directory");
 380  0 wdLabel.setToolTipText("<html>The root directory for relative path names.</html>");
 381  0 gridbag.setConstraints(wdLabel, c);
 382   
 383  0 panel.add(wdLabel);
 384  0 c.weightx = 1.0;
 385  0 c.gridwidth = GridBagConstraints.REMAINDER;
 386  0 c.insets = compInsets;
 387   
 388  0 JPanel wdPanel = _workDirectoryPanel();
 389  0 gridbag.setConstraints(wdPanel, c);
 390  0 panel.add(wdPanel);
 391   
 392    // Main Document file
 393   
 394  0 c.weightx = 0.0;
 395  0 c.gridwidth = 1;
 396  0 c.insets = labelInsets;
 397   
 398  0 JLabel classLabel = new JLabel("Main Class");
 399  0 classLabel.setToolTipText("<html>The class containing the <code>main</code><br>" +
 400    "method for the entire project</html>");
 401  0 gridbag.setConstraints(classLabel, c);
 402  0 panel.add(classLabel);
 403   
 404  0 c.weightx = 1.0;
 405  0 c.gridwidth = GridBagConstraints.REMAINDER;
 406  0 c.insets = compInsets;
 407   
 408  0 JPanel mainClassPanel = _mainDocumentSelector();
 409  0 gridbag.setConstraints(mainClassPanel, c);
 410  0 panel.add(mainClassPanel);
 411   
 412  0 c.weightx = 0.0;
 413  0 c.gridwidth = 1;
 414  0 c.insets = labelInsets;
 415   
 416    // ExtraProjectClasspaths
 417  0 JLabel extrasLabel = new JLabel("Extra Classpath");
 418  0 extrasLabel.setToolTipText("<html>The list of extra classpaths to load with the project.<br>" +
 419    "This may include either JAR files or directories. Any<br>" +
 420    "classes defined in these classpath locations will be <br>" +
 421    "visible in the interactions pane and also accessible <br>" +
 422    "by the compiler when compiling the project.<br>" +
 423    "The entries are relative to the project file unless<br>" +
 424    "the 'Absolute' checkbox is marked.</html>");
 425  0 gridbag.setConstraints(extrasLabel, c);
 426  0 panel.add(extrasLabel);
 427   
 428  0 c.weightx = 1.0;
 429  0 c.gridwidth = GridBagConstraints.REMAINDER;
 430  0 c.insets = compInsets;
 431   
 432  0 Component extrasComponent = _extraClassPathComponent();
 433  0 gridbag.setConstraints(extrasComponent, c);
 434  0 panel.add(extrasComponent);
 435   
 436  0 c.weightx = 0.0;
 437  0 c.gridwidth = 1;
 438  0 c.insets = labelInsets;
 439   
 440  0 JLabel refreshLabel = new JLabel("<html>Auto Refresh<br>on Open</html>");
 441  0 refreshLabel.setToolTipText("<html>Whether the project will automatically open new files found within the source tree</html>");
 442  0 gridbag.setConstraints(refreshLabel, c);
 443  0 panel.add(refreshLabel);
 444   
 445  0 c.weightx = 1.0;
 446  0 c.gridwidth = GridBagConstraints.REMAINDER;
 447  0 c.insets = compInsets;
 448   
 449  0 _autoRefreshComponent = new JCheckBox();
 450  0 gridbag.setConstraints(_autoRefreshComponent, c);
 451  0 panel.add(_autoRefreshComponent);
 452   
 453  0 c.weightx = 0.0;
 454  0 c.gridwidth = 1;
 455  0 c.insets = labelInsets;
 456   
 457    // Files excluded from auto-refresh
 458  0 JLabel excludedLabel = new JLabel("<html>Files Excluded from<br>Auto-Refresh</html>");
 459  0 excludedLabel.setToolTipText("<html>The list of source files excluded from project auto-refresh.<br>" +
 460    "These files will not be added to the project.</html>");
 461  0 gridbag.setConstraints(excludedLabel, c);
 462  0 panel.add(excludedLabel);
 463   
 464  0 c.weightx = 1.0;
 465  0 c.gridwidth = GridBagConstraints.REMAINDER;
 466  0 c.insets = compInsets;
 467   
 468  0 Component excludedComponent = _excludedFilesComponent();
 469  0 gridbag.setConstraints(excludedComponent, c);
 470  0 panel.add(excludedComponent);
 471    }
 472   
 473    private DocumentListener _applyListener = new DocumentListener() {
 474  0 public void insertUpdate(DocumentEvent e) { setEnabled(); }
 475  0 public void removeUpdate(DocumentEvent e) { setEnabled(); }
 476  0 public void changedUpdate(DocumentEvent e) { setEnabled(); }
 477  0 private void setEnabled() {
 478  0 assert EventQueue.isDispatchThread();
 479    // Utilities.invokeLater(new Runnable() {
 480    // public void run() {
 481  0 _applyButton.setEnabled(true);
 482    // }
 483    // });
 484    }
 485    };
 486   
 487  0 public JPanel _projRootPanel() {
 488  0 DirectoryChooser dirChooser = new DirectoryChooser(this);
 489  0 dirChooser.setSelectedFile(_getProjRoot());
 490  0 dirChooser.setDialogTitle("Select Project Root Folder");
 491  0 dirChooser.setApproveButtonText("Select");
 492    // dirChooser.setEditable(true);
 493  0 _projRootSelector = new DirectorySelectorComponent(this, dirChooser, 20, 12f) {
 494  0 protected void _chooseFile() {
 495  0 _mainFrame.removeModalWindowAdapter(ProjectPropertiesFrame.this);
 496  0 super._chooseFile();
 497  0 _mainFrame.installModalWindowAdapter(ProjectPropertiesFrame.this, LambdaUtil.NO_OP, CANCEL);
 498    }
 499    };
 500    //toReturn.add(_buildDirSelector, BorderLayout.EAST);
 501   
 502  0 _projRootSelector.getFileField().getDocument().addDocumentListener(_applyListener);
 503   
 504  0 return _projRootSelector;
 505    }
 506   
 507  0 public JPanel _buildDirectoryPanel() {
 508  0 DirectoryChooser dirChooser = new DirectoryChooser(this);
 509  0 File bd = _getBuildDir();
 510  0 if (bd == null || bd == FileOps.NULL_FILE) bd = _getProjRoot();
 511  0 dirChooser.setSelectedFile(bd);
 512  0 dirChooser.setDialogTitle("Select Build Directory");
 513  0 dirChooser.setApproveButtonText("Select");
 514    // dirChooser.setEditable(true);
 515    // (..., false); since build directory does not have to exist
 516  0 _buildDirSelector = new DirectorySelectorComponent(this, dirChooser, 20, 12f, false) {
 517  0 protected void _chooseFile() {
 518  0 _mainFrame.removeModalWindowAdapter(ProjectPropertiesFrame.this);
 519  0 super._chooseFile();
 520  0 _mainFrame.installModalWindowAdapter(ProjectPropertiesFrame.this, LambdaUtil.NO_OP, CANCEL);
 521    }
 522    };
 523  0 _buildDirSelector.setFileField(bd); // the file field is used as the initial file selection
 524    //toReturn.add(_buildDirSelector, BorderLayout.EAST);
 525   
 526  0 _buildDirSelector.getFileField().getDocument().addDocumentListener(_applyListener);
 527   
 528  0 return _buildDirSelector;
 529    }
 530   
 531  0 public JPanel _workDirectoryPanel() {
 532  0 DirectoryChooser dirChooser = new DirectoryChooser(this);
 533  0 dirChooser.setSelectedFile(_getWorkDir());
 534  0 dirChooser.setDialogTitle("Select Working Directory");
 535  0 dirChooser.setApproveButtonText("Select");
 536    // dirChooser.setEditable(true);
 537  0 _workDirSelector = new DirectorySelectorComponent(this, dirChooser, 20, 12f) {
 538  0 protected void _chooseFile() {
 539  0 _mainFrame.removeModalWindowAdapter(ProjectPropertiesFrame.this);
 540  0 super._chooseFile();
 541  0 _mainFrame.installModalWindowAdapter(ProjectPropertiesFrame.this, LambdaUtil.NO_OP, CANCEL);
 542    }
 543    };
 544    //toReturn.add(_buildDirSelector, BorderLayout.EAST);
 545   
 546  0 _workDirSelector.getFileField().getDocument().addDocumentListener(_applyListener);
 547  0 return _workDirSelector;
 548    }
 549   
 550  0 public Component _extraClassPathComponent() {
 551  0 _extraClassPathList = new VectorAbsRelFileOptionComponent(null, "Extra Project Classpaths", this, null, true) {
 552  0 protected Action _getAddAction() {
 553  0 final Action a = super._getAddAction();
 554  0 return new AbstractAction("Add") {
 555  0 public void actionPerformed(ActionEvent ae) {
 556  0 _mainFrame.removeModalWindowAdapter(ProjectPropertiesFrame.this);
 557  0 a.actionPerformed(ae);
 558  0 _mainFrame.installModalWindowAdapter(ProjectPropertiesFrame.this, LambdaUtil.NO_OP, CANCEL);
 559    }
 560    };
 561    }
 562    };
 563  0 _extraClassPathList.setRows(5,5);
 564  0 _extraClassPathList.addChangeListener(new OptionComponent.ChangeListener() {
 565  0 public Object value(Object oc) {
 566  0 _applyButton.setEnabled(true);
 567  0 return null;
 568    }
 569    });
 570  0 return _extraClassPathList.getComponent();
 571    }
 572   
 573  0 public Component _excludedFilesComponent() {
 574  0 _excludedFilesList = new VectorFileOptionComponent(null, "Files Excluded from Auto-Refresh", this, null, false) {
 575  0 protected Action _getAddAction() {
 576  0 final Action a = super._getAddAction();
 577  0 return new AbstractAction("Add") {
 578  0 public void actionPerformed(ActionEvent ae) {
 579  0 _mainFrame.removeModalWindowAdapter(ProjectPropertiesFrame.this);
 580  0 a.actionPerformed(ae);
 581  0 _mainFrame.installModalWindowAdapter(ProjectPropertiesFrame.this, LambdaUtil.NO_OP, CANCEL);
 582    }
 583    };
 584    }
 585    };
 586  0 _excludedFilesList.setRows(5,5);
 587  0 _excludedFilesList.getFileChooser().resetChoosableFileFilters();
 588  0 _excludedFilesList.getFileChooser().addChoosableFileFilter(new JavaSourceFilter());
 589  0 _excludedFilesList.getFileChooser().setFileFilter(new SmartSourceFilter());
 590  0 _excludedFilesList.addChangeListener(new OptionComponent.ChangeListener() {
 591  0 public Object value(Object oc) {
 592  0 _applyButton.setEnabled(true);
 593  0 return null;
 594    }
 595    });
 596  0 if (_model.getProjectRoot() != null) {
 597  0 _excludedFilesList.setBaseDir(_model.getProjectRoot());
 598    }
 599  0 return _excludedFilesList.getComponent();
 600    }
 601   
 602  0 public JPanel _mainDocumentSelector() {
 603  0 final File projRoot = _getProjRoot();
 604   
 605  0 final FileChooser chooser = new FileChooser(projRoot);
 606  0 chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
 607  0 chooser.setDialogType(JFileChooser.CUSTOM_DIALOG);
 608   
 609  0 chooser.setDialogTitle("Select Main Class");
 610  0 chooser.setCurrentDirectory(projRoot);
 611  0 File mainFile = _getMainFile();
 612  0 if (mainFile != FileOps.NULL_FILE){
 613  0 chooser.setSelectedFile(mainFile);
 614    }
 615   
 616  0 chooser.setApproveButtonText("Select");
 617   
 618  0 chooser.resetChoosableFileFilters();
 619  0 chooser.addChoosableFileFilter(new SmartSourceFilter());
 620  0 chooser.addChoosableFileFilter(new JavaSourceFilter());
 621  0 _mainDocumentSelector = new JTextField(20){
 622  0 public Dimension getMaximumSize() {
 623  0 return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
 624    }
 625    };
 626   
 627  0 _mainDocumentSelector.setFont(_mainDocumentSelector.getFont().deriveFont(12f));
 628  0 _mainDocumentSelector.setPreferredSize(new Dimension(22, 22));
 629   
 630  0 _mainDocumentSelector.getDocument().addDocumentListener(_applyListener);
 631   
 632  0 JButton selectFile = new JButton("...");
 633  0 selectFile.addActionListener(new ActionListener(){
 634  0 public void actionPerformed(ActionEvent e){
 635  0 int ret = chooser.showOpenDialog(ProjectPropertiesFrame.this);
 636   
 637  0 if(ret != JFileChooser.APPROVE_OPTION)
 638  0 return;
 639   
 640  0 File mainClass = chooser.getSelectedFile();
 641   
 642  0 File sourceRoot = new File(_projRootSelector.getFileField().getText());
 643   
 644  0 if(sourceRoot == null || mainClass == null)
 645  0 return;
 646   
 647  0 if(!mainClass.getAbsolutePath().startsWith(sourceRoot.getAbsolutePath())){
 648  0 JOptionPane.showMessageDialog(ProjectPropertiesFrame.this,
 649    "Main Class must be in either Project Root or one of its sub-directories.",
 650    "Unable to set Main Class", JOptionPane.ERROR_MESSAGE);
 651   
 652  0 _mainDocumentSelector.setText("");
 653  0 return;
 654    }
 655   
 656    //Strip off the source root path
 657  0 String qualifiedName = mainClass.getAbsolutePath().substring(sourceRoot.getAbsolutePath().length());
 658   
 659    //Strip off any leading slashes
 660  0 if(qualifiedName.startsWith("" + File.separatorChar))
 661  0 qualifiedName = qualifiedName.substring(1);
 662   
 663    //Remove the .java extension if it exists
 664    // TODO: What about language level file extensions? What about Habanero Java extension?
 665  0 if(qualifiedName.toLowerCase().endsWith(OptionConstants.JAVA_FILE_EXTENSION))
 666  0 qualifiedName = qualifiedName.substring(0, qualifiedName.length() - 5);
 667   
 668    //Replace path seperators with java standard '.' package seperators.
 669  0 _mainDocumentSelector.setText(qualifiedName.replace(File.separatorChar, '.'));
 670    }
 671    });
 672   
 673   
 674  0 selectFile.setMaximumSize(new Dimension(22, 22));
 675  0 selectFile.setMargin(new Insets(0, 5 ,0, 5));
 676   
 677  0 JPanel toRet = new JPanel();
 678  0 javax.swing.BoxLayout layout = new javax.swing.BoxLayout(toRet, javax.swing.BoxLayout.X_AXIS);
 679  0 toRet.setLayout(layout);
 680  0 toRet.add(_mainDocumentSelector);
 681  0 toRet.add(selectFile);
 682   
 683  0 return toRet;
 684    }
 685   
 686    /** Runnable that calls _cancel. */
 687    protected final Runnable1<WindowEvent> CANCEL = new Runnable1<WindowEvent>() {
 688  0 public void run(WindowEvent e) { cancel(); }
 689    };
 690   
 691    /** Validates before changing visibility. Only runs in the event thread.
 692    * @param vis true if frame should be shown, false if it should be hidden.
 693    */
 694  0 public void setVisible(boolean vis) {
 695  0 assert EventQueue.isDispatchThread();
 696  0 validate();
 697  0 if (vis) {
 698  0 _mainFrame.hourglassOn();
 699  0 _mainFrame.installModalWindowAdapter(this, LambdaUtil.NO_OP, CANCEL);
 700  0 toFront();
 701    }
 702    else {
 703  0 _mainFrame.removeModalWindowAdapter(this);
 704  0 _mainFrame.hourglassOff();
 705  0 _mainFrame.toFront();
 706    }
 707  0 super.setVisible(vis);
 708    }
 709   
 710    // advanced settings
 711  0 protected void advancedSettings() {
 712  0 _mainFrame.removeModalWindowAdapter(ProjectPropertiesFrame.this);
 713  0 ProjectAdvancedPropertiesFrame ppf = new ProjectAdvancedPropertiesFrame(_mainFrame, this) {
 714  0 public void setVisible(boolean vis) {
 715  ? assert EventQueue.isDispatchThread();
 716  0 validate();
 717  0 if (vis) {
 718  0 _mainFrame.hourglassOn();
 719  0 _mainFrame.installModalWindowAdapter(this, LambdaUtil.NO_OP, CANCEL);
 720  0 toFront();
 721    }
 722    else {
 723  0 _mainFrame.removeModalWindowAdapter(this);
 724  0 _mainFrame.hourglassOff();
 725  0 _mainFrame.installModalWindowAdapter(ProjectPropertiesFrame.this, LambdaUtil.NO_OP, CANCEL);
 726  0 toFront();
 727  0 Map<OptionParser<?>,String> newValues = this.getPreferencesStoredInProject();
 728  0 if (!newValues.keySet().equals(_storedPreferences.keySet())) {
 729  0 _storedPreferences.clear();
 730  0 _storedPreferences.putAll(newValues);
 731  0 _applyButton.setEnabled(true);
 732    }
 733    }
 734  0 super.setVisible(vis);
 735    }
 736    };
 737  0 ppf.reset(_storedPreferences);
 738  0 ppf.setVisible(true);
 739  0 ppf.toFront(); // ppf actions save state of ppf in global model
 740    }
 741    }