| 1 19 20 package org.netbeans.modules.j2ee.ejbjarproject.ui.customizer; 21 22 import java.awt.*; 23 import java.awt.event.ActionEvent ; 24 import java.awt.event.ActionListener ; 25 import java.io.File ; 26 import java.net.URI ; 27 import java.net.URL ; 28 import java.util.ArrayList ; 29 import java.util.Iterator ; 30 import java.util.HashSet ; 31 import java.util.Set ; 32 import java.util.Vector ; 33 import java.text.MessageFormat ; 34 import javax.swing.*; 35 import javax.swing.event.ListSelectionEvent ; 36 import javax.swing.event.ListSelectionListener ; 37 import javax.swing.event.CellEditorListener ; 38 import javax.swing.event.ChangeEvent ; 39 import javax.swing.table.DefaultTableCellRenderer ; 40 import javax.swing.table.DefaultTableModel ; 41 import org.netbeans.api.project.ProjectUtils; 42 import org.netbeans.modules.j2ee.ejbjarproject.EjbJarProject; 43 import org.netbeans.modules.j2ee.ejbjarproject.ui.FoldersListSettings; 44 import org.netbeans.api.project.FileOwnerQuery; 45 import org.netbeans.api.project.Project; 46 import org.netbeans.api.project.ProjectInformation; 47 import org.netbeans.modules.j2ee.ejbjarproject.SourceRoots; 48 import org.openide.DialogDisplayer; 49 import org.openide.DialogDescriptor; 50 import org.openide.filesystems.FileUtil; 51 import org.openide.util.NbBundle; 52 import org.openide.util.HelpCtx; 53 54 58 public final class EjbJarSourceRootsUi { 59 60 public static DefaultTableModel createModel( SourceRoots roots ) { 61 62 String [] rootLabels = roots.getRootNames(); 63 String [] rootProps = roots.getRootProperties(); 64 URL [] rootURLs = roots.getRootURLs(); 65 Object [][] data = new Object [rootURLs.length] [2]; 66 for (int i=0; i< rootURLs.length; i++) { 67 data[i][0] = new File (URI.create (rootURLs[i].toExternalForm())); 68 data[i][1] = roots.getRootDisplayName(rootLabels[i], rootProps[i]); 69 } 70 return new SourceRootsModel(data); 71 72 } 73 74 public static EditMediator registerEditMediator( EjbJarProject master, 75 SourceRoots sourceRoots, 76 JTable rootsList, 77 JButton addFolderButton, 78 JButton removeButton, 79 JButton upButton, 80 JButton downButton) { 81 82 EditMediator em = new EditMediator( master, 83 sourceRoots, 84 rootsList, 85 addFolderButton, 86 removeButton, 87 upButton, 88 downButton); 89 90 addFolderButton.addActionListener( em ); 93 removeButton.addActionListener( em ); 94 upButton.addActionListener( em ); 95 downButton.addActionListener( em ); 96 rootsList.getSelectionModel().addListSelectionListener( em ); 98 DefaultCellEditor editor = new DefaultCellEditor(new JTextField()); 99 editor.addCellEditorListener (em); 100 rootsList.setDefaultRenderer( File .class, new FileRenderer (FileUtil.toFile(master.getProjectDirectory()))); 101 rootsList.setDefaultEditor(String .class, editor); 102 em.valueChanged( null ); 104 105 DefaultTableModel model = (DefaultTableModel )rootsList.getModel(); 106 String [] columnNames = new String [2]; 107 columnNames[0] = NbBundle.getMessage( EjbJarSourceRootsUi.class,"CTL_PackageFolders"); 108 columnNames[1] = NbBundle.getMessage( EjbJarSourceRootsUi.class,"CTL_PackageLabels"); 109 model.setColumnIdentifiers(columnNames); 110 rootsList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 111 112 return em; 113 } 114 115 119 public static void showIllegalRootsDialog (Set roots) { 120 JButton closeOption = new JButton (NbBundle.getMessage(EjbJarSourceRootsUi.class,"CTL_EjbJarSourceRootsUi_Close")); 121 closeOption.getAccessibleContext ().setAccessibleDescription (NbBundle.getMessage(EjbJarSourceRootsUi.class,"AD_EjbJarSourceRootsUi_Close")); 122 JPanel warning = new WarningDlg (roots); 123 String message = NbBundle.getMessage(EjbJarSourceRootsUi.class,"MSG_InvalidRoot"); 124 JOptionPane optionPane = new JOptionPane (new Object [] {message, warning}, 125 JOptionPane.WARNING_MESSAGE, 126 0, 127 null, 128 new Object [0], 129 null); 130 optionPane.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(EjbJarSourceRootsUi.class,"AD_InvalidRootDlg")); 131 DialogDescriptor dd = new DialogDescriptor (optionPane, 132 NbBundle.getMessage(EjbJarSourceRootsUi.class,"TITLE_InvalidRoot"), 133 true, 134 new Object [] { 135 closeOption, 136 }, 137 closeOption, 138 DialogDescriptor.DEFAULT_ALIGN, 139 null, 140 null); 141 DialogDisplayer.getDefault().notify(dd); 142 } 143 144 146 public static class EditMediator implements ActionListener , ListSelectionListener , CellEditorListener { 147 148 149 final JTable rootsList; 150 final JButton addFolderButton; 151 final JButton removeButton; 152 final JButton upButton; 153 final JButton downButton; 154 private final Project project; 155 private final SourceRoots sourceRoots; 156 private final Set ownedFolders; 157 private DefaultTableModel rootsModel; 158 private EditMediator relatedEditMediator; 159 private File lastUsedDir; 161 public EditMediator( EjbJarProject master, 162 SourceRoots sourceRoots, 163 JTable rootsList, 164 JButton addFolderButton, 165 JButton removeButton, 166 JButton upButton, 167 JButton downButton) { 168 169 if ( !( rootsList.getModel() instanceof DefaultTableModel ) ) { 170 throw new IllegalArgumentException ( "Jtable's model has to be of class DefaultTableModel" ); } 172 173 this.rootsList = rootsList; 174 this.addFolderButton = addFolderButton; 175 this.removeButton = removeButton; 176 this.upButton = upButton; 177 this.downButton = downButton; 178 this.ownedFolders = new HashSet (); 179 180 this.project = master; 181 this.sourceRoots = sourceRoots; 182 183 this.ownedFolders.clear(); 184 this.rootsModel = (DefaultTableModel )rootsList.getModel(); 185 Vector data = rootsModel.getDataVector(); 186 for (Iterator it = data.iterator(); it.hasNext();) { 187 Vector row = (Vector ) it.next (); 188 File f = (File ) row.elementAt(0); 189 this.ownedFolders.add (f); 190 } 191 } 192 193 public void setRelatedEditMediator(EditMediator rem) { 194 this.relatedEditMediator = rem; 195 } 196 197 199 201 public void actionPerformed( ActionEvent e ) { 202 203 Object source = e.getSource(); 204 205 if ( source == addFolderButton ) { 206 207 JFileChooser chooser = new JFileChooser(); 209 FileUtil.preventFileChooserSymlinkTraversal(chooser, null); 210 chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY ); 211 chooser.setMultiSelectionEnabled( true ); 212 213 if (sourceRoots.isTest()) 214 chooser.setDialogTitle( NbBundle.getMessage( EjbJarSourceRootsUi.class, "LBL_TestFolder_DialogTitle" )); else 216 chooser.setDialogTitle( NbBundle.getMessage( EjbJarSourceRootsUi.class, "LBL_SourceFolder_DialogTitle" )); 218 File curDir = this.lastUsedDir; 219 if (curDir == null) { 220 curDir = FileUtil.toFile(this.project.getProjectDirectory()); 221 } 222 if (curDir != null) { 223 chooser.setCurrentDirectory (curDir); 224 } 225 int option = chooser.showOpenDialog( SwingUtilities.getWindowAncestor( addFolderButton ) ); 227 if ( option == JFileChooser.APPROVE_OPTION ) { 228 curDir = chooser.getCurrentDirectory(); 229 if (curDir != null) { 230 this.lastUsedDir = curDir; 231 if (this.relatedEditMediator != null) { 232 this.relatedEditMediator.lastUsedDir = curDir; 233 } 234 } 235 File files[] = chooser.getSelectedFiles(); 236 addFolders( files ); 237 } 238 } 239 else if ( source == removeButton ) { 240 removeElements(); 241 } 242 else if ( source == upButton ) { 243 moveUp(); 244 } 245 else if ( source == downButton ) { 246 moveDown(); 247 } 248 } 249 250 252 254 public void valueChanged( ListSelectionEvent e ) { 255 256 int[] si = rootsList.getSelectedRows(); 257 258 260 262 264 boolean edit = si != null && si.length > 0; 266 267 boolean remove = si != null && si.length > 0; 269 271 boolean up = si != null && si.length > 0 && si[0] != 0; 274 275 boolean down = si != null && si.length > 0 && si[si.length-1] !=rootsList.getRowCount() - 1; 278 279 removeButton.setEnabled( remove ); 280 upButton.setEnabled( up ); 281 downButton.setEnabled( down ); 282 283 285 } 286 287 public void editingCanceled(ChangeEvent e) { 288 289 } 290 291 public void editingStopped(ChangeEvent e) { 292 } 294 295 private void addFolders( File files[] ) { 296 int[] si = rootsList.getSelectedRows(); 297 int lastIndex = si == null || si.length == 0 ? -1 : si[si.length - 1]; 298 ListSelectionModel selectionModel = this.rootsList.getSelectionModel(); 299 selectionModel.clearSelection(); 300 Set rootsFromOtherProjects = new HashSet (); 301 Set rootsFromRelatedSourceRoots = new HashSet (); 302 for( int i = 0; i < files.length; i++ ) { 303 File normalizedFile = FileUtil.normalizeFile(files[i]); 304 Project p; 305 if (ownedFolders.contains(normalizedFile)) { 306 Vector dataVector = rootsModel.getDataVector(); 307 for (int j=0; j<dataVector.size();j++) { 308 File f = (File )((Vector )dataVector.elementAt(j)).elementAt(0); 310 if (f.equals(normalizedFile)) { 311 selectionModel.addSelectionInterval(j,j); 312 } 313 } 314 } 315 else if (this.relatedEditMediator != null && this.relatedEditMediator.ownedFolders.contains(normalizedFile)) { 316 rootsFromRelatedSourceRoots.add (normalizedFile); 317 } 318 else if ((p=FileOwnerQuery.getOwner(normalizedFile.toURI()))!=null && !p.getProjectDirectory().equals(project.getProjectDirectory())) { 319 rootsFromOtherProjects.add (normalizedFile); 320 } 321 else { 322 int current = lastIndex + 1 + i; 323 rootsModel.insertRow( current, new Object [] {normalizedFile, sourceRoots.createInitialDisplayName(normalizedFile)}); selectionModel.addSelectionInterval(current,current); 325 this.ownedFolders.add (normalizedFile); 326 } 327 } 328 if (rootsFromOtherProjects.size() > 0 || rootsFromRelatedSourceRoots.size() > 0) { 329 rootsFromOtherProjects.addAll(rootsFromRelatedSourceRoots); 330 showIllegalRootsDialog (rootsFromOtherProjects); 331 } 332 } 334 335 private void removeElements() { 336 337 int[] si = rootsList.getSelectedRows(); 338 339 if( si == null || si.length == 0 ) { 340 assert false : "Remove button should be disabled"; } 342 343 for( int i = si.length - 1 ; i >= 0 ; i-- ) { 345 this.ownedFolders.remove(((Vector )rootsModel.getDataVector().elementAt(si[i])).elementAt(0)); 346 rootsModel.removeRow( si[i] ); 347 } 348 349 350 if ( rootsModel.getRowCount() != 0) { 351 int selectedIndex = si[si.length - 1] - si.length + 1; 353 if ( selectedIndex > rootsModel.getRowCount() - 1) { 354 selectedIndex = rootsModel.getRowCount() - 1; 355 } 356 rootsList.setRowSelectionInterval( selectedIndex, selectedIndex ); 357 } 358 359 361 } 362 363 private void moveUp() { 364 365 int[] si = rootsList.getSelectedRows(); 366 367 if( si == null || si.length == 0 ) { 368 assert false : "MoveUp button should be disabled"; } 370 371 ListSelectionModel selectionModel = this.rootsList.getSelectionModel(); 373 selectionModel.clearSelection(); 374 for( int i = 0; i < si.length; i++ ) { 375 Vector item = (Vector ) rootsModel.getDataVector().elementAt(si[i]); 376 int newIndex = si[i]-1; 377 rootsModel.removeRow( si[i] ); 378 rootsModel.insertRow( newIndex, item ); 379 selectionModel.addSelectionInterval(newIndex,newIndex); 380 } 381 } 383 384 private void moveDown() { 385 386 int[] si = rootsList.getSelectedRows(); 387 388 if( si == null || si.length == 0 ) { 389 assert false : "MoveDown button should be disabled"; } 391 392 ListSelectionModel selectionModel = this.rootsList.getSelectionModel(); 394 selectionModel.clearSelection(); 395 for( int i = si.length -1 ; i >= 0 ; i-- ) { 396 Vector item = (Vector ) rootsModel.getDataVector().elementAt(si[i]); 397 int newIndex = si[i] + 1; 398 rootsModel.removeRow( si[i] ); 399 rootsModel.insertRow( newIndex, item ); 400 selectionModel.addSelectionInterval(newIndex,newIndex); 401 } 402 } 404 405 406 } 407 408 private static class SourceRootsModel extends DefaultTableModel { 409 410 public SourceRootsModel (Object [][] data) { 411 super (data,new Object []{"location","label"}); } 413 414 public boolean isCellEditable(int row, int column) { 415 return column == 1; 416 } 417 418 public Class getColumnClass(int columnIndex) { 419 switch (columnIndex) { 420 case 0: 421 return File .class; 422 case 1: 423 return String .class; 424 default: 425 return super.getColumnClass (columnIndex); 426 } 427 } 428 } 429 430 private static class FileRenderer extends DefaultTableCellRenderer { 431 432 private File projectFolder; 433 434 public FileRenderer (File projectFolder) { 435 this.projectFolder = projectFolder; 436 } 437 438 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row, int column) { 439 String displayName; 440 if (value instanceof File ) { 441 File root = (File ) value; 442 String pfPath = projectFolder.getAbsolutePath() + File.separatorChar; 443 String srPath = root.getAbsolutePath(); 444 if (srPath.startsWith(pfPath)) { 445 displayName = srPath.substring(pfPath.length()); 446 } 447 else { 448 displayName = srPath; 449 } 450 } 451 else { 452 displayName = null; 453 } 454 Component c = super.getTableCellRendererComponent(table, displayName, isSelected, hasFocus, row, column); 455 if (c instanceof JComponent) { 456 ((JComponent) c).setToolTipText (displayName); 457 } 458 return c; 459 } 460 } 461 462 private static class WarningDlg extends JPanel { 463 464 public WarningDlg (Set invalidRoots) { 465 this.initGui (invalidRoots); 466 } 467 468 private void initGui (Set invalidRoots) { 469 setLayout( new GridBagLayout ()); 470 JLabel label = new JLabel (); 471 label.setText (NbBundle.getMessage(EjbJarSourceRootsUi.class,"LBL_InvalidRoot")); 472 label.setDisplayedMnemonic(NbBundle.getMessage(EjbJarSourceRootsUi.class,"MNE_InvalidRoot").charAt(0)); 473 GridBagConstraints c = new GridBagConstraints(); 474 c.gridx = GridBagConstraints.RELATIVE; 475 c.gridy = GridBagConstraints.RELATIVE; 476 c.gridwidth = GridBagConstraints.REMAINDER; 477 c.fill = GridBagConstraints.HORIZONTAL; 478 c.anchor = GridBagConstraints.NORTHWEST; 479 c.weightx = 1.0; 480 c.insets = new Insets (12,0,6,0); 481 ((GridBagLayout)this.getLayout()).setConstraints(label,c); 482 this.add (label); 483 JList roots = new JList (invalidRoots.toArray()); 484 roots.setCellRenderer (new InvalidRootRenderer(true)); 485 JScrollPane p = new JScrollPane (roots); 486 c = new GridBagConstraints(); 487 c.gridx = GridBagConstraints.RELATIVE; 488 c.gridy = GridBagConstraints.RELATIVE; 489 c.gridwidth = GridBagConstraints.REMAINDER; 490 c.fill = GridBagConstraints.BOTH; 491 c.anchor = GridBagConstraints.NORTHWEST; 492 c.weightx = c.weighty = 1.0; 493 c.insets = new Insets (0,0,12,0); 494 ((GridBagLayout)this.getLayout()).setConstraints(p,c); 495 this.add (p); 496 label.setLabelFor(roots); 497 roots.getAccessibleContext().setAccessibleDescription (NbBundle.getMessage(EjbJarSourceRootsUi.class,"AD_InvalidRoot")); 498 JLabel label2 = new JLabel (); 499 label2.setText (NbBundle.getMessage(EjbJarSourceRootsUi.class,"MSG_InvalidRoot2")); 500 c = new GridBagConstraints(); 501 c.gridx = GridBagConstraints.RELATIVE; 502 c.gridy = GridBagConstraints.RELATIVE; 503 c.gridwidth = GridBagConstraints.REMAINDER; 504 c.fill = GridBagConstraints.HORIZONTAL; 505 c.anchor = GridBagConstraints.NORTHWEST; 506 c.weightx = 1.0; 507 c.insets = new Insets (0,0,0,0); 508 ((GridBagLayout)this.getLayout()).setConstraints(label2,c); 509 this.add (label2); 510 } 511 512 private static class InvalidRootRenderer extends DefaultListCellRenderer { 513 514 private boolean projectConflict; 515 516 public InvalidRootRenderer (boolean projectConflict) { 517 this.projectConflict = projectConflict; 518 } 519 520 public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 521 File f = (File ) value; 522 String message = f.getAbsolutePath(); 523 if (projectConflict) { 524 Project p = FileOwnerQuery.getOwner(f.toURI()); 525 if (p!=null) { 526 ProjectInformation pi = ProjectUtils.getInformation(p); 527 String projectName = pi.getDisplayName(); 528 message = MessageFormat.format (NbBundle.getMessage(EjbJarSourceRootsUi.class,"TXT_RootOwnedByProject"), new Object [] { 529 message, 530 projectName}); 531 } 532 } 533 return super.getListCellRendererComponent(list, message, index, isSelected, cellHasFocus); 534 } 535 } 536 } 537 538 } 539 | Popular Tags |