1 19 20 package org.netbeans.modules.projectimport.eclipse.wizard; 21 22 import java.awt.Component ; 23 import java.awt.event.ActionEvent ; 24 import java.awt.event.ActionListener ; 25 import java.io.File ; 26 import java.util.Collection ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.Set ; 30 import java.util.Stack ; 31 import java.util.TreeSet ; 32 import java.util.logging.Level ; 33 import java.util.logging.Logger ; 34 import javax.swing.AbstractCellEditor ; 35 import javax.swing.JCheckBox ; 36 import javax.swing.JFileChooser ; 37 import javax.swing.JPanel ; 38 import javax.swing.JTable ; 39 import javax.swing.ListSelectionModel ; 40 import javax.swing.UIManager ; 41 import javax.swing.event.DocumentEvent ; 42 import javax.swing.event.DocumentListener ; 43 import javax.swing.table.AbstractTableModel ; 44 import javax.swing.table.TableCellEditor ; 45 import javax.swing.table.TableCellRenderer ; 46 import org.netbeans.modules.projectimport.LoggerFactory; 47 import org.netbeans.modules.projectimport.ProjectImporterException; 48 import org.netbeans.modules.projectimport.eclipse.EclipseProject; 49 import org.netbeans.modules.projectimport.eclipse.Workspace; 50 import org.netbeans.modules.projectimport.eclipse.WorkspaceFactory; 51 import org.openide.DialogDescriptor; 52 import org.openide.DialogDisplayer; 53 import org.openide.NotifyDescriptor; 54 55 60 final class ProjectSelectionPanel extends JPanel { 61 62 65 private static final Logger logger = 66 LoggerFactory.getDefault().createLogger(ProjectSelectionPanel.class); 67 68 69 private class ProjectCellRenderer extends JCheckBox 70 implements TableCellRenderer { 71 public Component getTableCellRendererComponent(JTable table, Object value, 72 boolean isSelected, boolean hasFocus, int row, int column) { 73 EclipseProject project = projects[row]; 74 setColors(this, isSelected); 75 setText(project.getName()); 76 setSelected(selectedProjects.contains(project) || 77 requiredProjects.contains(project)); 78 setToolTipText(null); 79 if (project.hasJavaNature() && !requiredProjects.contains(project)) { 80 setEnabled(true); 81 } else { 82 setEnabled(false); 84 if (!project.hasJavaNature()) { 85 setToolTipText(ProjectImporterWizard.getMessage( 86 "MSG_NonJavaProject", project.getName())); } 88 } 89 return this; 90 } 91 } 92 93 private void setColors(Component c, boolean isSelected) { 94 c.setBackground(UIManager.getColor(isSelected ? 95 "Table.selectionBackground" : "Table.background")); c.setForeground(UIManager.getColor(isSelected ? 97 "Table.selectionForeground" : "Table.foreground")); } 99 100 private class ProjectCellEditor extends AbstractCellEditor 101 implements TableCellEditor { 102 103 private JCheckBox checkBox; 104 105 public Object getCellEditorValue() { 106 return Boolean.valueOf(checkBox.isSelected()); 107 } 108 109 public Component getTableCellEditorComponent(JTable table, Object value, 110 boolean isSelected, int row, int column) { 111 EclipseProject project = projects[row]; 112 checkBox = new JCheckBox (project.getName(), 113 ((Boolean ) value).booleanValue()); 114 setColors(checkBox, isSelected); 115 checkBox.addActionListener(new ActionListener () { 116 public void actionPerformed(ActionEvent ev) { 117 fireEditingStopped(); 118 } 119 }); 120 return checkBox; 121 } 122 123 public boolean shouldSelectCell(java.util.EventObject anEvent) { 124 return true; 125 } 126 } 127 128 129 private EclipseProject[] projects; 130 131 138 private Set selectedProjects; 139 140 144 private Set requiredProjects; 145 146 147 private String errorMessage; 148 149 private class ProjectTableModel extends AbstractTableModel { 150 public Object getValueAt(int rowIndex, int columnIndex) { 151 EclipseProject project = projects[rowIndex]; 152 return Boolean.valueOf(selectedProjects.contains(project) || 153 requiredProjects.contains(project)); 154 } 155 156 public int getRowCount() { 157 return projects != null ? projects.length : 0; 158 } 159 160 public int getColumnCount() { 161 return 1; 162 } 163 164 public Class getColumnClass(int columnIndex) { 165 return Boolean .class; 166 } 167 168 public boolean isCellEditable(int rowIndex, int columnIndex) { 169 return (projects[rowIndex].hasJavaNature() && 170 !requiredProjects.contains(projects[rowIndex])); 171 } 172 173 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 174 EclipseProject project = projects[rowIndex]; 175 assert projects != null; 176 if (((Boolean ) aValue).booleanValue()) { 177 selectedProjects.add(project); 178 } else { 179 selectedProjects.remove(project); 180 } 181 solveDependencies(); 182 fireTableDataChanged(); 183 projectTable.getSelectionModel().setLeadSelectionIndex(rowIndex); 184 updateValidity(); 185 } 186 } 187 188 189 public void updateValidity() { 190 if (selectedProjects == null || selectedProjects.isEmpty()) { 191 setErrorMessage(ProjectImporterWizard.getMessage( 193 "MSG_ProjectIsNotChosed")); return; 195 } 196 String parent = destination.getText(); 197 for (Iterator it = allProjects().iterator(); it.hasNext(); ) { 198 EclipseProject prj = (EclipseProject) it.next(); 199 String destDir = parent + "/" + prj.getName(); if (new File (destDir).exists()) { 201 setErrorMessage(ProjectImporterWizard.getMessage( 202 "MSG_ProjectExist", prj.getName())); return; 204 } 205 } 206 setErrorMessage(null); 207 } 208 209 210 private Collection allProjects() { 211 Collection all = new HashSet (selectedProjects); 212 all.addAll(requiredProjects); 213 return all; 214 } 215 216 private final Stack solved = new Stack (); 218 private EclipseProject currentRoot; 219 220 224 private void solveDependencies() { 225 requiredProjects.clear(); 226 if (selectedProjects == null || selectedProjects.isEmpty()) { 227 return; 228 } 229 for (Iterator it = selectedProjects.iterator(); it.hasNext(); ) { 230 EclipseProject selProject = (EclipseProject) it.next(); 231 assert selProject != null; 232 solved.push(selProject); 233 currentRoot = selProject; 234 fillUpRequiredProjects(selProject); 235 EclipseProject poped = (EclipseProject) solved.pop(); 236 assert poped.equals(currentRoot); 237 assert solved.isEmpty(); 238 currentRoot = null; 239 } 240 } 241 242 private void fillUpRequiredProjects(EclipseProject project) { 243 Set children = project.getProjects(); 244 if (children == null || children.isEmpty()) { 245 return; 246 } 247 for (Iterator it = children.iterator(); it.hasNext(); ) { 248 EclipseProject child = (EclipseProject) it.next(); 249 assert child != null; 250 if (solved.contains(child)) { 251 recursionDetected(child); 252 return; 253 } 254 requiredProjects.add(child); 255 solved.push(child); 256 fillUpRequiredProjects(child); 257 EclipseProject poped = (EclipseProject) solved.pop(); 258 assert poped.equals(child); 259 } 260 } 261 262 private void recursionDetected(EclipseProject start) { 263 int where = solved.search(start); 264 assert where != -1 : "Cannot find start of the cycle."; EclipseProject rootOfCycle = 266 (EclipseProject) solved.get(solved.size() - where); 267 StringBuffer cycle = new StringBuffer (); 268 for (Iterator it = solved.iterator(); it.hasNext(); ) { 269 cycle.append(((EclipseProject)it.next()).getName()).append(" --> "); } 271 cycle.append(rootOfCycle.getName()).append(" --> ..."); logger.warning("Cycle dependencies was detected. Detected cycle: " + cycle); NotifyDescriptor d = new DialogDescriptor.Message( 274 ProjectImporterWizard.getMessage("MSG_CycleDependencies", cycle.toString()), NotifyDescriptor.WARNING_MESSAGE); 276 DialogDisplayer.getDefault().notify(d); 277 } 278 279 280 public ProjectSelectionPanel() { 281 initComponents(); 282 init(); 283 destination.getDocument().addDocumentListener(new DocumentListener () { 284 public void insertUpdate(DocumentEvent e) { updateValidity(); } 285 public void removeUpdate(DocumentEvent e) { updateValidity(); } 286 public void changedUpdate(DocumentEvent e) {} 287 }); 288 updateValidity(); 289 } 290 291 private void init() { 292 projectTable.setModel(new ProjectTableModel()); 293 projectTable.setTableHeader(null); 294 projectTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 295 projectTable.setDefaultRenderer(Boolean .class, new ProjectCellRenderer()); 296 projectTable.setDefaultEditor(Boolean .class, new ProjectCellEditor()); 297 projectTableSP.getViewport().setBackground(projectTable.getBackground()); 298 destination.setText(System.getProperty("user.home")); } 300 301 302 void loadProjects(String workspaceDir) { 303 Workspace workspace = null; 304 try { 305 workspace = WorkspaceFactory.getInstance().load(workspaceDir); 306 } catch (ProjectImporterException e) { 307 setErrorMessage(ProjectImporterWizard.getMessage( 308 "MSG_WorkspaceIsInvalid", workspaceDir)); logger.log(Level.FINE, "ProjectImporterException catched", e); return; 311 } 312 Set wsPrjs = new TreeSet (workspace.getProjects()); 313 projects = new EclipseProject[wsPrjs.size()]; 314 int i = 0; 315 for (Iterator it = wsPrjs.iterator(); it.hasNext(); ) { 316 projects[i++] = (EclipseProject) it.next(); 317 } 318 selectedProjects = new HashSet (); 319 requiredProjects = new HashSet (); 320 if (projects.length == 0) { 321 setErrorMessage(ProjectImporterWizard.getMessage( 322 "MSG_WorkspaceIsEmpty", workspaceDir)); } else { 324 updateValidity(); 325 } 326 } 327 328 329 Set getProjects() { 330 return selectedProjects; 331 } 332 333 337 int getNumberOfImportedProject() { 338 return allProjects().size(); 339 } 340 341 344 String getDestination() { 345 return destination.getText(); 346 } 347 348 void setErrorMessage(String newMessage) { 349 String oldMessage = this.errorMessage; 350 this.errorMessage = newMessage; 351 firePropertyChange("errorMessage", oldMessage, newMessage); } 353 354 359 private void initComponents() { 361 java.awt.GridBagConstraints gridBagConstraints; 362 363 choosePanel = new javax.swing.JPanel (); 364 destination = new javax.swing.JTextField (); 365 chooseDestButton = new javax.swing.JButton (); 366 prjLocationLBL = new javax.swing.JLabel (); 367 projectPanel = new javax.swing.JPanel (); 368 projectListLabel = new javax.swing.JLabel (); 369 projectTableSP = new javax.swing.JScrollPane (); 370 projectTable = new javax.swing.JTable (); 371 372 setLayout(new java.awt.BorderLayout (0, 12)); 373 374 setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5)); 375 choosePanel.setLayout(new java.awt.GridBagLayout ()); 376 377 gridBagConstraints = new java.awt.GridBagConstraints (); 378 gridBagConstraints.gridx = 1; 379 gridBagConstraints.gridy = 0; 380 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 381 gridBagConstraints.weightx = 1.0; 382 choosePanel.add(destination, gridBagConstraints); 383 384 org.openide.awt.Mnemonics.setLocalizedText(chooseDestButton, org.openide.util.NbBundle.getMessage(ProjectSelectionPanel.class, "CTL_BrowseButton_B")); 385 chooseDestButton.addActionListener(new java.awt.event.ActionListener () { 386 public void actionPerformed(java.awt.event.ActionEvent evt) { 387 chooseDestButtonActionPerformed(evt); 388 } 389 }); 390 391 gridBagConstraints = new java.awt.GridBagConstraints (); 392 gridBagConstraints.gridx = 2; 393 gridBagConstraints.gridy = 0; 394 gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; 395 gridBagConstraints.insets = new java.awt.Insets (0, 11, 0, 0); 396 choosePanel.add(chooseDestButton, gridBagConstraints); 397 398 prjLocationLBL.setLabelFor(destination); 399 org.openide.awt.Mnemonics.setLocalizedText(prjLocationLBL, org.openide.util.NbBundle.getMessage(ProjectSelectionPanel.class, "LBL_LocationOfNBProjects")); 400 gridBagConstraints = new java.awt.GridBagConstraints (); 401 gridBagConstraints.gridx = 0; 402 gridBagConstraints.gridy = 0; 403 gridBagConstraints.insets = new java.awt.Insets (0, 0, 0, 12); 404 choosePanel.add(prjLocationLBL, gridBagConstraints); 405 406 add(choosePanel, java.awt.BorderLayout.SOUTH); 407 408 projectPanel.setLayout(new java.awt.GridBagLayout ()); 409 410 projectListLabel.setLabelFor(projectTable); 411 org.openide.awt.Mnemonics.setLocalizedText(projectListLabel, org.openide.util.NbBundle.getMessage(ProjectSelectionPanel.class, "LBL_ProjectsToImport")); 412 projectListLabel.setVerticalTextPosition(javax.swing.SwingConstants.TOP); 413 gridBagConstraints = new java.awt.GridBagConstraints (); 414 gridBagConstraints.gridx = 0; 415 gridBagConstraints.gridy = 0; 416 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 417 gridBagConstraints.weightx = 1.0; 418 projectPanel.add(projectListLabel, gridBagConstraints); 419 420 projectTable.setShowHorizontalLines(false); 421 projectTable.setShowVerticalLines(false); 422 projectTableSP.setViewportView(projectTable); 423 424 gridBagConstraints = new java.awt.GridBagConstraints (); 425 gridBagConstraints.gridx = 0; 426 gridBagConstraints.gridy = 1; 427 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 428 gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTH; 429 gridBagConstraints.weighty = 1.0; 430 gridBagConstraints.insets = new java.awt.Insets (2, 0, 0, 0); 431 projectPanel.add(projectTableSP, gridBagConstraints); 432 433 add(projectPanel, java.awt.BorderLayout.CENTER); 434 435 } 437 private void chooseDestButtonActionPerformed(java.awt.event.ActionEvent evt) { JFileChooser chooser = new JFileChooser (); 439 chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 440 int ret = chooser.showOpenDialog(this); 441 if (ret == JFileChooser.APPROVE_OPTION) { 442 destination.setText(chooser.getSelectedFile().getAbsolutePath()); 443 } 444 } 446 private javax.swing.JButton chooseDestButton; 448 private javax.swing.JPanel choosePanel; 449 private javax.swing.JTextField destination; 450 private javax.swing.JLabel prjLocationLBL; 451 private javax.swing.JLabel projectListLabel; 452 private javax.swing.JPanel projectPanel; 453 private javax.swing.JTable projectTable; 454 private javax.swing.JScrollPane projectTableSP; 455 } 457 | Popular Tags |