001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.apache.tools.ant.module;
043:
044: import java.awt.EventQueue;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.io.File;
048: import java.lang.reflect.InvocationTargetException;
049: import java.util.ArrayList;
050: import java.util.Collections;
051: import java.util.List;
052: import java.util.Map;
053: import java.util.Properties;
054: import java.util.regex.Pattern;
055: import javax.swing.DefaultComboBoxModel;
056: import javax.swing.JFileChooser;
057: import javax.swing.JPanel;
058: import javax.swing.SwingUtilities;
059: import org.openide.DialogDisplayer;
060: import org.openide.NotifyDescriptor;
061: import org.openide.execution.NbClassPath;
062: import org.openide.explorer.propertysheet.PropertyPanel;
063: import org.openide.nodes.Node;
064: import org.openide.nodes.PropertySupport;
065: import org.openide.util.NbBundle;
066: import org.openide.util.NbCollections;
067: import org.openide.util.RequestProcessor;
068:
069: /**
070: * Implementation of one panel in Options Dialog.
071: * @author Jan Jancura, Jesse Glick
072: */
073: public class AntCustomizer extends JPanel implements ActionListener {
074:
075: private List<File> classpath;
076: private Map<String, String> properties = Collections.emptyMap();
077: private boolean changed = false;
078: private boolean listen = false;
079: private File originalAntHome;
080: private final Node.Property classpathProperty;
081: private final Node.Property propertiesProperty;
082:
083: public AntCustomizer() {
084: initComponents();
085: bAntHome.addActionListener(this );
086: ((DefaultComboBoxModel) cbVerbosity.getModel())
087: .removeAllElements(); // just have prototype for form editor
088: cbVerbosity.addItem(NbBundle.getMessage(AntCustomizer.class,
089: "LBL_verbosity_warn"));
090: cbVerbosity.addItem(NbBundle.getMessage(AntCustomizer.class,
091: "LBL_verbosity_info"));
092: cbVerbosity.addItem(NbBundle.getMessage(AntCustomizer.class,
093: "LBL_verbosity_verbose"));
094: cbVerbosity.addItem(NbBundle.getMessage(AntCustomizer.class,
095: "LBL_verbosity_debug"));
096: cbSaveFiles.addActionListener(this );
097: cbReuseOutput.addActionListener(this );
098: cbAlwaysShowOutput.addActionListener(this );
099: cbVerbosity.addActionListener(this );
100: classpathProperty = new PropertySupport.ReadWrite<NbClassPath>(
101: "classpath", NbClassPath.class, null, null) {
102: public NbClassPath getValue()
103: throws IllegalAccessException,
104: InvocationTargetException {
105: return new NbClassPath(classpath
106: .toArray(new File[classpath.size()]));
107: }
108:
109: public void setValue(NbClassPath val)
110: throws IllegalAccessException,
111: IllegalArgumentException, InvocationTargetException {
112: String cp = val.getClassPath();
113: if (cp.startsWith("\"") && cp.endsWith("\"")) {
114: // *@%!* NbClassPath.getClassPath semantics.
115: cp = cp.substring(1, cp.length() - 1);
116: }
117: classpath = new ArrayList<File>();
118: for (String f : cp.split(Pattern
119: .quote(File.pathSeparator))) {
120: classpath.add(new File(f));
121: }
122: changed = true;
123: }
124: };
125: propertiesProperty = new PropertySupport.ReadWrite<Properties>(
126: "properties", Properties.class, null, null) {
127: public Properties getValue() throws IllegalAccessException,
128: InvocationTargetException {
129: Properties p = new Properties();
130: p.putAll(properties);
131: return p;
132: }
133:
134: public void setValue(Properties val)
135: throws IllegalAccessException,
136: IllegalArgumentException, InvocationTargetException {
137: properties = NbCollections.checkedMapByCopy(val,
138: String.class, String.class, true);
139: changed = true;
140: }
141: };
142: setUpPropertyPanels();
143: }
144:
145: private void setUpPropertyPanels() {
146: classpathPanel.removeAll();
147: PropertyPanel pp = new PropertyPanel(classpathProperty,
148: PropertyPanel.PREF_CUSTOM_EDITOR);
149: classpathPanel.add(pp);
150: classpathLabel.setLabelFor(pp);
151: propertiesPanel.removeAll();
152: pp = new PropertyPanel(propertiesProperty,
153: PropertyPanel.PREF_CUSTOM_EDITOR);
154: propertiesPanel.add(pp);
155: propertiesLabel.setLabelFor(pp);
156: }
157:
158: void update() {
159: listen = false;
160: classpath = AntSettings.getExtraClasspath();
161: properties = AntSettings.getProperties();
162: setUpPropertyPanels();
163: originalAntHome = AntSettings.getAntHome();
164:
165: tfAntHome.setText(originalAntHome != null ? originalAntHome
166: .toString() : null);
167: cbSaveFiles.setSelected(AntSettings.getSaveAll());
168: cbReuseOutput.setSelected(AntSettings.getAutoCloseTabs());
169: cbAlwaysShowOutput.setSelected(AntSettings
170: .getAlwaysShowOutput());
171: cbVerbosity.setSelectedIndex(AntSettings.getVerbosity() - 1);
172: updateAntVersion();
173: changed = false;
174: initialized = true;
175: listen = true;
176: }
177:
178: private void updateAntVersion() { // #107094: asynch, since it can be slow
179: lAntVersion.setText(NbBundle.getMessage(AntCustomizer.class,
180: "LBL_please_wait"));
181: RequestProcessor.getDefault().post(new Runnable() {
182: public void run() {
183: final String version = AntSettings.getAntVersion();
184: EventQueue.invokeLater(new Runnable() {
185: public void run() {
186: lAntVersion.setText("(" + version + ")");
187: }
188: });
189: }
190: });
191: }
192:
193: private boolean initialized = false;
194:
195: void applyChanges() {
196: if (!initialized)
197: return;
198: String antHome = tfAntHome.getText().trim();
199: AntSettings.setAntHome(new File(antHome));
200: if (AntSettings.getAutoCloseTabs() != cbReuseOutput
201: .isSelected()) {
202: AntSettings.setAutoCloseTabs(cbReuseOutput.isSelected());
203: }
204: if (AntSettings.getSaveAll() != cbSaveFiles.isSelected()) {
205: AntSettings.setSaveAll(cbSaveFiles.isSelected());
206: }
207: if (AntSettings.getAlwaysShowOutput() != cbAlwaysShowOutput
208: .isSelected()) {
209: AntSettings.setAlwaysShowOutput(cbAlwaysShowOutput
210: .isSelected());
211: }
212: if (AntSettings.getVerbosity() != cbVerbosity
213: .getSelectedIndex() + 1) {
214: AntSettings
215: .setVerbosity(cbVerbosity.getSelectedIndex() + 1);
216: }
217: if (!AntSettings.getProperties().equals(properties)) {
218: AntSettings.setProperties(properties);
219: }
220: if (!AntSettings.getExtraClasspath().equals(classpath)) {
221: AntSettings.setExtraClasspath(classpath);
222: }
223: changed = false;
224: }
225:
226: void cancel() {
227: if (AntSettings.getAntHome() != originalAntHome) {
228: AntSettings.setAntHome(originalAntHome);
229: }
230: changed = false;
231: }
232:
233: boolean dataValid() {
234: return true;
235: }
236:
237: boolean isChanged() {
238: return changed;
239: }
240:
241: public void actionPerformed(ActionEvent e) {
242: if (!listen)
243: return;
244: Object o = e.getSource();
245: if (o == cbAlwaysShowOutput) {
246: changed = true;
247: } else if (o == cbReuseOutput) {
248: changed = true;
249: } else if (o == cbSaveFiles) {
250: changed = true;
251: } else if (o == cbVerbosity) {
252: changed = true;
253: } else if (o == bAntHome) {
254: JFileChooser chooser = new JFileChooser(tfAntHome.getText());
255: chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
256: int r = chooser.showDialog(SwingUtilities
257: .getWindowAncestor(this ), NbBundle.getMessage(
258: AntCustomizer.class, "Select_Directory"));
259: if (r == JFileChooser.APPROVE_OPTION) {
260: File file = chooser.getSelectedFile();
261: if (!new File(new File(file, "lib"), "ant.jar")
262: .isFile()) {
263: DialogDisplayer
264: .getDefault()
265: .notify(
266: new NotifyDescriptor.Message(
267: NbBundle
268: .getMessage(
269: AntCustomizer.class,
270: "Not_a_ant_home",
271: file),
272: NotifyDescriptor.Message.WARNING_MESSAGE));
273: return;
274: }
275: tfAntHome.setText(file.getAbsolutePath());
276: AntSettings.setAntHome(file);
277: updateAntVersion();
278: changed = true;
279: }
280: }
281: }
282:
283: // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
284: private void initComponents() {
285:
286: javax.swing.JLabel antHomeLabel = new javax.swing.JLabel();
287: tfAntHome = new javax.swing.JTextField();
288: bAntHome = new javax.swing.JButton();
289: bAntHomeDefault = new javax.swing.JButton();
290: lAntVersion = new javax.swing.JLabel();
291: cbSaveFiles = new javax.swing.JCheckBox();
292: cbReuseOutput = new javax.swing.JCheckBox();
293: cbAlwaysShowOutput = new javax.swing.JCheckBox();
294: cbVerbosity = new javax.swing.JComboBox();
295: javax.swing.JLabel verbosityLabel = new javax.swing.JLabel();
296: classpathLabel = new javax.swing.JLabel();
297: classpathPanel = new javax.swing.JPanel();
298: propertiesLabel = new javax.swing.JLabel();
299: propertiesPanel = new javax.swing.JPanel();
300:
301: antHomeLabel.setLabelFor(tfAntHome);
302: org.openide.awt.Mnemonics.setLocalizedText(antHomeLabel,
303: NbBundle.getMessage(AntCustomizer.class, "Ant_Home")); // NOI18N
304:
305: org.openide.awt.Mnemonics.setLocalizedText(bAntHome, NbBundle
306: .getMessage(AntCustomizer.class, "Ant_Home_Button")); // NOI18N
307:
308: org.openide.awt.Mnemonics.setLocalizedText(bAntHomeDefault,
309: NbBundle.getMessage(AntCustomizer.class,
310: "Ant_Home_Default_Button")); // NOI18N
311: bAntHomeDefault
312: .addActionListener(new java.awt.event.ActionListener() {
313: public void actionPerformed(
314: java.awt.event.ActionEvent evt) {
315: bAntHomeDefaultActionPerformed(evt);
316: }
317: });
318:
319: lAntVersion.setBackground(java.awt.Color.white);
320: org.openide.awt.Mnemonics.setLocalizedText(lAntVersion,
321: org.openide.util.NbBundle.getMessage(
322: AntCustomizer.class,
323: "AntCustomizer.lAntVersion.text")); // NOI18N
324:
325: org.openide.awt.Mnemonics.setLocalizedText(cbSaveFiles,
326: NbBundle.getMessage(AntCustomizer.class, "Save_Files")); // NOI18N
327: cbSaveFiles.setBorder(javax.swing.BorderFactory
328: .createEmptyBorder(0, 0, 0, 0));
329: cbSaveFiles.setMargin(new java.awt.Insets(0, 0, 0, 0));
330:
331: org.openide.awt.Mnemonics
332: .setLocalizedText(cbReuseOutput, NbBundle.getMessage(
333: AntCustomizer.class, "Reuse_Output")); // NOI18N
334: cbReuseOutput.setBorder(javax.swing.BorderFactory
335: .createEmptyBorder(0, 0, 0, 0));
336: cbReuseOutput.setMargin(new java.awt.Insets(0, 0, 0, 0));
337:
338: org.openide.awt.Mnemonics.setLocalizedText(cbAlwaysShowOutput,
339: NbBundle.getMessage(AntCustomizer.class,
340: "Always_Show_Output")); // NOI18N
341: cbAlwaysShowOutput.setBorder(javax.swing.BorderFactory
342: .createEmptyBorder(0, 0, 0, 0));
343: cbAlwaysShowOutput.setMargin(new java.awt.Insets(0, 0, 0, 0));
344:
345: cbVerbosity.setModel(new javax.swing.DefaultComboBoxModel(
346: new String[] { "Normal" }));
347:
348: verbosityLabel.setLabelFor(cbVerbosity);
349: org.openide.awt.Mnemonics.setLocalizedText(verbosityLabel,
350: NbBundle.getMessage(AntCustomizer.class, "Verbosity")); // NOI18N
351:
352: org.openide.awt.Mnemonics.setLocalizedText(classpathLabel,
353: org.openide.util.NbBundle.getMessage(
354: AntCustomizer.class,
355: "AntCustomizer.classpathLabel.text")); // NOI18N
356:
357: classpathPanel.setBackground(new java.awt.Color(153, 0, 204));
358: classpathPanel.setForeground(new java.awt.Color(153, 0, 204));
359: classpathPanel.setLayout(new java.awt.BorderLayout());
360:
361: org.openide.awt.Mnemonics.setLocalizedText(propertiesLabel,
362: org.openide.util.NbBundle.getMessage(
363: AntCustomizer.class,
364: "AntCustomizer.propertiesLabel.text")); // NOI18N
365:
366: propertiesPanel
367: .setBackground(new java.awt.Color(255, 204, 204));
368: propertiesPanel.setLayout(new java.awt.BorderLayout());
369:
370: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
371: this );
372: this .setLayout(layout);
373: layout
374: .setHorizontalGroup(layout
375: .createParallelGroup(
376: org.jdesktop.layout.GroupLayout.LEADING)
377: .add(
378: layout
379: .createSequentialGroup()
380: .add(antHomeLabel)
381: .add(49, 49, 49)
382: .add(
383: layout
384: .createParallelGroup(
385: org.jdesktop.layout.GroupLayout.LEADING)
386: .add(
387: layout
388: .createSequentialGroup()
389: .add(
390: cbAlwaysShowOutput)
391: .addContainerGap())
392: .add(
393: layout
394: .createParallelGroup(
395: org.jdesktop.layout.GroupLayout.LEADING)
396: .add(
397: lAntVersion,
398: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
399: 519,
400: Short.MAX_VALUE)
401: .add(
402: layout
403: .createSequentialGroup()
404: .add(
405: cbReuseOutput)
406: .addContainerGap())
407: .add(
408: layout
409: .createSequentialGroup()
410: .add(
411: cbSaveFiles)
412: .addContainerGap())
413: .add(
414: org.jdesktop.layout.GroupLayout.TRAILING,
415: layout
416: .createSequentialGroup()
417: .add(
418: tfAntHome,
419: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
420: 354,
421: Short.MAX_VALUE)
422: .addPreferredGap(
423: org.jdesktop.layout.LayoutStyle.RELATED)
424: .add(
425: bAntHome)
426: .addPreferredGap(
427: org.jdesktop.layout.LayoutStyle.RELATED)
428: .add(
429: bAntHomeDefault)))))
430: .add(
431: layout
432: .createSequentialGroup()
433: .add(
434: layout
435: .createParallelGroup(
436: org.jdesktop.layout.GroupLayout.LEADING)
437: .add(
438: verbosityLabel)
439: .add(
440: classpathLabel)
441: .add(
442: propertiesLabel))
443: .add(16, 16, 16)
444: .add(
445: layout
446: .createParallelGroup(
447: org.jdesktop.layout.GroupLayout.LEADING)
448: .add(
449: propertiesPanel,
450: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
451: 524,
452: Short.MAX_VALUE)
453: .add(
454: layout
455: .createSequentialGroup()
456: .add(
457: cbVerbosity,
458: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
459: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
460: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
461: .addContainerGap())
462: .add(
463: classpathPanel,
464: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
465: 524,
466: Short.MAX_VALUE))));
467: layout
468: .setVerticalGroup(layout
469: .createParallelGroup(
470: org.jdesktop.layout.GroupLayout.LEADING)
471: .add(
472: layout
473: .createSequentialGroup()
474: .add(
475: layout
476: .createParallelGroup(
477: org.jdesktop.layout.GroupLayout.BASELINE,
478: false)
479: .add(
480: antHomeLabel)
481: .add(
482: bAntHomeDefault)
483: .add(bAntHome)
484: .add(
485: tfAntHome,
486: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
487: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
488: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
489: .addPreferredGap(
490: org.jdesktop.layout.LayoutStyle.RELATED)
491: .add(
492: lAntVersion,
493: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
494: 15,
495: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
496: .addPreferredGap(
497: org.jdesktop.layout.LayoutStyle.RELATED)
498: .add(cbSaveFiles)
499: .addPreferredGap(
500: org.jdesktop.layout.LayoutStyle.RELATED)
501: .add(cbReuseOutput)
502: .addPreferredGap(
503: org.jdesktop.layout.LayoutStyle.RELATED)
504: .add(cbAlwaysShowOutput)
505: .addPreferredGap(
506: org.jdesktop.layout.LayoutStyle.UNRELATED)
507: .add(
508: layout
509: .createParallelGroup(
510: org.jdesktop.layout.GroupLayout.BASELINE)
511: .add(
512: cbVerbosity,
513: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
514: org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
515: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
516: .add(
517: verbosityLabel))
518: .addPreferredGap(
519: org.jdesktop.layout.LayoutStyle.RELATED)
520: .add(
521: layout
522: .createParallelGroup(
523: org.jdesktop.layout.GroupLayout.LEADING)
524: .add(
525: classpathLabel)
526: .add(
527: classpathPanel,
528: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
529: 193,
530: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
531: .add(
532: layout
533: .createParallelGroup(
534: org.jdesktop.layout.GroupLayout.LEADING)
535: .add(
536: layout
537: .createSequentialGroup()
538: .add(
539: 7,
540: 7,
541: 7)
542: .add(
543: propertiesLabel))
544: .add(
545: layout
546: .createSequentialGroup()
547: .addPreferredGap(
548: org.jdesktop.layout.LayoutStyle.UNRELATED)
549: .add(
550: propertiesPanel,
551: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
552: 113,
553: org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
554: .addContainerGap(22,
555: Short.MAX_VALUE)));
556: }// </editor-fold>//GEN-END:initComponents
557:
558: private void bAntHomeDefaultActionPerformed(
559: java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bAntHomeDefaultActionPerformed
560: AntSettings.setAntHome(null);
561: File antHome = AntSettings.getAntHome();
562: if (antHome != null) {
563: tfAntHome.setText(antHome.getAbsolutePath());
564: } else {
565: tfAntHome.setText(null);
566: }
567: updateAntVersion();
568: changed = true;
569: }//GEN-LAST:event_bAntHomeDefaultActionPerformed
570:
571: // Variables declaration - do not modify//GEN-BEGIN:variables
572: private javax.swing.JButton bAntHome;
573: private javax.swing.JButton bAntHomeDefault;
574: private javax.swing.JCheckBox cbAlwaysShowOutput;
575: private javax.swing.JCheckBox cbReuseOutput;
576: private javax.swing.JCheckBox cbSaveFiles;
577: private javax.swing.JComboBox cbVerbosity;
578: private javax.swing.JLabel classpathLabel;
579: private javax.swing.JPanel classpathPanel;
580: private javax.swing.JLabel lAntVersion;
581: private javax.swing.JLabel propertiesLabel;
582: private javax.swing.JPanel propertiesPanel;
583: private javax.swing.JTextField tfAntHome;
584: // End of variables declaration//GEN-END:variables
585:
586: }
|