1 19 20 package org.netbeans.modules.java.j2seproject.ui.wizards; 21 22 23 import java.awt.Color ; 24 import java.awt.Component ; 25 import java.beans.PropertyChangeListener ; 26 import java.io.File ; 27 import java.text.MessageFormat ; 28 import java.util.Arrays ; 29 import java.util.Collections ; 30 import java.util.HashSet ; 31 import java.util.Set ; 32 import javax.swing.DefaultListModel ; 33 import javax.swing.DefaultListCellRenderer ; 34 import javax.swing.Icon ; 35 import javax.swing.JFileChooser ; 36 import javax.swing.JList ; 37 import javax.swing.event.ListSelectionListener ; 38 import javax.swing.event.ListSelectionEvent ; 39 import org.netbeans.api.java.project.JavaProjectConstants; 40 import org.netbeans.api.project.SourceGroup; 41 import org.netbeans.api.project.Sources; 42 import org.netbeans.modules.java.j2seproject.ui.customizer.J2SESourceRootsUi; 43 import org.openide.filesystems.FileObject; 44 import org.openide.filesystems.FileUtil; 45 import org.openide.util.NbBundle; 46 import org.netbeans.api.project.FileOwnerQuery; 47 import org.netbeans.api.project.Project; 48 import org.netbeans.api.project.ProjectInformation; 49 import org.netbeans.modules.java.j2seproject.ui.FoldersListSettings; 50 51 52 56 public final class FolderList extends javax.swing.JPanel { 57 58 public static final String PROP_FILES = "files"; public static final String PROP_LAST_USED_DIR = "lastUsedDir"; 61 private String fcMessage; 62 private File projectFolder; 63 private File lastUsedFolder; 64 private FolderList relatedFolderList; 65 66 67 public FolderList (String label, char mnemonic, String accessibleDesc, String fcMessage, 68 char addButtonMnemonic, String addButtonAccessibleDesc, 69 char removeButtonMnemonic,String removeButtonAccessibleDesc) { 70 this.fcMessage = fcMessage; 71 initComponents(); 72 this.jLabel1.setText(label); 73 this.jLabel1.setDisplayedMnemonic(mnemonic); 74 this.roots.getAccessibleContext().setAccessibleDescription(accessibleDesc); 75 this.roots.setCellRenderer(new Renderer ()); 76 this.roots.setModel (new DefaultListModel ()); 77 this.roots.addListSelectionListener(new ListSelectionListener () { 78 public void valueChanged(ListSelectionEvent e) { 79 if (!e.getValueIsAdjusting()) { 80 removeButton.setEnabled(roots.getSelectedIndices().length != 0); 81 } 82 } 83 }); 84 this.addButton.getAccessibleContext().setAccessibleDescription(addButtonAccessibleDesc); 85 this.addButton.setMnemonic (addButtonMnemonic); 86 this.removeButton.getAccessibleContext().setAccessibleDescription(removeButtonAccessibleDesc); 87 this.removeButton.setMnemonic (removeButtonMnemonic); 88 this.removeButton.setEnabled(false); 89 } 90 91 public void setProjectFolder (File projectFolder) { 92 this.projectFolder = projectFolder; 93 } 94 95 public void setRelatedFolderList (FolderList relatedFolderList) { 96 this.relatedFolderList = relatedFolderList; 97 } 98 99 public File [] getFiles () { 100 Object [] files = ((DefaultListModel )this.roots.getModel()).toArray(); 101 File [] result = new File [files.length]; 102 System.arraycopy(files, 0, result, 0, files.length); 103 return result; 104 } 105 106 public void setFiles (File [] files) { 107 DefaultListModel model = ((DefaultListModel )this.roots.getModel()); 108 model.clear(); 109 for (int i=0; i<files.length; i++) { 110 model.addElement (files[i]); 111 } 112 if (files.length>0) { 113 this.roots.setSelectedIndex(0); 114 } 115 } 116 117 public void setLastUsedDir (File lastUsedDir) { 118 if (this.lastUsedFolder == null ? lastUsedDir != null : !this.lastUsedFolder.equals(lastUsedDir)) { 119 File oldValue = this.lastUsedFolder; 120 this.lastUsedFolder = lastUsedDir; 121 this.firePropertyChange(PROP_LAST_USED_DIR, oldValue, this.lastUsedFolder); 122 } 123 } 124 125 public File getLastUsedDir () { 126 return this.lastUsedFolder; 127 } 128 129 134 private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; 136 137 jLabel1 = new javax.swing.JLabel (); 138 jScrollPane1 = new javax.swing.JScrollPane (); 139 roots = new javax.swing.JList (); 140 addButton = new javax.swing.JButton (); 141 removeButton = new javax.swing.JButton (); 142 143 setLayout(new java.awt.GridBagLayout ()); 144 145 jLabel1.setLabelFor(roots); 146 jLabel1.setText("jLabel1"); 147 gridBagConstraints = new java.awt.GridBagConstraints (); 148 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 149 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 150 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 151 gridBagConstraints.weightx = 1.0; 152 gridBagConstraints.insets = new java.awt.Insets (0, 0, 6, 0); 153 add(jLabel1, gridBagConstraints); 154 155 jScrollPane1.setViewportView(roots); 156 157 gridBagConstraints = new java.awt.GridBagConstraints (); 158 gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; 159 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 160 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 161 gridBagConstraints.weightx = 1.0; 162 gridBagConstraints.weighty = 1.0; 163 gridBagConstraints.insets = new java.awt.Insets (0, 0, 0, 12); 164 add(jScrollPane1, gridBagConstraints); 165 166 addButton.setText(java.util.ResourceBundle.getBundle("org/netbeans/modules/java/j2seproject/ui/wizards/Bundle").getString("CTL_AddFolder")); 167 addButton.addActionListener(new java.awt.event.ActionListener () { 168 public void actionPerformed(java.awt.event.ActionEvent evt) { 169 addButtonActionPerformed(evt); 170 } 171 }); 172 173 gridBagConstraints = new java.awt.GridBagConstraints (); 174 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 175 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 176 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 177 add(addButton, gridBagConstraints); 178 179 removeButton.setText(java.util.ResourceBundle.getBundle("org/netbeans/modules/java/j2seproject/ui/wizards/Bundle").getString("CTL_RemoveFolder")); 180 removeButton.addActionListener(new java.awt.event.ActionListener () { 181 public void actionPerformed(java.awt.event.ActionEvent evt) { 182 removeButtonActionPerformed(evt); 183 } 184 }); 185 186 gridBagConstraints = new java.awt.GridBagConstraints (); 187 gridBagConstraints.gridx = 1; 188 gridBagConstraints.gridy = 2; 189 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 190 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 191 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 192 gridBagConstraints.insets = new java.awt.Insets (12, 0, 0, 0); 193 add(removeButton, gridBagConstraints); 194 195 } 197 private void removeButtonActionPerformed(java.awt.event.ActionEvent evt) { Object [] selection = this.roots.getSelectedValues (); 199 for (int i=0; i<selection.length; i++) { 200 ((DefaultListModel )this.roots.getModel()).removeElement (selection[i]); 201 } 202 this.firePropertyChange(PROP_FILES, null, null); 203 } 205 private void addButtonActionPerformed(java.awt.event.ActionEvent evt) { JFileChooser chooser = new JFileChooser (); 207 chooser.setDialogTitle(this.fcMessage); 208 chooser.setFileSelectionMode (JFileChooser.DIRECTORIES_ONLY); 209 chooser.setMultiSelectionEnabled(true); 210 File curDir = null; 211 if (this.lastUsedFolder != null && this.lastUsedFolder.isDirectory()) { 212 curDir = this.lastUsedFolder; 213 } 214 else if (this.projectFolder != null && this.projectFolder.isDirectory()) { 215 curDir = this.projectFolder; 216 } 217 FileUtil.preventFileChooserSymlinkTraversal(chooser, curDir); 218 if (chooser.showOpenDialog(this)== JFileChooser.APPROVE_OPTION) { 219 File [] files = chooser.getSelectedFiles(); 220 int[] indecesToSelect = new int[files.length]; 221 DefaultListModel model = (DefaultListModel )this.roots.getModel(); 222 Set invalidRoots = new HashSet (); 223 File [] relatedFolders = this.relatedFolderList == null ? 224 new File [0] : this.relatedFolderList.getFiles(); 225 for (int i=0, index=model.size(); i<files.length; i++, index++) { 226 File normalizedFile = FileUtil.normalizeFile(files[i]); 227 if (!isValidRoot(normalizedFile, relatedFolders, this.projectFolder)) { 228 invalidRoots.add (normalizedFile); 229 } 230 else { 231 int pos = model.indexOf (normalizedFile); 232 if (pos == -1) { 233 model.addElement (normalizedFile); 234 indecesToSelect[i] = index; 235 } 236 else { 237 indecesToSelect[i] = pos; 238 } 239 } 240 } 241 this.roots.setSelectedIndices(indecesToSelect); 242 this.firePropertyChange(PROP_FILES, null, null); 243 File cd = chooser.getCurrentDirectory(); 244 if (cd != null) { 245 this.setLastUsedDir(FileUtil.normalizeFile(cd)); 246 } 247 if (invalidRoots.size()>0) { 248 J2SESourceRootsUi.showIllegalRootsDialog(invalidRoots); 249 } 250 } 251 } 253 254 static boolean isValidRoot (File file, File [] relatedRoots, File projectFolder) { 255 Project p; 256 if ((p = FileOwnerQuery.getOwner(file.toURI()))!=null 257 && !file.getAbsolutePath().startsWith(projectFolder.getAbsolutePath()+File.separatorChar)) { 258 final Sources sources = (Sources) p.getLookup().lookup(Sources.class); 259 if (sources == null) { 260 return false; 261 } 262 final SourceGroup[] sourceGroups = sources.getSourceGroups(Sources.TYPE_GENERIC); 263 final SourceGroup[] javaGroups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); 264 final SourceGroup[] groups = new SourceGroup [sourceGroups.length + javaGroups.length]; 265 System.arraycopy(sourceGroups,0,groups,0,sourceGroups.length); 266 System.arraycopy(javaGroups,0,groups,sourceGroups.length,javaGroups.length); 267 final FileObject projectDirectory = p.getProjectDirectory(); 268 final FileObject fileObject = FileUtil.toFileObject(file); 269 if (projectDirectory == null || fileObject == null) { 270 return false; 271 } 272 for (int i = 0; i< groups.length; i++) { 273 final FileObject sgRoot = groups[i].getRootFolder(); 274 if (fileObject.equals(sgRoot)) { 275 return false; 276 } 277 if (!projectDirectory.equals(sgRoot) && FileUtil.isParentOf(sgRoot, fileObject)) { 278 return false; 279 } 280 } 281 return true; 282 } 283 else if (contains (file, relatedRoots)) { 284 return false; 285 } 286 return true; 287 } 288 289 private static boolean contains (File folder, File [] roots) { 290 String path = folder.getAbsolutePath (); 291 for (int i=0; i<roots.length; i++) { 292 String rootPath = roots[i].getAbsolutePath(); 293 if (rootPath.equals (path) || path.startsWith (rootPath + File.separatorChar)) { 294 return true; 295 } 296 } 297 return false; 298 } 299 300 private static class Renderer extends DefaultListCellRenderer { 301 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 302 File f = (File ) value; 303 Project p = FileOwnerQuery.getOwner(f.toURI()); 304 String message = f.getAbsolutePath(); 305 Component result = super.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus); 306 return result; 307 } 308 309 } 310 311 private javax.swing.JButton addButton; 313 private javax.swing.JLabel jLabel1; 314 private javax.swing.JScrollPane jScrollPane1; 315 private javax.swing.JButton removeButton; 316 private javax.swing.JList roots; 317 319 } 320 | Popular Tags |