1 19 20 package org.netbeans.modules.java.j2seplatform.libraries; 21 22 import java.awt.Color ; 23 import java.awt.Component ; 24 import java.beans.Customizer ; 25 import java.io.File ; 26 import java.net.URL ; 27 import java.net.MalformedURLException ; 28 import java.util.Collection ; 29 import java.util.Arrays ; 30 import javax.swing.DefaultListCellRenderer ; 31 import javax.swing.JButton ; 32 import javax.swing.JComponent ; 33 import javax.swing.JFileChooser ; 34 import javax.swing.JList ; 35 import javax.swing.event.ListSelectionEvent ; 36 import javax.swing.event.ListSelectionListener ; 37 import javax.swing.filechooser.FileFilter ; 38 import org.openide.DialogDisplayer; 39 import org.openide.ErrorManager; 40 import org.openide.NotifyDescriptor; 41 import org.openide.NotifyDescriptor.Message; 42 import org.openide.filesystems.FileObject; 43 import org.openide.filesystems.FileUtil; 44 import org.openide.filesystems.URLMapper; 45 import org.openide.util.NbBundle; 46 import org.netbeans.spi.project.libraries.LibraryImplementation; 47 48 52 public class J2SEVolumeCustomizer extends javax.swing.JPanel implements Customizer { 53 54 private String volumeType; 55 private LibraryImplementation impl; 56 private VolumeContentModel model; 57 58 59 J2SEVolumeCustomizer (String volumeType) { 60 this.volumeType = volumeType; 61 initComponents(); 62 postInitComponents (); 63 this.setName (NbBundle.getMessage(J2SEVolumeCustomizer.class,"TXT_"+volumeType)); 64 } 65 66 67 public void addNotify() { 68 super.addNotify(); 69 this.addButton.requestFocus(); 70 } 71 72 public void setEnabled(boolean enabled) { 73 super.setEnabled(enabled); 74 this.addButton.setEnabled(enabled); 75 if (this.addURLButton != null) { 76 this.addURLButton.setEnabled(enabled); 77 } 78 int[] indices = content.getSelectedIndices(); 79 this.removeButton.setEnabled(enabled && indices.length > 0); 80 this.downButton.setEnabled(enabled && indices.length > 0 && indices[indices.length-1]<model.getSize()-1); 81 this.upButton.setEnabled(enabled && indices.length>0 && indices[0]>0); 82 } 83 84 85 private void postInitComponents () { 86 this.content.setCellRenderer(new ContentRenderer()); 87 this.upButton.setEnabled (false); 88 this.downButton.setEnabled (false); 89 this.removeButton.setEnabled (false); 90 if (this.volumeType.equals(J2SELibraryTypeProvider.VOLUME_TYPE_CLASSPATH)) { 91 this.addButton.setText (NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_AddClassPath")); 92 this.addButton.setMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_AddClassPath").charAt(0)); 93 this.message.setText(NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_ContentClassPath")); 94 this.message.setDisplayedMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_ContentClassPath").charAt(0)); 95 this.addButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(J2SEVolumeCustomizer.class,"AD_AddClassPath")); 96 this.message.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(J2SEVolumeCustomizer.class,"AD_ContentClassPath")); 97 } 98 else if (this.volumeType.equals(J2SELibraryTypeProvider.VOLUME_TYPE_JAVADOC)) { 99 this.addButton.setText(NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_AddJavadoc")); 100 this.addButton.setMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_AddJavadoc").charAt(0)); 101 this.message.setText(NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_ContentJavadoc")); 102 this.message.setDisplayedMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_ContentJavadoc").charAt(0)); 103 this.addButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(J2SEVolumeCustomizer.class,"AD_AddJavadoc")); 104 this.message.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(J2SEVolumeCustomizer.class,"AD_ContentJavadoc")); 105 } 124 else if (this.volumeType.equals(J2SELibraryTypeProvider.VOLUME_TYPE_SRC)) { 125 this.addButton.setText (NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_AddSources")); 126 this.addButton.setMnemonic (NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_AddSources").charAt(0)); 127 this.message.setText(NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_ContentSources")); 128 this.message.setDisplayedMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_ContentSources").charAt(0)); 129 this.addButton.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(J2SEVolumeCustomizer.class,"AD_AddSources")); 130 this.message.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(J2SEVolumeCustomizer.class,"AD_ContentSources")); 131 } 132 this.content.addListSelectionListener(new ListSelectionListener () { 133 public void valueChanged(ListSelectionEvent e) { 134 if (e.getValueIsAdjusting()) 135 return; 136 int[] indices = content.getSelectedIndices(); 137 removeButton.setEnabled(indices.length > 0); 138 downButton.setEnabled(indices.length > 0 && indices[indices.length-1]<model.getSize()-1); 139 upButton.setEnabled(indices.length>0 && indices[0]>0); 140 } 141 }); 142 } 143 144 149 private void initComponents() { 151 java.awt.GridBagConstraints gridBagConstraints; 152 153 message = new javax.swing.JLabel (); 154 jScrollPane1 = new javax.swing.JScrollPane (); 155 content = new javax.swing.JList (); 156 addButton = new javax.swing.JButton (); 157 removeButton = new javax.swing.JButton (); 158 upButton = new javax.swing.JButton (); 159 downButton = new javax.swing.JButton (); 160 161 setLayout(new java.awt.GridBagLayout ()); 162 163 getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("AD_J2SEVolumeCustomizer")); 164 message.setLabelFor(content); 165 org.openide.awt.Mnemonics.setLocalizedText(message, org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("CTL_ContentMessage")); 166 gridBagConstraints = new java.awt.GridBagConstraints (); 167 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 168 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 169 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 170 gridBagConstraints.weightx = 1.0; 171 gridBagConstraints.insets = new java.awt.Insets (6, 6, 2, 6); 172 add(message, gridBagConstraints); 173 174 jScrollPane1.setViewportView(content); 175 176 gridBagConstraints = new java.awt.GridBagConstraints (); 177 gridBagConstraints.gridx = 0; 178 gridBagConstraints.gridy = 1; 179 gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER; 180 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 181 gridBagConstraints.weightx = 1.0; 182 gridBagConstraints.weighty = 1.0; 183 gridBagConstraints.insets = new java.awt.Insets (0, 6, 6, 6); 184 add(jScrollPane1, gridBagConstraints); 185 186 org.openide.awt.Mnemonics.setLocalizedText(addButton, org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("CTL_AddContent")); 187 addButton.addActionListener(new java.awt.event.ActionListener () { 188 public void actionPerformed(java.awt.event.ActionEvent evt) { 189 addResource(evt); 190 } 191 }); 192 193 gridBagConstraints = new java.awt.GridBagConstraints (); 194 gridBagConstraints.gridx = 1; 195 gridBagConstraints.gridy = 1; 196 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 197 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 198 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 199 gridBagConstraints.insets = new java.awt.Insets (0, 6, 6, 6); 200 add(addButton, gridBagConstraints); 201 addButton.getAccessibleContext().setAccessibleDescription(null); 202 203 org.openide.awt.Mnemonics.setLocalizedText(removeButton, org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("CTL_RemoveContent")); 204 removeButton.addActionListener(new java.awt.event.ActionListener () { 205 public void actionPerformed(java.awt.event.ActionEvent evt) { 206 removeResource(evt); 207 } 208 }); 209 210 gridBagConstraints = new java.awt.GridBagConstraints (); 211 gridBagConstraints.gridx = 1; 212 gridBagConstraints.gridy = 3; 213 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 214 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 215 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 216 gridBagConstraints.insets = new java.awt.Insets (5, 6, 6, 6); 217 add(removeButton, gridBagConstraints); 218 removeButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("AD_RemoveContent")); 219 220 org.openide.awt.Mnemonics.setLocalizedText(upButton, org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("CTL_UpContent")); 221 upButton.addActionListener(new java.awt.event.ActionListener () { 222 public void actionPerformed(java.awt.event.ActionEvent evt) { 223 upResource(evt); 224 } 225 }); 226 227 gridBagConstraints = new java.awt.GridBagConstraints (); 228 gridBagConstraints.gridx = 1; 229 gridBagConstraints.gridy = 4; 230 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 231 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 232 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 233 gridBagConstraints.insets = new java.awt.Insets (5, 6, 0, 6); 234 add(upButton, gridBagConstraints); 235 upButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("AD_UpContent")); 236 237 org.openide.awt.Mnemonics.setLocalizedText(downButton, org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("CTL_DownContent")); 238 downButton.addActionListener(new java.awt.event.ActionListener () { 239 public void actionPerformed(java.awt.event.ActionEvent evt) { 240 downResource(evt); 241 } 242 }); 243 244 gridBagConstraints = new java.awt.GridBagConstraints (); 245 gridBagConstraints.gridx = 1; 246 gridBagConstraints.gridy = 5; 247 gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; 248 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 249 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; 250 gridBagConstraints.insets = new java.awt.Insets (5, 6, 6, 6); 251 add(downButton, gridBagConstraints); 252 downButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getBundle(J2SEVolumeCustomizer.class).getString("AD_DownContent")); 253 254 } 255 257 private void downResource(java.awt.event.ActionEvent evt) { int[] indices = this.content.getSelectedIndices(); 259 if (indices.length == 0 || indices[0] < 0 || indices[indices.length-1]>=model.getSize()-1) { 260 return; 261 } 262 this.model.moveDown(indices); 263 for (int i=0; i< indices.length; i++) { 264 indices[i] = indices[i] + 1; 265 } 266 this.content.setSelectedIndices (indices); 267 } 269 private void upResource(java.awt.event.ActionEvent evt) { int[] indices = this.content.getSelectedIndices(); 271 if (indices.length == 0 || indices[0] <= 0) { 272 return; 273 } 274 this.model.moveUp(indices); 275 for (int i=0; i< indices.length; i++) { 276 indices[i] = indices[i] - 1; 277 } 278 this.content.setSelectedIndices(indices); 279 } 281 private void removeResource(java.awt.event.ActionEvent evt) { int[] indices =this.content.getSelectedIndices(); 283 if (indices.length == 0) { 284 return; 285 } 286 this.model.removeResources(indices); 287 if (indices[indices.length-1]-indices.length+1 < this.model.getSize()) { 288 this.content.setSelectedIndex(indices[indices.length-1]-indices.length+1); 289 } 290 else if (indices[0] >= 1) { 291 this.content.setSelectedIndex (indices[0]-1); 292 } 293 } 295 private void addResource(java.awt.event.ActionEvent evt) { JFileChooser chooser = new JFileChooser (); 298 FileUtil.preventFileChooserSymlinkTraversal(chooser, null); 299 chooser.setAcceptAllFileFilterUsed(false); 300 if (this.volumeType.equals(J2SELibraryTypeProvider.VOLUME_TYPE_CLASSPATH)) { 301 chooser.setMultiSelectionEnabled (true); 302 chooser.setDialogTitle(NbBundle.getMessage(J2SEVolumeCustomizer.class,"TXT_OpenClasses")); 303 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 304 chooser.setFileFilter (new SimpleFileFilter(NbBundle.getMessage( 305 J2SEVolumeCustomizer.class,"TXT_Classpath"),new String [] {"ZIP","JAR"})); chooser.setApproveButtonText(NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_SelectCP")); 307 chooser.setApproveButtonMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_SelectCP").charAt(0)); 308 } 309 else if (this.volumeType.equals(J2SELibraryTypeProvider.VOLUME_TYPE_JAVADOC)) { 310 chooser.setDialogTitle(NbBundle.getMessage(J2SEVolumeCustomizer.class,"TXT_OpenJavadoc")); 311 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 312 chooser.setFileFilter (new SimpleFileFilter(NbBundle.getMessage( 313 J2SEVolumeCustomizer.class,"TXT_Javadoc"),new String [] {"ZIP","JAR"})); chooser.setApproveButtonText(NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_SelectJD")); 315 chooser.setApproveButtonMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_SelectJD").charAt(0)); 316 } 317 else if (this.volumeType.equals(J2SELibraryTypeProvider.VOLUME_TYPE_SRC)) { 318 chooser.setMultiSelectionEnabled (true); 319 chooser.setDialogTitle(NbBundle.getMessage(J2SEVolumeCustomizer.class,"TXT_OpenSources")); 320 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 321 chooser.setFileFilter (new SimpleFileFilter(NbBundle.getMessage( 322 J2SEVolumeCustomizer.class,"TXT_Sources"),new String [] {"ZIP","JAR"})); chooser.setApproveButtonText(NbBundle.getMessage(J2SEVolumeCustomizer.class,"CTL_SelectSRC")); 324 chooser.setApproveButtonMnemonic(NbBundle.getMessage(J2SEVolumeCustomizer.class,"MNE_SelectSRC").charAt(0)); 325 } 326 if (lastFolder != null) { 327 chooser.setCurrentDirectory (lastFolder); 328 } 329 if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { 330 try { 331 lastFolder = chooser.getCurrentDirectory(); 332 if (chooser.isMultiSelectionEnabled()) { 333 addFiles (chooser.getSelectedFiles()); 334 } 335 else { 336 final File selectedFile = chooser.getSelectedFile(); 337 addFiles (new File [] {selectedFile}); 338 } 339 } catch (MalformedURLException mue) { 340 ErrorManager.getDefault().notify(mue); 341 } 342 } 343 } 345 346 366 367 private void addFiles (File [] files) throws MalformedURLException { 368 int firstIndex = this.model.getSize(); 369 for (int i = 0; i < files.length; i++) { 370 File f = files[i]; 371 if (!f.exists()) { 375 File parent = f.getParentFile(); 376 if (parent != null && f.getName().equals(parent.getName()) && parent.exists()) { 377 f = parent; 378 } 379 } 380 URL url = f.toURI().toURL(); 381 if (FileUtil.isArchiveFile(url)) { 382 url = FileUtil.getArchiveRoot(url); 383 } 384 else if (!url.toExternalForm().endsWith("/")){ 385 try { 386 url = new URL (url.toExternalForm()+"/"); 387 } catch (MalformedURLException mue) { 388 ErrorManager.getDefault().notify(mue); 389 } 390 } 391 if (this.volumeType.equals(J2SELibraryTypeProvider.VOLUME_TYPE_JAVADOC) 392 && !JavadocForBinaryQueryLibraryImpl.isValidLibraryJavadocRoot (url)) { 393 DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message( 394 NbBundle.getMessage(J2SEVolumeCustomizer.class,"TXT_InvalidJavadocRoot", f.getPath()), 395 NotifyDescriptor.ERROR_MESSAGE)); 396 continue; 397 } 398 this.model.addResource(url); 399 } 400 int lastIndex = this.model.getSize()-1; 401 if (firstIndex<=lastIndex) { 402 int[] toSelect = new int[lastIndex-firstIndex+1]; 403 for (int i = 0; i < toSelect.length; i++) { 404 toSelect[i] = firstIndex+i; 405 } 406 this.content.setSelectedIndices(toSelect); 407 } 408 } 409 410 public void setObject(Object bean) { 411 if (bean instanceof LibraryImplementation) { 412 this.impl = (LibraryImplementation) bean; 413 this.model = new VolumeContentModel(this.impl,this.volumeType); 414 this.content.setModel(model); 415 if (this.model.getSize()>0) { 416 this.content.setSelectedIndex(0); 417 } 418 } 419 else { 420 throw new IllegalArgumentException (); 421 } 422 } 423 424 425 private static class SimpleFileFilter extends FileFilter { 426 427 private String description; 428 private Collection extensions; 429 430 431 public SimpleFileFilter(String description, String [] extensions) { 432 this.description = description; 433 this.extensions = Arrays.asList(extensions); 434 } 435 436 public boolean accept(File f) { 437 if (f.isDirectory()) 438 return true; 439 String name = f.getName(); 440 int index = name.lastIndexOf('.'); if (index <= 0 || index==name.length()-1) 442 return false; 443 String extension = name.substring(index+1).toUpperCase(); 444 return this.extensions.contains(extension); 445 } 446 447 public String getDescription() { 448 return this.description; 449 } 450 } 451 452 453 private static File lastFolder = null; 454 455 456 private javax.swing.JButton addButton; 458 private javax.swing.JList content; 459 private javax.swing.JButton downButton; 460 private javax.swing.JScrollPane jScrollPane1; 461 private javax.swing.JLabel message; 462 private javax.swing.JButton removeButton; 463 private javax.swing.JButton upButton; 464 private JButton addURLButton; 466 467 private static class ContentRenderer extends DefaultListCellRenderer { 468 469 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 470 String displayName = null; 471 Color color = null; 472 String toolTip = null; 473 474 if (value instanceof URL ) { 475 URL url = (URL ) value; 476 if ("jar".equals(url.getProtocol())) { url = FileUtil.getArchiveFile (url); 478 } 479 FileObject fo = URLMapper.findFileObject (url); 480 if (fo == null) { 481 displayName = url.toExternalForm(); 482 color = new Color (164,0,0); 483 toolTip = NbBundle.getMessage (J2SEVolumeCustomizer.class,"TXT_BrokenFile"); 484 } 485 else { 486 displayName = FileUtil.getFileDisplayName(fo); 487 } 488 } 489 Component c = super.getListCellRendererComponent(list, displayName, index, isSelected, cellHasFocus); 490 if (c instanceof JComponent ) { 491 if (color != null) { 492 ((JComponent )c).setForeground (color); 493 } 494 if (toolTip != null) { 495 ((JComponent )c).setToolTipText (toolTip); 496 } 497 } 498 return c; 499 } 500 501 } 502 503 } 504 | Popular Tags |