2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.core.execution.beaninfo.editors;
44
import java.beans.PropertyEditor;
46
import java.io.IOException;
47
import java.util.Collections;
48
import java.util.List;
49
import java.util.StringTokenizer;
50
import javax.swing.DefaultListModel;
51
import javax.swing.JFileChooser;
52
import javax.swing.filechooser.FileFilter;
53
import org.netbeans.beaninfo.editors.FileEditor;
54
import org.openide.execution.NbClassPath;
55
import org.openide.util.HelpCtx;
56
import org.openide.util.NbBundle;
57
import org.openide.util.NbCollections;
58
import org.openide.windows.WindowManager;
61
* Panel for editing entries in the classpath.
62
* @author David Strupl
64
class NbClassPathCustomEditor extends javax.swing.JPanel {
66
/** Remember last folder, which was explored in FileChooser.*/
67
private static File lastDirFolder = null;
68
/** Remember last folder, which was explored in FileChooser.*/
69
private static File lastJarFolder = null;
70
/** Property editor associated with. */
71
private PropertyEditor editor;
72
/** Model of list of class path items. */
73
private DefaultListModel listModel = new DefaultListModel();
74
private boolean editable = true;
77
/** Creates new form NbClassPathCustomEditor */
78
public NbClassPathCustomEditor() {
80
pathList.setModel(listModel);
81
pathScrollPane.setViewportView(pathList);
83
setMinimumSize (new java.awt.Dimension(400, 200));
84
setPreferredSize(new java.awt.Dimension(400, 200));
86
pathList.getAccessibleContext().setAccessibleDescription(getString("ACSD_PathList"));
87
addDirButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_AddDirectory"));
88
addJarButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_AddJAR"));
89
upButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_MoveUp"));
90
downButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_MoveDown"));
91
removeButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_Remove"));
93
getAccessibleContext().setAccessibleDescription(getString("ACSD_CustomNbClassPathEditor"));
96
NbClassPathCustomEditor(PropertyEditor propEd) {
99
Object value = propEd.getValue();
100
if (value instanceof NbClassPath) {
101
setClassPath(((NbClassPath)value).getClassPath());
103
if ( editor instanceof NbClassPathEditor )
104
if ( ! ((NbClassPathEditor)editor).isEditable() ) {
106
addDirButton.setEnabled( false );
107
addJarButton.setEnabled( false );
111
/** This method is called from within the constructor to
112
* initialize the form.
113
* WARNING: Do NOT modify this code. The content of this method is
114
* always regenerated by the FormEditor.
116
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
117
private void initComponents() {
118
java.awt.GridBagConstraints gridBagConstraints;
120
innerPanel = new javax.swing.JPanel();
121
addDirButton = new javax.swing.JButton();
122
addJarButton = new javax.swing.JButton();
123
upButton = new javax.swing.JButton();
124
downButton = new javax.swing.JButton();
125
removeButton = new javax.swing.JButton();
126
pathScrollPane = new javax.swing.JScrollPane();
127
pathList = new javax.swing.JList();
129
setLayout(new java.awt.BorderLayout());
131
innerPanel.setLayout(new java.awt.GridBagLayout());
133
org.openide.awt.Mnemonics.setLocalizedText(addDirButton, getString("CTL_AddDirectory")); // NOI18N
134
addDirButton.addActionListener(new java.awt.event.ActionListener() {
135
public void actionPerformed(java.awt.event.ActionEvent evt) {
136
addDirButtonActionPerformed(evt);
139
gridBagConstraints = new java.awt.GridBagConstraints();
140
gridBagConstraints.gridx = 1;
141
gridBagConstraints.gridy = 0;
142
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
143
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
144
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
145
innerPanel.add(addDirButton, gridBagConstraints);
147
org.openide.awt.Mnemonics.setLocalizedText(addJarButton, getString("CTL_AddJAR")); // NOI18N
148
addJarButton.addActionListener(new java.awt.event.ActionListener() {
149
public void actionPerformed(java.awt.event.ActionEvent evt) {
150
addJarButtonActionPerformed(evt);
153
gridBagConstraints = new java.awt.GridBagConstraints();
154
gridBagConstraints.gridx = 1;
155
gridBagConstraints.gridy = 1;
156
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
157
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
158
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
159
innerPanel.add(addJarButton, gridBagConstraints);
161
org.openide.awt.Mnemonics.setLocalizedText(upButton, getString("CTL_MoveUp")); // NOI18N
162
upButton.setEnabled(false);
163
upButton.addActionListener(new java.awt.event.ActionListener() {
164
public void actionPerformed(java.awt.event.ActionEvent evt) {
165
upButtonActionPerformed(evt);
168
gridBagConstraints = new java.awt.GridBagConstraints();
169
gridBagConstraints.gridx = 1;
170
gridBagConstraints.gridy = 3;
171
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
172
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
173
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
174
innerPanel.add(upButton, gridBagConstraints);
176
org.openide.awt.Mnemonics.setLocalizedText(downButton, getString("CTL_MoveDown")); // NOI18N
177
downButton.setEnabled(false);
178
downButton.addActionListener(new java.awt.event.ActionListener() {
179
public void actionPerformed(java.awt.event.ActionEvent evt) {
180
downButtonActionPerformed(evt);
183
gridBagConstraints = new java.awt.GridBagConstraints();
184
gridBagConstraints.gridx = 1;
185
gridBagConstraints.gridy = 4;
186
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
187
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
188
innerPanel.add(downButton, gridBagConstraints);
190
org.openide.awt.Mnemonics.setLocalizedText(removeButton, getString("CTL_Remove")); // NOI18N
191
removeButton.setEnabled(false);
192
removeButton.addActionListener(new java.awt.event.ActionListener() {
193
public void actionPerformed(java.awt.event.ActionEvent evt) {
194
removeButtonActionPerformed(evt);
197
gridBagConstraints = new java.awt.GridBagConstraints();
198
gridBagConstraints.gridx = 1;
199
gridBagConstraints.gridy = 2;
200
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
201
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH;
202
gridBagConstraints.insets = new java.awt.Insets(0, 0, 11, 0);
203
innerPanel.add(removeButton, gridBagConstraints);
205
pathList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
206
public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
207
pathListValueChanged(evt);
210
pathList.addMouseListener(new java.awt.event.MouseAdapter() {
211
public void mouseClicked(java.awt.event.MouseEvent evt) {
212
pathListMouseClicked(evt);
215
pathScrollPane.setViewportView(pathList);
217
gridBagConstraints = new java.awt.GridBagConstraints();
218
gridBagConstraints.gridx = 0;
219
gridBagConstraints.gridy = 0;
220
gridBagConstraints.gridheight = 5;
221
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
222
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
223
gridBagConstraints.weightx = 1.0;
224
gridBagConstraints.weighty = 1.0;
225
gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 11);
226
innerPanel.add(pathScrollPane, gridBagConstraints);
228
add(innerPanel, java.awt.BorderLayout.CENTER);
229
}// </editor-fold>//GEN-END:initComponents
231
private void pathListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_pathListMouseClicked
232
if (evt.getClickCount() != 2) {
233
// trigger the action on double-click
236
triggerEdit(pathList.getSelectedIndex());
237
}//GEN-LAST:event_pathListMouseClicked
239
private void pathListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_pathListValueChanged
241
}//GEN-LAST:event_pathListValueChanged
243
private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeButtonActionPerformed
244
int index = pathList.getSelectedIndex();
246
Object [] selectedValues = pathList.getSelectedValues();
247
for (int i = 0; i < selectedValues.length; i++) {
248
listModel.removeElement(selectedValues[i]);
252
// Select some of remaining item.
253
int size = listModel.getSize();
255
if(index >= 0 && size > 0) {
257
pathList.setSelectedIndex(index - 1);
258
} else if(size > index) {
259
pathList.setSelectedIndex(index);
261
pathList.setSelectedIndex(0);
265
// If empty disable up, down, remve buttons.
267
}//GEN-LAST:event_removeButtonActionPerformed
269
private void downButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downButtonActionPerformed
270
int i = pathList.getSelectedIndex();
272
pathList.setSelectedIndex(i+1);
273
}//GEN-LAST:event_downButtonActionPerformed
275
private void upButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_upButtonActionPerformed
276
int i = pathList.getSelectedIndex();
278
pathList.setSelectedIndex(i - 1);
279
}//GEN-LAST:event_upButtonActionPerformed
281
private void addJarButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addJarButtonActionPerformed
283
JFileChooser chooser = FileEditor.createHackedFileChooser();
284
setHelpToChooser( chooser );
286
chooser.setFileFilter(new FileFilter() {
287
public boolean accept(File f) {
288
return (f.isDirectory() || f.getName().endsWith(".jar") || f.getName().endsWith(".zip")); // NOI18N
290
public String getDescription() {
291
return getString("CTL_JarArchivesMask");
295
if (lastJarFolder != null) {
296
chooser.setCurrentDirectory(lastJarFolder);
299
chooser.setDialogTitle(getString("CTL_FileSystemPanel.Jar_Dialog_Title"));
300
chooser.setMultiSelectionEnabled( true );
301
if (chooser.showDialog(WindowManager.getDefault ().getMainWindow (),
302
getString("CTL_Approve_Button_Title"))
303
== JFileChooser.APPROVE_OPTION) {
304
File[] files = chooser.getSelectedFiles();
305
boolean found = false;
306
for (int i=0; i<files.length; i++) {
307
if ((files[i] != null) && (files[i].isFile())) {
309
String path = files[i].getAbsolutePath();
310
if (! listModel.contains (path)) {
311
listModel.addElement (path);
316
lastJarFolder = chooser.getCurrentDirectory();
319
pathList.setSelectedIndex(listModel.size() - 1);
321
}//GEN-LAST:event_addJarButtonActionPerformed
323
private void addDirButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addDirButtonActionPerformed
324
JFileChooser chooser = FileEditor.createHackedFileChooser();
325
setHelpToChooser( chooser );
326
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
327
chooser.setDialogTitle(getString("CTL_FileSystemPanel.Local_Dialog_Title"));
329
if (lastDirFolder != null) {
330
chooser.setCurrentDirectory(lastDirFolder);
333
if (chooser.showDialog(WindowManager.getDefault ().getMainWindow (),
334
getString("CTL_Approve_Button_Title"))
335
== JFileChooser.APPROVE_OPTION) {
336
File f = chooser.getSelectedFile();
337
if ((f != null) && (f.isDirectory())) {
338
lastDirFolder = f.getParentFile();
340
String path = f.getAbsolutePath();
341
if (! listModel.contains (path)) {
342
listModel.addElement (path);
346
pathList.setSelectedIndex(listModel.size() - 1);
349
}//GEN-LAST:event_addDirButtonActionPerformed
352
// Variables declaration - do not modify//GEN-BEGIN:variables
353
private javax.swing.JButton addDirButton;
354
private javax.swing.JButton addJarButton;
355
private javax.swing.JButton downButton;
356
private javax.swing.JPanel innerPanel;
357
private javax.swing.JList pathList;
358
private javax.swing.JScrollPane pathScrollPane;
359
private javax.swing.JButton removeButton;
360
private javax.swing.JButton upButton;
361
// End of variables declaration//GEN-END:variables
364
/** Sets value to property editor if exists.
366
private void fireValueChanged() {
367
if (editor != null) {
368
editor.setValue(getPropertyValue());
372
/** Allows the user to edit the selected item. */
373
private void triggerEdit(int index) {
377
String selectedItem = (String)listModel.elementAt(index);
378
File selectedF = new File(selectedItem);
379
if (selectedF.isDirectory()) {
381
JFileChooser chooser = FileEditor.createHackedFileChooser();
382
setHelpToChooser( chooser );
383
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
384
chooser.setDialogTitle(getString("CTL_Edit_Local_Dialog_Title"));
386
if (selectedF.getParentFile() != null) {
387
chooser.setCurrentDirectory(selectedF.getParentFile());
388
chooser.setSelectedFile(selectedF);
391
if (chooser.showDialog(WindowManager.getDefault ().getMainWindow (),
392
getString("CTL_Approve_Button_Title"))
393
== JFileChooser.APPROVE_OPTION) {
394
File f = chooser.getSelectedFile();
395
if ((f != null) && (f.isDirectory())) {
396
lastDirFolder = chooser.getCurrentDirectory();
398
f = f.getCanonicalFile ();
399
} catch(IOException ioe) {
403
listModel.set(index, f.getAbsolutePath());
407
} else if (selectedF.isFile()) {
408
JFileChooser chooser = FileEditor.createHackedFileChooser();
409
setHelpToChooser( chooser );
411
chooser.setFileFilter(new FileFilter() {
412
public boolean accept(File f) {
413
return (f.isDirectory() || f.getName().endsWith(".jar") || f.getName().endsWith(".zip")); // NOI18N
415
public String getDescription() {
416
return getString("CTL_JarArchivesMask");
420
chooser.setCurrentDirectory(selectedF.getParentFile());
421
chooser.setSelectedFile(selectedF);
423
chooser.setDialogTitle(getString("CTL_Edit_Jar_Dialog_Title"));
424
if (chooser.showDialog(WindowManager.getDefault ().getMainWindow (),
425
getString("CTL_Approve_Button_Title"))
426
== JFileChooser.APPROVE_OPTION) {
427
File f = chooser.getSelectedFile();
428
if ((f != null) && (f.isFile())) {
429
lastJarFolder = chooser.getCurrentDirectory();
430
listModel.set(index, f.getAbsolutePath());
437
/** Swaps item on the the position index with item on the position index+1. */
438
private void swap(int index) {
439
if ((index < 0)||(index >= listModel.size() -1 )) {
442
Object value = listModel.elementAt(index);
443
listModel.removeElement(value);
444
listModel.add(index + 1, value);
448
/** Enables buttons according to the state of the list.*/
449
private void enableButtons() {
452
removeButton.setEnabled(pathList.getSelectedIndices().length > 0);
453
if (pathList.getSelectedIndices().length == 1) {
454
downButton.setEnabled(pathList.getSelectedIndices()[0] < pathList.getModel().getSize() - 1);
455
upButton.setEnabled(pathList.getSelectedIndices()[0] > 0);
457
downButton.setEnabled(false);
458
upButton.setEnabled(false);
462
/** This method parses given classPath and adds the elements to
465
private void setClassPath(String classPath) {
466
StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator);
467
while (tok.hasMoreTokens()) {
468
String s = tok.nextToken();
469
if (s.startsWith("\"")) { // NOI18N
472
if (s.endsWith("\"")) { // NOI18N
473
s = s.substring(0, s.length() -1 );
475
if (! listModel.contains (s)) {
476
listModel.addElement(s);
482
/** Get the customized property value. Implements <code>EnhancedCustomPropertyEditor</code>.
483
* @return the property value
484
* @exception InvalidStateException when the custom property editor does not contain a valid property value
485
* (and thus it should not be set)
487
public Object getPropertyValue() throws IllegalStateException {
488
List<String> list = Collections.list(NbCollections.checkedEnumerationByFilter(listModel.elements(), String.class, true));
489
String []arr = list.toArray(new String[list.size()]);
490
return new NbClassPath(arr);
493
/** Gets localized string. Helper method. */
494
private static final String getString(String s) {
495
return NbBundle.getMessage(NbClassPathCustomEditor.class, s);
498
private void setHelpToChooser( JFileChooser chooser ) {
499
HelpCtx help = HelpCtx.findHelp( this );
501
HelpCtx.setHelpIDString(chooser, help.getHelpID());