KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > web > project > ui > customizer > WebSourceRootsUi


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.modules.web.project.ui.customizer;
21
22 import java.awt.*;
23 import java.awt.event.ActionEvent JavaDoc;
24 import java.awt.event.ActionListener JavaDoc;
25 import java.io.File JavaDoc;
26 import java.net.URI JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.HashSet JavaDoc;
30 import java.util.Set JavaDoc;
31 import java.util.Vector JavaDoc;
32 import java.text.MessageFormat JavaDoc;
33 import javax.swing.*;
34 import javax.swing.event.ListSelectionEvent JavaDoc;
35 import javax.swing.event.ListSelectionListener JavaDoc;
36 import javax.swing.event.CellEditorListener JavaDoc;
37 import javax.swing.event.ChangeEvent JavaDoc;
38 import javax.swing.table.DefaultTableCellRenderer JavaDoc;
39 import javax.swing.table.DefaultTableModel JavaDoc;
40 import org.netbeans.api.project.ProjectUtils;
41 import org.netbeans.modules.web.project.WebProject;
42 import org.netbeans.api.project.FileOwnerQuery;
43 import org.netbeans.api.project.Project;
44 import org.netbeans.api.project.ProjectInformation;
45 import org.netbeans.modules.web.project.SourceRoots;
46 import org.openide.DialogDisplayer;
47 import org.openide.DialogDescriptor;
48 import org.openide.filesystems.FileUtil;
49 import org.openide.util.NbBundle;
50
51
52 /** Handles adding, removing, reordering of source roots.
53  *
54  * @author Tomas Zezula, Radko Najman
55  */

56 public final class WebSourceRootsUi {
57   
58     public static DefaultTableModel JavaDoc createModel( SourceRoots roots ) {
59         
60         String JavaDoc[] rootLabels = roots.getRootNames();
61         String JavaDoc[] rootProps = roots.getRootProperties();
62         URL JavaDoc[] rootURLs = roots.getRootURLs();
63         Object JavaDoc[][] data = new Object JavaDoc[rootURLs.length] [2];
64         for (int i=0; i< rootURLs.length; i++) {
65             data[i][0] = new File JavaDoc (URI.create (rootURLs[i].toExternalForm()));
66             data[i][1] = roots.getRootDisplayName(rootLabels[i], rootProps[i]);
67         }
68         return new SourceRootsModel(data);
69                 
70     }
71     
72     public static EditMediator registerEditMediator( WebProject master,
73                                              SourceRoots sourceRoots,
74                                              JTable rootsList,
75                                              JButton addFolderButton,
76                                              JButton removeButton,
77                                              JButton upButton,
78                                              JButton downButton) {
79         
80         EditMediator em = new EditMediator( master,
81                                             sourceRoots,
82                                             rootsList,
83                                             addFolderButton,
84                                             removeButton,
85                                             upButton,
86                                             downButton);
87         
88         // Register the listeners
89
// On all buttons
90
addFolderButton.addActionListener( em );
91         removeButton.addActionListener( em );
92         upButton.addActionListener( em );
93         downButton.addActionListener( em );
94         // On list selection
95
rootsList.getSelectionModel().addListSelectionListener( em );
96         DefaultCellEditor editor = new DefaultCellEditor(new JTextField());
97         editor.addCellEditorListener (em);
98         rootsList.setDefaultRenderer( File JavaDoc.class, new FileRenderer (FileUtil.toFile(master.getProjectDirectory())));
99         rootsList.setDefaultEditor(String JavaDoc.class, editor);
100         // Set the initial state of the buttons
101
em.valueChanged( null );
102         
103         DefaultTableModel JavaDoc model = (DefaultTableModel JavaDoc)rootsList.getModel();
104         String JavaDoc[] columnNames = new String JavaDoc[2];
105         columnNames[0] = NbBundle.getMessage( WebSourceRootsUi.class,"CTL_PackageFolders"); //NOI18N
106
columnNames[1] = NbBundle.getMessage( WebSourceRootsUi.class,"CTL_PackageLabels"); //NOI18N
107
model.setColumnIdentifiers(columnNames);
108         rootsList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
109         
110         return em;
111     }
112         
113     /**
114      * Opens the standard dialog for warning an user about illegal source roots.
115      * @param roots the set of illegal source/test roots
116      */

117     public static void showIllegalRootsDialog (Set JavaDoc/*<File>*/ roots) {
118         JButton closeOption = new JButton (NbBundle.getMessage(WebSourceRootsUi.class,"CTL_WebSourceRootsUi_Close"));
119         closeOption.getAccessibleContext ().setAccessibleDescription (NbBundle.getMessage(WebSourceRootsUi.class,"AD_WebSourceRootsUi_Close"));
120         JPanel warning = new WarningDlg (roots);
121         String JavaDoc message = NbBundle.getMessage(WebSourceRootsUi.class,"MSG_InvalidRoot");
122         JOptionPane optionPane = new JOptionPane (new Object JavaDoc[] {message, warning},
123             JOptionPane.WARNING_MESSAGE,
124             0,
125             null,
126             new Object JavaDoc[0],
127             null);
128         optionPane.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(WebSourceRootsUi.class,"AD_InvalidRootDlg"));
129         DialogDescriptor dd = new DialogDescriptor (optionPane,
130             NbBundle.getMessage(WebSourceRootsUi.class,"TITLE_InvalidRoot"),
131             true,
132             new Object JavaDoc[] {
133                 closeOption,
134             },
135             closeOption,
136             DialogDescriptor.DEFAULT_ALIGN,
137             null,
138             null);
139         DialogDisplayer.getDefault().notify(dd);
140     }
141  
142     // Private innerclasses ----------------------------------------------------
143

144     public static class EditMediator implements ActionListener JavaDoc, ListSelectionListener JavaDoc, CellEditorListener JavaDoc {
145
146         
147         final JTable rootsList;
148         final JButton addFolderButton;
149         final JButton removeButton;
150         final JButton upButton;
151         final JButton downButton;
152         private final Project project;
153         private final SourceRoots sourceRoots;
154         private final Set JavaDoc ownedFolders;
155         private DefaultTableModel JavaDoc rootsModel;
156         private EditMediator relatedEditMediator;
157         private File JavaDoc lastUsedDir; //Last used current folder in JFileChooser
158

159         public EditMediator( WebProject master,
160                              SourceRoots sourceRoots,
161                              JTable rootsList,
162                              JButton addFolderButton,
163                              JButton removeButton,
164                              JButton upButton,
165                              JButton downButton) {
166
167             if ( !( rootsList.getModel() instanceof DefaultTableModel JavaDoc ) ) {
168                 throw new IllegalArgumentException JavaDoc( "Jtable's model has to be of class DefaultTableModel" ); // NOI18N
169
}
170                     
171             this.rootsList = rootsList;
172             this.addFolderButton = addFolderButton;
173             this.removeButton = removeButton;
174             this.upButton = upButton;
175             this.downButton = downButton;
176             this.ownedFolders = new HashSet JavaDoc();
177
178             this.project = master;
179             this.sourceRoots = sourceRoots;
180
181             this.ownedFolders.clear();
182             this.rootsModel = (DefaultTableModel JavaDoc)rootsList.getModel();
183             Vector JavaDoc data = rootsModel.getDataVector();
184             for (Iterator JavaDoc it = data.iterator(); it.hasNext();) {
185                 Vector JavaDoc row = (Vector JavaDoc) it.next ();
186                 File JavaDoc f = (File JavaDoc) row.elementAt(0);
187                 this.ownedFolders.add (f);
188             }
189         }
190         
191         public void setRelatedEditMediator(EditMediator rem) {
192             this.relatedEditMediator = rem;
193         }
194         
195         // Implementation of ActionListener ------------------------------------
196

197         /** Handles button events
198          */

199         public void actionPerformed( ActionEvent JavaDoc e ) {
200             
201             Object JavaDoc source = e.getSource();
202             
203             if ( source == addFolderButton ) {
204                 // Let user search for the Jar file
205
JFileChooser chooser = new JFileChooser();
206                 FileUtil.preventFileChooserSymlinkTraversal(chooser, null);
207                 chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
208                 chooser.setMultiSelectionEnabled( true );
209                 
210                 if (sourceRoots.isTest())
211                     chooser.setDialogTitle( NbBundle.getMessage( WebSourceRootsUi.class, "LBL_TestFolder_DialogTitle" )); // NOI18N
212
else
213                     chooser.setDialogTitle( NbBundle.getMessage( WebSourceRootsUi.class, "LBL_SourceFolder_DialogTitle" )); // NOI18N
214

215                 File JavaDoc curDir = this.lastUsedDir;
216                 if (curDir == null) {
217                     curDir = FileUtil.toFile(this.project.getProjectDirectory());
218                 }
219                 if (curDir != null) {
220                     chooser.setCurrentDirectory (curDir);
221                 }
222                 int option = chooser.showOpenDialog( SwingUtilities.getWindowAncestor( addFolderButton ) ); // Sow the chooser
223

224                 if ( option == JFileChooser.APPROVE_OPTION ) {
225                     curDir = chooser.getCurrentDirectory();
226                     if (curDir != null) {
227                         this.lastUsedDir = curDir;
228                         if (this.relatedEditMediator != null) {
229                             this.relatedEditMediator.lastUsedDir = curDir;
230                         }
231                     }
232                     File JavaDoc files[] = chooser.getSelectedFiles();
233                     addFolders( files );
234                 }
235                 
236             }
237             else if ( source == removeButton ) {
238                 removeElements();
239             }
240             else if ( source == upButton ) {
241                 moveUp();
242             }
243             else if ( source == downButton ) {
244                 moveDown();
245             }
246         }
247         
248         // Selection listener implementation ----------------------------------
249

250         /** Handles changes in the selection
251          */

252         public void valueChanged( ListSelectionEvent JavaDoc e ) {
253             
254             int[] si = rootsList.getSelectedRows();
255             
256             // addJar allways enabled
257

258             // addLibrary allways enabled
259

260             // addArtifact allways enabled
261

262             // remove enabled only if selection is not empty
263
boolean remove = si != null && si.length > 0;
264             // and when the selection does not contain unremovable item
265

266             // up button enabled if selection is not empty
267
// and the first selected index is not the first row
268
boolean up = si != null && si.length > 0 && si[0] != 0;
269             
270             // up button enabled if selection is not empty
271
// and the laset selected index is not the last row
272
boolean down = si != null && si.length > 0 && si[si.length-1] !=rootsList.getRowCount() - 1;
273
274             removeButton.setEnabled( remove );
275             upButton.setEnabled( up );
276             downButton.setEnabled( down );
277         }
278
279         public void editingCanceled(ChangeEvent JavaDoc e) {
280
281         }
282
283         public void editingStopped(ChangeEvent JavaDoc e) {
284             // fireActionPerformed();
285
}
286         
287         private void addFolders( File JavaDoc files[] ) {
288             int[] si = rootsList.getSelectedRows();
289             int lastIndex = si == null || si.length == 0 ? -1 : si[si.length - 1];
290             ListSelectionModel selectionModel = this.rootsList.getSelectionModel();
291             selectionModel.clearSelection();
292             Set JavaDoc rootsFromOtherProjects = new HashSet JavaDoc ();
293             Set JavaDoc rootsFromRelatedSourceRoots = new HashSet JavaDoc();
294             for( int i = 0; i < files.length; i++ ) {
295                 File JavaDoc normalizedFile = FileUtil.normalizeFile(files[i]);
296                 Project p;
297                 if (ownedFolders.contains(normalizedFile)) {
298                     Vector JavaDoc dataVector = rootsModel.getDataVector();
299                     for (int j=0; j<dataVector.size();j++) {
300                         //Sequential search in this minor case is faster than update of positions during each modification
301
File JavaDoc f = (File JavaDoc )((Vector JavaDoc)dataVector.elementAt(j)).elementAt(0);
302                         if (f.equals(normalizedFile)) {
303                             selectionModel.addSelectionInterval(j,j);
304                         }
305                     }
306                 }
307                 else if (this.relatedEditMediator != null && this.relatedEditMediator.ownedFolders.contains(normalizedFile)) {
308                     rootsFromRelatedSourceRoots.add (normalizedFile);
309                 }
310                 else if ((p=FileOwnerQuery.getOwner(normalizedFile.toURI()))!=null && !p.getProjectDirectory().equals(project.getProjectDirectory())) {
311                     rootsFromOtherProjects.add (normalizedFile);
312                 }
313                 else {
314                     int current = lastIndex + 1 + i;
315                     rootsModel.insertRow( current, new Object JavaDoc[] {normalizedFile, sourceRoots.createInitialDisplayName(normalizedFile)}); //NOI18N
316
selectionModel.addSelectionInterval(current,current);
317                     this.ownedFolders.add (normalizedFile);
318                 }
319             }
320             if (rootsFromOtherProjects.size() > 0 || rootsFromRelatedSourceRoots.size() > 0) {
321                 rootsFromOtherProjects.addAll(rootsFromRelatedSourceRoots);
322                 showIllegalRootsDialog (rootsFromOtherProjects);
323             }
324             // fireActionPerformed();
325
}
326
327         private void removeElements() {
328
329             int[] si = rootsList.getSelectedRows();
330
331             if( si == null || si.length == 0 ) {
332                 assert false : "Remove button should be disabled"; // NOI18N
333
}
334
335             // Remove the items
336
for( int i = si.length - 1 ; i >= 0 ; i-- ) {
337                 this.ownedFolders.remove(((Vector JavaDoc)rootsModel.getDataVector().elementAt(0)).elementAt(0));
338                 rootsModel.removeRow( si[i] );
339             }
340
341
342             if ( rootsModel.getRowCount() != 0) {
343                 // Select reasonable item
344
int selectedIndex = si[si.length - 1] - si.length + 1;
345                 if ( selectedIndex > rootsModel.getRowCount() - 1) {
346                     selectedIndex = rootsModel.getRowCount() - 1;
347                 }
348                 rootsList.setRowSelectionInterval( selectedIndex, selectedIndex );
349             }
350
351             // fireActionPerformed();
352

353         }
354
355         private void moveUp() {
356
357             int[] si = rootsList.getSelectedRows();
358
359             if( si == null || si.length == 0 ) {
360                 assert false : "MoveUp button should be disabled"; // NOI18N
361
}
362
363             // Move the items up
364
ListSelectionModel selectionModel = this.rootsList.getSelectionModel();
365             selectionModel.clearSelection();
366             for( int i = 0; i < si.length; i++ ) {
367                 Vector JavaDoc item = (Vector JavaDoc) rootsModel.getDataVector().elementAt(si[i]);
368                 int newIndex = si[i]-1;
369                 rootsModel.removeRow( si[i] );
370                 rootsModel.insertRow( newIndex, item );
371                 selectionModel.addSelectionInterval(newIndex,newIndex);
372             }
373             // fireActionPerformed();
374
}
375
376         private void moveDown() {
377
378             int[] si = rootsList.getSelectedRows();
379
380             if( si == null || si.length == 0 ) {
381                 assert false : "MoveDown button should be disabled"; // NOI18N
382
}
383
384             // Move the items up
385
ListSelectionModel selectionModel = this.rootsList.getSelectionModel();
386             selectionModel.clearSelection();
387             for( int i = si.length -1 ; i >= 0 ; i-- ) {
388                 Vector JavaDoc item = (Vector JavaDoc) rootsModel.getDataVector().elementAt(si[i]);
389                 int newIndex = si[i] + 1;
390                 rootsModel.removeRow( si[i] );
391                 rootsModel.insertRow( newIndex, item );
392                 selectionModel.addSelectionInterval(newIndex,newIndex);
393             }
394             // fireActionPerformed();
395
}
396         
397
398     }
399
400     private static class SourceRootsModel extends DefaultTableModel JavaDoc {
401
402         public SourceRootsModel (Object JavaDoc[][] data) {
403             super (data,new Object JavaDoc[]{"location","label"});//NOI18N
404
}
405
406         public boolean isCellEditable(int row, int column) {
407             return column == 1;
408         }
409
410         public Class JavaDoc getColumnClass(int columnIndex) {
411             switch (columnIndex) {
412                 case 0:
413                     return File JavaDoc.class;
414                 case 1:
415                     return String JavaDoc.class;
416                 default:
417                     return super.getColumnClass (columnIndex);
418             }
419         }
420     }
421     
422     private static class FileRenderer extends DefaultTableCellRenderer JavaDoc {
423         
424         private File JavaDoc projectFolder;
425         
426         public FileRenderer (File JavaDoc projectFolder) {
427             this.projectFolder = projectFolder;
428         }
429         
430         public Component getTableCellRendererComponent(JTable table, Object JavaDoc value, boolean isSelected, boolean hasFocus,int row, int column) {
431             String JavaDoc displayName;
432            if (value instanceof File JavaDoc) {
433                 File JavaDoc root = (File JavaDoc) value;
434                 String JavaDoc pfPath = projectFolder.getAbsolutePath() + File.separatorChar;
435                 String JavaDoc srPath = root.getAbsolutePath();
436                 if (srPath.startsWith(pfPath)) {
437                     displayName = srPath.substring(pfPath.length());
438                 }
439                 else {
440                     displayName = srPath;
441                 }
442             }
443             else {
444                 displayName = null;
445             }
446             Component c = super.getTableCellRendererComponent(table, displayName, isSelected, hasFocus, row, column);
447             if (c instanceof JComponent) {
448                 ((JComponent) c).setToolTipText (displayName);
449             }
450             return c;
451         }
452     }
453
454     private static class WarningDlg extends JPanel {
455
456         public WarningDlg (Set JavaDoc invalidRoots) {
457             this.initGui (invalidRoots);
458         }
459
460         private void initGui (Set JavaDoc invalidRoots) {
461             setLayout( new GridBagLayout ());
462             JLabel label = new JLabel ();
463             label.setText (NbBundle.getMessage(WebSourceRootsUi.class,"LBL_InvalidRoot")); //NOI18N
464
label.setDisplayedMnemonic(NbBundle.getMessage(WebSourceRootsUi.class,"MNE_InvalidRoot").charAt(0)); //NOI18N
465
GridBagConstraints c = new GridBagConstraints();
466             c.gridx = GridBagConstraints.RELATIVE;
467             c.gridy = GridBagConstraints.RELATIVE;
468             c.gridwidth = GridBagConstraints.REMAINDER;
469             c.fill = GridBagConstraints.HORIZONTAL;
470             c.anchor = GridBagConstraints.NORTHWEST;
471             c.weightx = 1.0;
472             c.insets = new Insets (12,0,6,0);
473             ((GridBagLayout)this.getLayout()).setConstraints(label,c);
474             this.add (label);
475             JList roots = new JList (invalidRoots.toArray());
476             roots.setCellRenderer (new InvalidRootRenderer(true));
477             JScrollPane p = new JScrollPane (roots);
478             c = new GridBagConstraints();
479             c.gridx = GridBagConstraints.RELATIVE;
480             c.gridy = GridBagConstraints.RELATIVE;
481             c.gridwidth = GridBagConstraints.REMAINDER;
482             c.fill = GridBagConstraints.BOTH;
483             c.anchor = GridBagConstraints.NORTHWEST;
484             c.weightx = c.weighty = 1.0;
485             c.insets = new Insets (0,0,12,0);
486             ((GridBagLayout)this.getLayout()).setConstraints(p,c);
487             this.add (p);
488             label.setLabelFor(roots);
489             roots.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(WebSourceRootsUi.class,"AD_InvalidRoot")); //NOI18N
490
JLabel label2 = new JLabel ();
491             label2.setText (NbBundle.getMessage(WebSourceRootsUi.class,"MSG_InvalidRoot2")); //NOI18N
492
c = new GridBagConstraints();
493             c.gridx = GridBagConstraints.RELATIVE;
494             c.gridy = GridBagConstraints.RELATIVE;
495             c.gridwidth = GridBagConstraints.REMAINDER;
496             c.fill = GridBagConstraints.HORIZONTAL;
497             c.anchor = GridBagConstraints.NORTHWEST;
498             c.weightx = 1.0;
499             c.insets = new Insets (0,0,0,0);
500             ((GridBagLayout)this.getLayout()).setConstraints(label2,c);
501             this.add (label2);
502         }
503
504         private static class InvalidRootRenderer extends DefaultListCellRenderer {
505
506             private boolean projectConflict;
507
508             public InvalidRootRenderer (boolean projectConflict) {
509                 this.projectConflict = projectConflict;
510             }
511
512             public Component getListCellRendererComponent(JList list, Object JavaDoc value, int index, boolean isSelected, boolean cellHasFocus) {
513                 File JavaDoc f = (File JavaDoc) value;
514                 String JavaDoc message = f.getAbsolutePath();
515                 if (projectConflict) {
516                     Project p = FileOwnerQuery.getOwner(f.toURI());
517                     if (p!=null) {
518                         ProjectInformation pi = ProjectUtils.getInformation(p);
519                         String JavaDoc projectName = pi.getDisplayName();
520                         message = MessageFormat.format (NbBundle.getMessage(WebSourceRootsUi.class,"TXT_RootOwnedByProject"), new Object JavaDoc[] { //NOI18N
521
message,
522                             projectName});
523                     }
524                 }
525                 return super.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus);
526             }
527         }
528     }
529 }
530
Popular Tags