This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 74646
Collapse All | Expand All

(-)apichanges.xml (+17 lines)
Lines 80-85 Link Here
80
    <!-- ACTUAL CHANGES BEGIN HERE: -->
80
    <!-- ACTUAL CHANGES BEGIN HERE: -->
81
81
82
    <changes>
82
    <changes>
83
        <change id="customizerSupport">
84
            <api name="plugins"/>
85
            <summary>
86
                Added server customizer support.
87
            </summary>
88
            <version major="1" minor="19"/>
89
            <date day="9" month="4" year="2006"/>
90
            <author login="sherold"/>
91
            <compatibility binary="compatible" source="compatible" semantic="compatible" addition="yes"/>
92
            <description>
93
                <p>
94
                    Server customizer support class. Provides default implementations of some 
95
                    common server manager customizer panes.
96
                </p>
97
            </description>
98
            <class package="org.netbeans.modules.j2ee.deployment.plugins.api" name="CustomizerSupport"/>
99
        </change>
83
        <change id="antDeployment">
100
        <change id="antDeployment">
84
            <api name="j2eeserver"/>
101
            <api name="j2eeserver"/>
85
            <summary>
102
            <summary>
(-)nbproject/project.properties (-1 / +1 lines)
Lines 11-17 Link Here
11
11
12
is.autoload=true
12
is.autoload=true
13
javac.source=1.5
13
javac.source=1.5
14
spec.version.base=1.18.0
14
spec.version.base=1.19.0
15
15
16
javadoc.title=J2EE Server API
16
javadoc.title=J2EE Server API
17
javadoc.overview=${basedir}/api/doc/overview.html
17
javadoc.overview=${basedir}/api/doc/overview.html
(-)src/org/netbeans/modules/j2ee/deployment/plugins/api/Bundle.properties (+37 lines)
Lines 12-14 Link Here
12
#
12
#
13
13
14
TXT_J2eeLibraryType=J2EE Libraries
14
TXT_J2eeLibraryType=J2EE Libraries
15
16
#Customizer
17
TXT_Classes=Classes
18
TXT_Javadoc=Javadoc
19
TXT_OpenJavadoc=Add ZIP/Folder
20
TXT_OpenSources=Add JAR/Folder
21
TXT_Sources=Sources
22
AD_Add=N/A
23
AD_AddZip=N/A
24
AD_Classes=Classes
25
AD_Down=N/A
26
AD_Javadoc=Javadocs
27
AD_Remove=N/A]
28
AD_Sources=Sources
29
AD_Up=N/A
30
CTL_Add=Add JAR/Folder...
31
CTL_AddJavadocURLMessage=URL:
32
CTL_AddJavadocURLTitle=Add URL
33
CTL_AddURL=Add URL...
34
CTL_AddZip=Add ZIP/Folder...
35
CTL_Cancel=Cancel
36
CTL_Down=Move Down
37
CTL_InvalidURLFormat=Invalid URL format.
38
CTL_Remove=Remove
39
CTL_Up=Move Up
40
MNE_Add=J
41
MNE_AddURL=U
42
MNE_AddZip=Z
43
MNE_Cancel=C
44
MNE_Classes=C
45
MNE_Down=D
46
MNE_Javadoc=J
47
MNE_OpenJavadoc=A
48
MNE_OpenSources=A
49
MNE_Remove=m
50
MNE_Sources=o
51
MNE_Up=U
(-)src/org/netbeans/modules/j2ee/deployment/plugins/api/CustomizerSupport.java (+746 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 *
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 *
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.modules.j2ee.deployment.plugins.api;
15
16
import java.awt.Component;
17
import java.awt.GridBagConstraints;
18
import java.awt.GridBagLayout;
19
import java.awt.Insets;
20
import java.awt.event.ActionEvent;
21
import java.awt.event.ActionListener;
22
import java.beans.Customizer;
23
import java.io.File;
24
import java.net.MalformedURLException;
25
import java.net.URI;
26
import java.net.URL;
27
import java.util.ArrayList;
28
import java.util.Arrays;
29
import java.util.Collection;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.StringTokenizer;
33
import javax.swing.AbstractListModel;
34
import javax.swing.JButton;
35
import javax.swing.JFileChooser;
36
import javax.swing.JLabel;
37
import javax.swing.JList;
38
import javax.swing.JPanel;
39
import javax.swing.JScrollPane;
40
import javax.swing.event.ListSelectionEvent;
41
import javax.swing.event.ListSelectionListener;
42
import javax.swing.filechooser.FileFilter;
43
import org.netbeans.modules.j2ee.deployment.common.api.J2eeLibraryTypeProvider;
44
import org.openide.ErrorManager;
45
import org.openide.NotifyDescriptor;
46
import org.openide.filesystems.FileUtil;
47
import org.openide.util.NbBundle;
48
49
/**
50
 * Server customizer support class. Provides default implementations of some 
51
 * common server manager customizer panes.
52
 *
53
 * @author sherold
54
 *
55
 * @since 1.19
56
 */
57
public final class CustomizerSupport {
58
    
59
    private static final String CLASSPATH = J2eeLibraryTypeProvider.VOLUME_TYPE_CLASSPATH;
60
    private static final String SOURCES = J2eeLibraryTypeProvider.VOLUME_TYPE_SRC;
61
    private static final String JAVADOC = J2eeLibraryTypeProvider.VOLUME_TYPE_JAVADOC;
62
    
63
    /** Do not allow to create instances of this class */
64
    private CustomizerSupport() {
65
    }
66
    
67
    /**
68
     * Creates non-editable customizer classes pane.
69
     *
70
     * @param model A model prepresenting the class path entries.
71
     *
72
     * @return A Component representing the classes pane.
73
     *
74
     * @throws NullPointerException If null model is passed in.
75
     */
76
    public static Component createClassesCustomizer(PathModel model) {
77
        if (model == null) {
78
            throw new NullPointerException();
79
        }
80
        return new PathView(model, CLASSPATH, null);
81
    }
82
    
83
    /**
84
     * Creates an editable customizer sources pane.
85
     *
86
     * @param model A model prepresenting the source path entries.
87
     * @param currentDir Add sources file chooser current directory. Passing in 
88
     *                   a null represents the user's default directory.
89
     *
90
     * @return A Component representing the sources pane.
91
     *
92
     * @throws NullPointerException If null model is passed in.
93
     */
94
    public static Component createSourcesCustomizer(PathModel model, File currentDir) {
95
        if (model == null) {
96
            throw new NullPointerException();
97
        }
98
        return new PathView(model, SOURCES, currentDir);
99
    }
100
    
101
    /**
102
     * Creates an editable customizer javadoc pane.
103
     *
104
     * @param model A model prepresenting the javadoc entries.
105
     * @param currentDir Add javadoc file chooser current directory. Passing in 
106
     *                   a null represents the user's default directory.
107
     *
108
     * @return A Component representing the javadoc pane.
109
     *
110
     * @throws NullPointerException If null model is passed in.
111
     */
112
    public static Component createJavadocCustomizer(PathModel model, File currentDir) {
113
        if (model == null) {
114
            throw new NullPointerException();
115
        }
116
        return new PathView(model, JAVADOC, currentDir);
117
    }
118
    
119
    /**
120
     * Creates an Ant-style path specification from the specified list of URLs.
121
     *
122
     * @param The list of URLs.
123
     *
124
     * @return An Ant-style path specification.
125
     */
126
    public static String buildPath(List<URL> path) {
127
        String PATH_SEPARATOR = System.getProperty("path.separator"); // NOI18N
128
        StringBuffer sb = new StringBuffer(path.size() * 16);
129
        for (Iterator<URL> i = path.iterator(); i.hasNext(); ) {
130
            sb.append(urlToString(i.next()));
131
            if (i.hasNext()) {
132
                sb.append(PATH_SEPARATOR);
133
            }
134
        }
135
        return sb.toString();
136
    }
137
    
138
    /**
139
     * Splits an Ant-style path specification into the list of URLs.  Tokenizes on 
140
     * <code>:</code> and <code>;</code>, paying attention to DOS-style components 
141
     * such as <samp>C:\FOO</samp>. Also removes any empty components.
142
     *
143
     * @param path An Ant-style path (elements arbitrary) using DOS or Unix separators
144
     *
145
     * @return A tokenization of the specified path into the list of URLs.
146
     */
147
    public static List<URL> tokenizePath(String path) {
148
        try {
149
            List<URL> l = new ArrayList();
150
            StringTokenizer tok = new StringTokenizer(path, ":;", true); // NOI18N
151
            char dosHack = '\0';
152
            char lastDelim = '\0';
153
            int delimCount = 0;
154
            while (tok.hasMoreTokens()) {
155
                String s = tok.nextToken();
156
                if (s.length() == 0) {
157
                    // Strip empty components.
158
                    continue;
159
                }
160
                if (s.length() == 1) {
161
                    char c = s.charAt(0);
162
                    if (c == ':' || c == ';') {
163
                        // Just a delimiter.
164
                        lastDelim = c;
165
                        delimCount++;
166
                        continue;
167
                    }
168
                }
169
                if (dosHack != '\0') {
170
                    // #50679 - "C:/something" is also accepted as DOS path
171
                    if (lastDelim == ':' && delimCount == 1 && (s.charAt(0) == '\\' || s.charAt(0) == '/')) {
172
                        // We had a single letter followed by ':' now followed by \something or /something
173
                        s = "" + dosHack + ':' + s;
174
                        // and use the new token with the drive prefix...
175
                    } else {
176
                        // Something else, leave alone.
177
                        l.add(fileToUrl(new File(Character.toString(dosHack))));
178
                        // and continue with this token too...
179
                    }
180
                    dosHack = '\0';
181
                }
182
                // Reset count of # of delimiters in a row.
183
                delimCount = 0;
184
                if (s.length() == 1) {
185
                    char c = s.charAt(0);
186
                    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
187
                        // Probably a DOS drive letter. Leave it with the next component.
188
                        dosHack = c;
189
                        continue;
190
                    }
191
                }
192
                l.add(fileToUrl(new File(s)));
193
            }
194
            if (dosHack != '\0') {
195
                //the dosHack was the last letter in the input string (not followed by the ':')
196
                //so obviously not a drive letter.
197
                //Fix for issue #57304
198
                l.add(fileToUrl(new File(Character.toString(dosHack))));
199
            }
200
            return l;
201
        } catch (MalformedURLException e) {
202
            ErrorManager.getDefault().notify(e);
203
            return new ArrayList();
204
        }
205
    }
206
    
207
    /** Return URL representation of the specified file. */
208
    private static URL fileToUrl(File file) throws MalformedURLException {
209
        URL url = file.toURI().toURL();
210
        if (FileUtil.isArchiveFile(url)) {
211
            url = FileUtil.getArchiveRoot(url);
212
        }
213
        return url;
214
    }
215
    
216
    /** Return string representation of the specified URL. */
217
    private static String urlToString(URL url) {
218
        if ("jar".equals(url.getProtocol())) { // NOI18N
219
            URL fileURL = FileUtil.getArchiveFile(url);
220
            if (FileUtil.getArchiveRoot(fileURL).equals(url)) {
221
                // really the root
222
                url = fileURL;
223
            } else {
224
                // some subdir, just show it as is
225
                return url.toExternalForm();
226
            }
227
        }
228
        if ("file".equals(url.getProtocol())) { // NOI18N
229
            File f = new File(URI.create(url.toExternalForm()));
230
            return f.getAbsolutePath();
231
        }
232
        else {
233
            return url.toExternalForm();
234
        }
235
    }
236
    
237
    /**
238
     * Path list model, supports adding, removing and moving URL entries in the list.
239
     */
240
    public static final class PathModel extends AbstractListModel {
241
242
        private final List<URL> data;
243
244
        /**
245
         * Creates a new PathModel initialized with a list of URL entries.
246
         *
247
         * @param data The list of URL entries.
248
         *
249
         * @throws NullPointerException If null data attribute is passed in.
250
         */
251
        public PathModel(List<URL> data) {
252
            if (data == null) {
253
                throw new NullPointerException("The data attribute must not be null."); // NOI18N
254
            }
255
            this.data = data;
256
        }
257
258
        /**
259
         * Returns the number of URL entries in the list.
260
         *
261
         * return The number of URL entries in the list.
262
         */
263
        public int getSize() {
264
            return data.size();
265
        }
266
267
        /**
268
         * Returns the element at the specified position in this list.
269
         *
270
         * @param index The element position in the list.
271
         *
272
         * @return The element at the specified position in this list.
273
         */
274
        public Object getElementAt(int index) {
275
            URL url = data.get(index);
276
            if ("jar".equals(url.getProtocol())) { // NOI18N
277
                URL fileURL = FileUtil.getArchiveFile(url);
278
                if (FileUtil.getArchiveRoot(fileURL).equals(url)) {
279
                    // really the root
280
                    url = fileURL;
281
                } else {
282
                    // some subdir, just show it as is
283
                    return url.toExternalForm();
284
                }
285
            }
286
            if ("file".equals(url.getProtocol())) { // NOI18N
287
                File f = new File(URI.create(url.toExternalForm()));
288
                return f.getAbsolutePath();
289
            }
290
            else {
291
                return url.toExternalForm();
292
            }
293
        }
294
295
        /**
296
         * Removes the URL entries denotated with their respective indices from the list.
297
         */
298
        public void removePath(int[] indices) {
299
            for (int i = indices.length - 1; i >= 0; i--) {
300
                data.remove(indices[i]);
301
            }
302
            fireIntervalRemoved(this, indices[0], indices[indices.length - 1]);
303
        }
304
305
        /**
306
         * Moves the URL entries denotated with their respective indices up in the list.
307
         */
308
        public void moveUpPath(int[] indices) {
309
            for (int i = 0; i < indices.length; i++) {
310
                URL p2 = data.get(indices[i]);
311
                URL p1 = data.set(indices[i] - 1, p2);
312
                data.set(indices[i], p1);
313
            }
314
            fireContentsChanged(this, indices[0] - 1, indices[indices.length - 1]);
315
        }
316
317
        /**
318
         * Moves the URL entries denotated with their respective indices down in the list.
319
         */
320
        public void moveDownPath(int[] indices) {
321
            for (int i = indices.length - 1; i >= 0; i--) {
322
                URL p1 = data.get(indices[i]);
323
                URL p2 = data.set(indices[i] + 1, p1);
324
                data.set(indices[i], p2);
325
            }
326
            fireContentsChanged(this, indices[0], indices[indices.length - 1] + 1);
327
        }
328
329
        /**
330
         * Appends the URL representing the specified file to the end of the list.
331
         * 
332
         * @return true if the URL was appended, false otherwise.
333
         */
334
        public boolean addPath(File f) {
335
            try {
336
                URL url = f.toURI().toURL();
337
                return this.addPath(url);
338
            } catch (MalformedURLException mue) {
339
                return false;
340
            }
341
        }
342
343
        /**
344
         * Appends the specified URL to the end of the list.
345
         * 
346
         * @return true if the URL was appended, false otherwise.
347
         */
348
        public boolean addPath(URL url) {
349
            if (FileUtil.isArchiveFile(url)) {
350
                url = FileUtil.getArchiveRoot(url);
351
            } else if (!url.toExternalForm().endsWith("/")) { // NOI18N
352
                try {
353
                    url = new URL(url.toExternalForm() + "/"); // NOI18N
354
                } catch (MalformedURLException mue) {
355
                    ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, mue);
356
                }
357
            }
358
            int oldSize = data.size();
359
            data.add(url);
360
            fireIntervalAdded(this, oldSize, oldSize);
361
            return true;
362
        }
363
364
        /**
365
         * Returns the list of URL entries.
366
         * @return The list of URL entries.
367
         */
368
        public List<URL> getData() {
369
            return data;
370
        }
371
    }
372
    
373
    // private helper classes -------------------------------------------------
374
    
375
    private static class PathView extends JPanel {
376
        
377
        private JList resources;
378
        private JButton addButton;
379
        private JButton addURLButton;
380
        private JButton removeButton;
381
        private JButton moveUpButton;
382
        private JButton moveDownButton;
383
        private File currentDir;
384
        private String type;
385
386
        public PathView (PathModel model, String type, File currentDir) {
387
            this.type = type;
388
            this.currentDir = currentDir;
389
            initComponents(model);
390
        }
391
392
        private void initComponents(PathModel model) {
393
            setLayout(new GridBagLayout());
394
            JLabel label = new JLabel ();
395
            String key = null;
396
            String mneKey = null;
397
            String ad = null;
398
            if (type.equals(CLASSPATH)) {
399
                key = "TXT_Classes";       // NOI18N
400
                mneKey = "MNE_Classes";    // NOI18N
401
                ad = "AD_Classes";       // NOI18N                
402
            } else if (type.equals(SOURCES)) {
403
                key = "TXT_Sources";        // NOI18N
404
                mneKey = "MNE_Sources";     // NOI18N
405
                ad = "AD_Sources";          // NOI18N
406
            } else if (type.equals(JAVADOC)) {
407
                key = "TXT_Javadoc";        // NOI18N
408
                mneKey = "MNE_Javadoc";     // NOI18N
409
                ad = "AD_Javadoc";          // NOI18N                
410
            } else {
411
                assert false : "Illegal type of panel"; //NOI18N
412
                return;
413
            }
414
            label.setText(NbBundle.getMessage(CustomizerSupport.class,key));
415
            label.setDisplayedMnemonic(NbBundle.getMessage(CustomizerSupport.class,mneKey).charAt(0));
416
            GridBagConstraints c = new GridBagConstraints();
417
            c.gridx = GridBagConstraints.RELATIVE;
418
            c.gridy = GridBagConstraints.RELATIVE;
419
            c.gridwidth = GridBagConstraints.REMAINDER;
420
            c.insets = new Insets (6,12,2,0);
421
            c.fill = GridBagConstraints.HORIZONTAL;
422
            c.weightx = 1.0;
423
            ((GridBagLayout)getLayout()).setConstraints(label,c);
424
            add(label);
425
            resources = new JList(model);
426
            label.setLabelFor(resources);
427
            resources.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerSupport.class,ad));
428
            resources.addListSelectionListener(new ListSelectionListener() {
429
                public void valueChanged(ListSelectionEvent e) {
430
                    selectionChanged ();
431
                }
432
            });
433
            JScrollPane spane = new JScrollPane (this.resources);            
434
            // set the preferred size so that the size won't be set according to
435
            // the longest row in the list by default
436
            spane.setPreferredSize(new java.awt.Dimension(200, 100));
437
            c = new GridBagConstraints();
438
            c.gridx = GridBagConstraints.RELATIVE;
439
            c.gridy = GridBagConstraints.RELATIVE;
440
            c.gridwidth = 1;
441
            c.gridheight = 5;
442
            c.insets = new Insets (0,12,12,6);
443
            c.fill = GridBagConstraints.BOTH;
444
            c.weightx = 1.0;
445
            c.weighty = 1.0;
446
            ((GridBagLayout)this.getLayout()).setConstraints(spane,c);
447
            add(spane);
448
            if (type == SOURCES || type == JAVADOC) {
449
                this.addButton = new JButton ();
450
                String text;
451
                char mne;
452
                if (type == SOURCES) {
453
                    text = NbBundle.getMessage(CustomizerSupport.class, "CTL_Add");
454
                    mne = NbBundle.getMessage(CustomizerSupport.class, "MNE_Add").charAt(0);
455
                    ad = NbBundle.getMessage(CustomizerSupport.class, "AD_Add");
456
                }
457
                else {
458
                    text = NbBundle.getMessage(CustomizerSupport.class, "CTL_AddZip");
459
                    mne = NbBundle.getMessage(CustomizerSupport.class, "MNE_AddZip").charAt(0);
460
                    ad = NbBundle.getMessage(CustomizerSupport.class, "AD_AddZip");
461
                }
462
                this.addButton.setText(text);
463
                this.addButton.setMnemonic(mne);
464
                this.addButton.getAccessibleContext().setAccessibleDescription (ad);
465
                addButton.addActionListener( new ActionListener () {
466
                    public void actionPerformed(ActionEvent e) {
467
                        addPathElement ();
468
                    }
469
                });
470
                c = new GridBagConstraints();
471
                c.gridx = 1;
472
                c.gridy = 1;
473
                c.gridwidth = GridBagConstraints.REMAINDER;
474
                c.fill = GridBagConstraints.HORIZONTAL;
475
                c.anchor = GridBagConstraints.NORTHWEST;
476
                c.insets = new Insets (0,6,0,6);
477
                ((GridBagLayout)this.getLayout()).setConstraints(addButton,c);
478
                this.add (addButton);
479
//                if (this.type == JAVADOC) {
480
//                    addURLButton  = new JButton (NbBundle.getMessage(CustomizerSupport.class, "CTL_AddURL"));
481
//                    addURLButton.setMnemonic(NbBundle.getMessage(CustomizerSupport.class, "MNE_AddURL").charAt(0));
482
//                    addURLButton.addActionListener(new ActionListener () {
483
//                        public void actionPerformed(ActionEvent e) {
484
//                            addURLElement ();
485
//                        }
486
//                    });
487
//                    c = new GridBagConstraints();
488
//                    c.gridx = 1;
489
//                    c.gridy = 2;
490
//                    c.gridwidth = GridBagConstraints.REMAINDER;
491
//                    c.fill = GridBagConstraints.HORIZONTAL;
492
//                    c.anchor = GridBagConstraints.NORTHWEST;
493
//                    c.insets = new Insets (0,6,6,12);
494
//                    ((GridBagLayout)this.getLayout()).setConstraints(addURLButton,c);
495
//                    this.add (addURLButton);
496
//                }
497
                removeButton = new JButton (NbBundle.getMessage(CustomizerSupport.class, "CTL_Remove"));
498
                removeButton.setMnemonic(NbBundle.getMessage(CustomizerSupport.class, "MNE_Remove").charAt(0));
499
                removeButton.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(CustomizerSupport.class,"AD_Remove"));
500
                removeButton.addActionListener( new ActionListener () {
501
                    public void actionPerformed(ActionEvent e) {
502
                        removePathElement ();
503
                    }
504
                });
505
                removeButton.setEnabled(false);
506
                c = new GridBagConstraints();
507
                c.gridx = 1;
508
                c.gridy = 3;
509
                c.gridwidth = GridBagConstraints.REMAINDER;
510
                c.fill = GridBagConstraints.HORIZONTAL;
511
                c.anchor = GridBagConstraints.NORTHWEST;
512
                c.insets = new Insets (12,6,0,6);
513
                ((GridBagLayout)this.getLayout()).setConstraints(removeButton,c);
514
                this.add (removeButton);
515
                moveUpButton = new JButton (NbBundle.getMessage(CustomizerSupport.class, "CTL_Up"));
516
                moveUpButton.setMnemonic(NbBundle.getMessage(CustomizerSupport.class, "MNE_Up").charAt(0));
517
                moveUpButton.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(CustomizerSupport.class,"AD_Up"));
518
                moveUpButton.addActionListener( new ActionListener () {
519
                    public void actionPerformed(ActionEvent e) {
520
                        moveUpPathElement ();
521
                    }
522
                });
523
                moveUpButton.setEnabled(false);
524
                c = new GridBagConstraints();
525
                c.gridx = 1;
526
                c.gridy = 4;
527
                c.gridwidth = GridBagConstraints.REMAINDER;
528
                c.fill = GridBagConstraints.HORIZONTAL;
529
                c.anchor = GridBagConstraints.NORTHWEST;
530
                c.insets = new Insets (12,6,0,6);
531
                ((GridBagLayout)this.getLayout()).setConstraints(moveUpButton,c);
532
                this.add (moveUpButton);
533
                moveDownButton = new JButton (NbBundle.getMessage(CustomizerSupport.class, "CTL_Down"));
534
                moveDownButton.setMnemonic (NbBundle.getMessage(CustomizerSupport.class, "MNE_Down").charAt(0));
535
                moveDownButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(CustomizerSupport.class,"AD_Down"));
536
                moveDownButton.addActionListener( new ActionListener () {
537
                    public void actionPerformed(ActionEvent e) {
538
                        moveDownPathElement ();
539
                    }
540
                });
541
                moveDownButton.setEnabled(false);
542
                c = new GridBagConstraints();
543
                c.gridx = 1;
544
                c.gridy = 5;
545
                c.gridwidth = GridBagConstraints.REMAINDER;
546
                c.fill = GridBagConstraints.HORIZONTAL;
547
                c.anchor = GridBagConstraints.NORTHWEST;
548
                c.insets = new Insets (5,6,6,6);
549
                ((GridBagLayout)this.getLayout()).setConstraints(moveDownButton,c);
550
                this.add (moveDownButton);
551
            }
552
        }
553
        
554
//        private void addURLElement() {
555
//            JPanel p = new JPanel ();
556
//            GridBagLayout lm = new GridBagLayout();
557
//            p.setLayout (lm);
558
//            GridBagConstraints c = new GridBagConstraints ();
559
//            c.gridx = c.gridy = GridBagConstraints.RELATIVE;
560
//            c.insets = new Insets (12,12,12,6);
561
//            c.anchor = GridBagConstraints.NORTHWEST;
562
//            JLabel label = new JLabel (NbBundle.getMessage(CustomizerSupport.class,"CTL_AddJavadocURLMessage"));
563
//            label.setDisplayedMnemonic ('U');
564
//            lm.setConstraints(label,c);
565
//            p.add (label);
566
//            c = new GridBagConstraints ();
567
//            c.gridx = c.gridy = GridBagConstraints.RELATIVE;
568
//            c.gridwidth = GridBagConstraints.REMAINDER;
569
//            c.insets = new Insets (12,0,12,6);
570
//            c.fill = GridBagConstraints.HORIZONTAL;
571
//            c.anchor = GridBagConstraints.NORTHWEST;
572
//            JTextField text = new JTextField ();
573
//            text.setColumns(30);
574
//            text.setText (NbBundle.getMessage(CustomizerSupport.class,"TXT_DefaultProtocol"));
575
//            text.selectAll();
576
//            label.setLabelFor(text);
577
//            lm.setConstraints(text,c);
578
//            p.add (text);            
579
//            JButton[] options = new JButton[] {
580
//                new JButton (NbBundle.getMessage(CustomizerSupport.class,"CTL_AddJavadocURLTitle")),
581
//                new JButton (NbBundle.getMessage(CustomizerSupport.class,"CTL_Cancel"))
582
//            };
583
//            options[0].setMnemonic(NbBundle.getMessage(CustomizerSupport.class,"MNE_Add").charAt(0));
584
//            options[1].setMnemonic(NbBundle.getMessage(CustomizerSupport.class,"MNE_Cancel").charAt(0));
585
//            DialogDescriptor input = new DialogDescriptor (
586
//                p,
587
//                NbBundle.getMessage(CustomizerSupport.class,"CTL_AddJavadocURLTitle"),
588
//                true, options, options[0], DialogDescriptor.DEFAULT_ALIGN, null, null);            
589
//            if (DialogDisplayer.getDefault().notify(input) == options[0]) {
590
//                try {
591
//                    String value = text.getText();
592
//                    URL url = new URL (value);
593
//                    ((PathModel)this.resources.getModel()).addPath(url);
594
//                    this.resources.setSelectedIndex (this.resources.getModel().getSize()-1);
595
//                } catch (MalformedURLException mue) {
596
//                    DialogDescriptor.Message message = new DialogDescriptor.Message (
597
//                        NbBundle.getMessage(CustomizerSupport.class,"CTL_InvalidURLFormat"),
598
//                        DialogDescriptor.ERROR_MESSAGE);
599
//                    DialogDisplayer.getDefault().notify(message);
600
//                }
601
//            }
602
//        }
603
604
        private void addPathElement () {
605
            JFileChooser chooser = new JFileChooser();
606
            FileUtil.preventFileChooserSymlinkTraversal(chooser, null);
607
            chooser.setMultiSelectionEnabled (true);
608
            String title = null;
609
            String message = null;
610
            String approveButtonName = null;
611
            String approveButtonNameMne = null;
612
            if (this.type == SOURCES) {
613
                title = NbBundle.getMessage (CustomizerSupport.class,"TXT_OpenSources");
614
                message = NbBundle.getMessage (CustomizerSupport.class,"TXT_Sources");
615
                approveButtonName = NbBundle.getMessage (CustomizerSupport.class,"TXT_OpenSources");
616
                approveButtonNameMne = NbBundle.getMessage (CustomizerSupport.class,"MNE_OpenSources");
617
            }
618
            else if (this.type == JAVADOC) {
619
                title = NbBundle.getMessage (CustomizerSupport.class,"TXT_OpenJavadoc");
620
                message = NbBundle.getMessage (CustomizerSupport.class,"TXT_Javadoc");
621
                approveButtonName = NbBundle.getMessage (CustomizerSupport.class,"TXT_OpenJavadoc");
622
                approveButtonNameMne = NbBundle.getMessage (CustomizerSupport.class,"MNE_OpenJavadoc");
623
            }
624
            chooser.setDialogTitle(title);
625
            chooser.setApproveButtonText(approveButtonName);
626
            chooser.setApproveButtonMnemonic (approveButtonNameMne.charAt(0));
627
            chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
628
            //#61789 on old macosx (jdk 1.4.1) these two method need to be called in this order.
629
            chooser.setAcceptAllFileFilterUsed( false );
630
            chooser.setFileFilter (new SimpleFileFilter(message,new String[] {"ZIP","JAR"}));   //NOI18N
631
            if (this.currentDir != null && currentDir.exists()) {
632
                chooser.setCurrentDirectory(this.currentDir);
633
            }
634
            if (chooser.showOpenDialog(this)==JFileChooser.APPROVE_OPTION) {
635
                File[] fs = chooser.getSelectedFiles();
636
                PathModel model = (PathModel) this.resources.getModel();
637
                boolean addingFailed = false;
638
                int firstIndex = this.resources.getModel().getSize();
639
                for (int i = 0; i < fs.length; i++) {
640
                    File f = fs[i];
641
                    //XXX: JFileChooser workaround (JDK bug #5075580), double click on folder returns wrong file
642
                    // E.g. for /foo/src it returns /foo/src/src
643
                    // Try to convert it back by removing last invalid name component
644
                    if (!f.exists()) {
645
                        File parent = f.getParentFile();
646
                        if (parent != null && f.getName().equals(parent.getName()) && parent.exists()) {
647
                            f = parent;
648
                        }
649
                    }
650
                    addingFailed|=!model.addPath (f);
651
                }
652
                if (addingFailed) {
653
                    new NotifyDescriptor.Message (NbBundle.getMessage(CustomizerSupport.class,"TXT_CanNotAddResolve"),
654
                            NotifyDescriptor.ERROR_MESSAGE);
655
                }
656
                int lastIndex = this.resources.getModel().getSize()-1;
657
                if (firstIndex<=lastIndex) {
658
                    int[] toSelect = new int[lastIndex-firstIndex+1];
659
                    for (int i = 0; i < toSelect.length; i++) {
660
                        toSelect[i] = firstIndex+i;
661
                    }
662
                    this.resources.setSelectedIndices(toSelect);
663
                }
664
                this.currentDir = FileUtil.normalizeFile(chooser.getCurrentDirectory());
665
            }
666
        }
667
668
        private void removePathElement () {
669
            int[] indices = this.resources.getSelectedIndices();
670
            if (indices.length == 0) {
671
                return;
672
            }
673
            PathModel model = (PathModel) this.resources.getModel();
674
            model.removePath (indices);
675
            if ( indices[indices.length-1]-indices.length+1 < this.resources.getModel().getSize()) {
676
                this.resources.setSelectedIndex (indices[indices.length-1]-indices.length+1);
677
            }
678
            else if (indices[0]>0) {
679
                this.resources.setSelectedIndex (indices[0]-1);
680
            }
681
        }
682
683
        private void moveDownPathElement () {
684
            int[] indices = this.resources.getSelectedIndices();
685
            if (indices.length == 0) {
686
                return;
687
            }
688
            PathModel model = (PathModel) this.resources.getModel();
689
            model.moveDownPath (indices);
690
            for (int i=0; i< indices.length; i++) {
691
                indices[i] = indices[i] + 1;
692
            }
693
            this.resources.setSelectedIndices (indices);
694
        }
695
696
        private void moveUpPathElement () {
697
            int[] indices = this.resources.getSelectedIndices();
698
            if (indices.length == 0) {
699
                return;
700
            }
701
            PathModel model = (PathModel) this.resources.getModel();
702
            model.moveUpPath (indices);
703
            for (int i=0; i< indices.length; i++) {
704
                indices[i] = indices[i] - 1;
705
            }
706
            this.resources.setSelectedIndices (indices);
707
        }
708
709
        private void selectionChanged () {
710
            if (this.type == CLASSPATH) {
711
                return;
712
            }
713
            int indices[] = this.resources.getSelectedIndices();
714
            this.removeButton.setEnabled (indices.length > 0);
715
            this.moveUpButton.setEnabled (indices.length > 0 && indices[0]>0);
716
            this.moveDownButton.setEnabled(indices.length > 0 && indices[indices.length-1]<this.resources.getModel().getSize()-1);
717
        }
718
    }
719
    
720
    private static class SimpleFileFilter extends FileFilter {
721
722
        private String description;
723
        private Collection extensions;
724
725
726
        public SimpleFileFilter (String description, String[] extensions) {
727
            this.description = description;
728
            this.extensions = Arrays.asList(extensions);
729
        }
730
731
        public boolean accept(File f) {
732
            if (f.isDirectory())
733
                return true;
734
            String name = f.getName();
735
            int index = name.lastIndexOf('.');   //NOI18N
736
            if (index <= 0 || index==name.length()-1)
737
                return false;
738
            String extension = name.substring (index+1).toUpperCase();
739
            return this.extensions.contains(extension);
740
        }
741
742
        public String getDescription() {
743
            return this.description;
744
        }
745
    }
746
}

Return to bug 74646