1 19 20 package org.netbeans.modules.apisupport.project.ui.customizer; 21 22 import java.awt.Component ; 23 import java.io.CharConversionException ; 24 import java.util.Arrays ; 25 import java.util.Collection ; 26 import java.util.Collections ; 27 import java.util.HashMap ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.Map ; 31 import java.util.Set ; 32 import java.util.SortedSet ; 33 import java.util.TreeSet ; 34 import javax.swing.AbstractListModel ; 35 import javax.swing.ComboBoxModel ; 36 import javax.swing.DefaultComboBoxModel ; 37 import javax.swing.DefaultListCellRenderer ; 38 import javax.swing.DefaultListModel ; 39 import javax.swing.JList ; 40 import javax.swing.ListCellRenderer ; 41 import javax.swing.ListModel ; 42 import javax.swing.table.AbstractTableModel ; 43 import org.netbeans.api.project.Project; 44 import org.netbeans.api.project.ProjectUtils; 45 import org.netbeans.modules.apisupport.project.NbModuleProject; 46 import org.netbeans.modules.apisupport.project.Util; 47 import org.netbeans.modules.apisupport.project.universe.ModuleEntry; 48 import org.openide.awt.HtmlRenderer; 49 import org.openide.util.NbBundle; 50 import org.openide.xml.XMLUtil; 51 52 55 public final class CustomizerComponentFactory { 56 57 58 public static final String WAIT_VALUE = 59 NbBundle.getMessage(CustomizerComponentFactory.class, "ComponentFactory_please_wait"); 60 61 62 public static final String EMPTY_VALUE = 63 NbBundle.getMessage(CustomizerComponentFactory.class, "LBL_Empty"); 64 65 static DependencyListModel INVALID_DEP_LIST_MODEL; 66 67 private static final String INVALID_PLATFORM = 68 "<html><font color=\"!nb.errorForeground\"><" + NbBundle.getMessage(CustomizerComponentFactory.class, "MSG_InvalidPlatform") 70 + "></font></html>"; 72 private CustomizerComponentFactory() { 73 } 75 76 80 public static ComboBoxModel createComboWaitModel() { 81 return new DefaultComboBoxModel (new Object [] { WAIT_VALUE }); 82 } 83 84 85 public static ComboBoxModel createComboEmptyModel() { 86 return new DefaultComboBoxModel (new Object [] { EMPTY_VALUE }); 87 } 88 89 93 public static boolean isWaitModel(final ListModel model) { 94 return hasOnlyValue(model, CustomizerComponentFactory.WAIT_VALUE); 95 } 96 97 101 public static boolean hasOnlyValue(final ListModel model, final Object value) { 102 return model != null && model.getSize() == 1 && model.getElementAt(0) == value; 103 } 104 105 111 public static ListModel createListWaitModel() { 112 DefaultListModel listWaitModel = new DefaultListModel (); 113 listWaitModel.addElement(WAIT_VALUE); 114 return listWaitModel; 115 } 116 117 121 static CustomizerComponentFactory.DependencyListModel createSortedDependencyListModel( 122 final Set <ModuleDependency> deps) { 123 assert deps != null; 124 return new CustomizerComponentFactory.DependencyListModel(deps, true); 125 } 126 127 131 static CustomizerComponentFactory.DependencyListModel createDependencyListModel( 132 final Set <ModuleDependency> deps) { 133 assert deps != null; 134 return new CustomizerComponentFactory.DependencyListModel(deps, false); 135 } 136 137 static synchronized CustomizerComponentFactory.DependencyListModel getInvalidDependencyListModel() { 138 if (INVALID_DEP_LIST_MODEL == null) { 139 INVALID_DEP_LIST_MODEL = new DependencyListModel(); 140 } 141 return INVALID_DEP_LIST_MODEL; 142 } 143 144 static ListCellRenderer getDependencyCellRenderer(boolean boldfaceApiModules) { 145 return new DependencyListCellRenderer(boldfaceApiModules); 146 } 147 148 static ListCellRenderer getModuleCellRenderer() { 149 return new ProjectListCellRenderer(); 150 } 151 static ListCellRenderer getModuleEntryCellRenderer() { 152 return new ModuleEntryListCellRenderer(); 153 } 154 155 static final class DependencyListModel extends AbstractListModel { 156 157 private final Set <ModuleDependency> currentDeps; 158 private final Set <ModuleDependency> addedDeps = new HashSet (); 159 private final Set <ModuleDependency> removedDeps = new HashSet (); 160 private final Map <ModuleDependency, ModuleDependency> editedDeps = new HashMap (); 161 162 private boolean changed; 163 private final boolean invalid; 164 165 DependencyListModel(Set <ModuleDependency> deps, boolean sorted) { 166 if (sorted) { 167 currentDeps = new TreeSet (ModuleDependency.LOCALIZED_NAME_COMPARATOR); 168 currentDeps.addAll(deps); 169 } else { 170 currentDeps = deps; 171 } 172 invalid = false; 173 } 174 175 DependencyListModel() { 176 currentDeps = Collections.emptySet(); 177 invalid = true; 178 } 179 180 public int getSize() { 181 return invalid ? 1 : currentDeps.size(); 182 } 183 184 public Object getElementAt(int i) { 185 return invalid ? INVALID_PLATFORM : currentDeps.toArray()[i]; 186 } 187 188 ModuleDependency getDependency(int i) { 189 return (ModuleDependency) getElementAt(i); 190 } 191 192 void addDependency(ModuleDependency dep) { 193 if (!currentDeps.contains(dep)) { 194 int origSize = currentDeps.size(); 195 currentDeps.add(dep); 196 removedDeps.remove(dep); changed = true; 198 this.fireContentsChanged(this, 0, origSize); 199 } 200 } 201 202 void removeDependencies(Collection <ModuleDependency> deps) { 203 int origSize = currentDeps.size(); 204 currentDeps.removeAll(deps); 205 for (ModuleDependency entry : deps) { 206 if (!addedDeps.remove(entry)) { 207 removedDeps.add(entry); 208 } 209 } 210 changed = true; 211 this.fireContentsChanged(this, 0, origSize); 212 } 213 214 void editDependency(ModuleDependency origDep, ModuleDependency newDep) { 215 editedDeps.put(origDep, newDep); 216 currentDeps.remove(origDep); 217 currentDeps.add(newDep); 218 changed = true; 219 this.fireContentsChanged(this, 0, currentDeps.size()); 220 } 221 222 Set <ModuleDependency> getDependencies() { 223 return Collections.unmodifiableSet(currentDeps); 224 } 225 226 Set <ModuleDependency> getRemovedDependencies() { 227 return removedDeps; 228 } 229 230 Set <ModuleDependency> getAddedDependencies() { 231 return addedDeps; 232 } 233 234 Map <ModuleDependency, ModuleDependency> getEditedDependencies() { 235 return editedDeps; 236 } 237 238 242 ModuleDependency findEdited(ModuleDependency toFind) { 243 for (Iterator it = editedDeps.values().iterator(); it.hasNext(); ) { 244 ModuleDependency curr = (ModuleDependency) it.next(); 245 if (curr.getModuleEntry().getCodeNameBase().equals( 246 toFind.getModuleEntry().getCodeNameBase())) { 247 return curr; 248 } 249 } 250 return null; 251 } 252 253 boolean isChanged() { 254 return changed; 255 } 256 } 257 258 private static final class DependencyListCellRenderer implements ListCellRenderer { 259 260 private final HtmlRenderer.Renderer renderer = HtmlRenderer.createRenderer(); 261 private final boolean boldfaceApiModules; 262 263 public DependencyListCellRenderer(boolean boldfaceApiModules) { 264 this.boldfaceApiModules = boldfaceApiModules; 265 } 266 267 public Component getListCellRendererComponent(JList list, Object value, 268 int index, boolean isSelected, boolean cellHasFocus) { 269 String text; 270 if (value == WAIT_VALUE) { 271 text = WAIT_VALUE; 272 } else if (value == INVALID_PLATFORM) { 273 text = INVALID_PLATFORM; 274 renderer.setHtml(true); 275 } else { 276 ModuleDependency md = (ModuleDependency) value; 277 boolean bold = boldfaceApiModules && md.getModuleEntry().getPublicPackages().length > 0; 279 boolean deprecated = md.getModuleEntry().isDeprecated(); 280 renderer.setHtml(bold || deprecated); 281 String locName = md.getModuleEntry().getLocalizedName(); 282 text = locName; 283 if (bold || deprecated) { 284 try { 285 text = "<html>" + (bold ? "<b>" : "") + (deprecated ? "<s>" : "") + XMLUtil.toElementContent(locName); } catch (CharConversionException e) { 287 } 289 } 290 } 291 return renderer.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus); 292 } 293 294 } 295 296 private static class ProjectListCellRenderer extends DefaultListCellRenderer { 297 298 public Component getListCellRendererComponent(JList list, Object value, 299 int index, boolean isSelected, boolean cellHasFocus) { 300 Component c = super.getListCellRendererComponent( 301 list, ProjectUtils.getInformation((Project) value).getDisplayName(), 302 index, isSelected, cellHasFocus); 303 return c; 304 } 305 306 } 307 308 private static class ModuleEntryListCellRenderer extends DefaultListCellRenderer { 309 310 public Component getListCellRendererComponent(JList list, Object value, 311 int index, boolean isSelected, boolean cellHasFocus) { 312 ModuleEntry me = (ModuleEntry)value; 313 Component c = super.getListCellRendererComponent( 314 list, me.getLocalizedName(), index, isSelected, cellHasFocus); 315 return c; 316 } 317 318 } 319 320 static final class PublicPackagesTableModel extends AbstractTableModel { 321 322 private Boolean [] selected; 323 private Boolean [] originalSelected; 324 private String [] pkgNames; 325 326 PublicPackagesTableModel(Map <String , Boolean > publicPackages) { 327 reloadData(publicPackages); 328 } 329 330 void reloadData(Map <String , Boolean > publicPackages) { 331 selected = new Boolean [publicPackages.size()]; 332 publicPackages.values().toArray(selected); 333 originalSelected = new Boolean [publicPackages.size()]; 334 System.arraycopy(selected, 0, originalSelected, 0, selected.length); 335 pkgNames = new String [publicPackages.size()]; 336 publicPackages.keySet().toArray(pkgNames); 337 fireTableDataChanged(); 338 } 339 340 public int getRowCount() { 341 return pkgNames.length; 342 } 343 344 public int getColumnCount() { 345 return 2; 346 } 347 348 public Object getValueAt(int rowIndex, int columnIndex) { 349 if (columnIndex == 0) { 350 return selected[rowIndex]; 351 } else { 352 return pkgNames[rowIndex]; 353 } 354 } 355 356 public Class getColumnClass(int columnIndex) { 357 if (columnIndex == 0) { 358 return Boolean .class; 359 } else { 360 return String .class; 361 } 362 } 363 364 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 365 assert columnIndex == 0 : "Who is trying to modify second column?"; selected[rowIndex] = (Boolean ) aValue; 367 fireTableCellUpdated(rowIndex, 0); 368 } 369 370 String [] getSelectedPackages() { 371 Set s = new TreeSet (); 372 for (int i = 0; i < pkgNames.length; i++) { 373 if (selected[i].booleanValue()) { 374 s.add(pkgNames[i]); 375 } 376 } 377 String [] result = new String [s.size()]; 378 s.toArray(result); 379 return result; 380 } 381 382 public boolean isChanged() { 383 return !Arrays.asList(selected).equals(Arrays.asList(originalSelected)); 384 } 385 386 } 387 388 static final class FriendListModel extends AbstractListModel { 389 390 private final Set <String > friends = new TreeSet (); 391 392 private boolean changed; 393 394 FriendListModel(String [] friends) { 395 if (friends != null) { 396 this.friends.addAll(Arrays.asList(friends)); 397 } 398 } 399 400 public Object getElementAt(int index) { 401 if (index >= friends.size()) { 402 return null; 403 } else { 404 return friends.toArray()[index]; 405 } 406 } 407 408 public int getSize() { 409 return friends.size(); 410 } 411 412 void addFriend(String friend) { 413 friends.add(friend); 414 changed = true; 415 super.fireIntervalAdded(this, 0, friends.size()); 416 } 417 418 void removeFriend(String friend) { 419 friends.remove(friend); 420 changed = true; 421 super.fireIntervalRemoved(this, 0, friends.size()); 422 } 423 424 String [] getFriends() { 425 String [] result = new String [friends.size()]; 426 return (String []) friends.toArray(result); 427 } 428 429 boolean isChanged() { 430 return changed; 431 } 432 } 433 434 static final class RequiredTokenListModel extends AbstractListModel { 435 436 private final SortedSet <String > tokens; 437 private boolean changed; 438 439 RequiredTokenListModel(final SortedSet tokens) { 440 this.tokens = new TreeSet (tokens); 441 } 442 443 public Object getElementAt(int index) { 444 return index >= tokens.size() ? null : tokens.toArray()[index]; 445 } 446 447 public int getSize() { 448 return tokens.size(); 449 } 450 451 void addToken(String token) { 452 tokens.add(token); 453 changed = true; 454 super.fireIntervalAdded(this, 0, tokens.size()); 455 } 456 457 void removeToken(String token) { 458 tokens.remove(token); 459 changed = true; 460 super.fireIntervalRemoved(this, 0, tokens.size()); 461 } 462 463 String [] getTokens() { 464 String [] result = new String [tokens.size()]; 465 return (String []) tokens.toArray(result); 466 } 467 468 boolean isChanged() { 469 return changed; 470 } 471 472 } 473 474 static final class SuiteSubModulesListModel extends AbstractListModel { 475 476 private final Set <NbModuleProject> subModules; 477 478 private boolean changed; 479 480 SuiteSubModulesListModel(Set <NbModuleProject> subModules) { 481 this.subModules = new TreeSet (Util.projectDisplayNameComparator()); 482 this.subModules.addAll(subModules); 483 } 484 485 public int getSize() { 486 return subModules.size(); 487 } 488 489 public Object getElementAt(int i) { 490 return subModules.toArray()[i]; 491 } 492 493 boolean contains(Project module) { 494 return subModules.contains(module); 495 } 496 497 void removeModules(Collection modules) { 498 int origSize = subModules.size(); 499 subModules.removeAll(modules); 500 changed = true; 501 this.fireContentsChanged(this, 0, origSize); 502 } 503 504 boolean addModule(NbModuleProject module) { 505 int origSize = subModules.size(); 506 boolean added = subModules.add(module); 507 changed = true; 508 this.fireContentsChanged(this, 0, origSize + 1); 509 return added; 510 } 511 512 public Set <NbModuleProject> getSubModules() { 513 return subModules; 514 } 515 516 public boolean isChanged() { 517 return changed; 518 } 519 } 520 521 } 522 | Popular Tags |