1 7 package javax.swing; 8 9 import java.awt.Component ; 10 import java.awt.Container ; 11 import java.awt.Window ; 12 import java.util.*; 13 import java.awt.FocusTraversalPolicy ; 14 import java.util.logging.*; 15 16 44 public class SortingFocusTraversalPolicy 45 extends InternalFrameFocusTraversalPolicy 46 { 47 private Comparator<? super Component > comparator; 48 private boolean implicitDownCycleTraversal = true; 49 50 private Logger log = Logger.getLogger("javax.swing.SortingFocusTraversalPolicy"); 51 52 64 private Container cachedRoot; 65 private List cachedCycle; 66 67 private static final SwingContainerOrderFocusTraversalPolicy 70 fitnessTestPolicy = new SwingContainerOrderFocusTraversalPolicy(); 71 72 78 protected SortingFocusTraversalPolicy() { 79 } 80 81 84 public SortingFocusTraversalPolicy(Comparator<? super Component > comparator) { 85 this.comparator = comparator; 86 } 87 88 private void enumerateAndSortCycle(Container focusCycleRoot, 89 List cycle, Map defaults) { 90 List defaultRoots = null; 91 92 if (!focusCycleRoot.isShowing()) { 93 return; 94 } 95 96 enumerateCycle(focusCycleRoot, cycle); 97 98 boolean addDefaultComponents = 99 (defaults != null && getImplicitDownCycleTraversal()); 100 101 if (log.isLoggable(Level.FINE)) log.fine("### Will add defaults: " + addDefaultComponents); 102 103 if (addDefaultComponents) { 106 defaultRoots = new ArrayList(); 107 for (Iterator iter = cycle.iterator(); iter.hasNext(); ) { 108 Component comp = (Component )iter.next(); 109 if ((comp instanceof Container ) && 110 ((Container )comp).isFocusCycleRoot()) 111 { 112 defaultRoots.add(comp); 113 } 114 } 115 Collections.sort(defaultRoots, comparator); 116 } 117 118 Collections.sort(cycle, comparator); 120 121 if (addDefaultComponents) { 126 for (ListIterator defaultRootsIter = 127 defaultRoots.listIterator(defaultRoots.size()); 128 defaultRootsIter.hasPrevious(); ) 129 { 130 Container root = (Container )defaultRootsIter.previous(); 131 Component defComp = 132 root.getFocusTraversalPolicy().getDefaultComponent(root); 133 134 if (defComp != null && defComp.isShowing()) { 135 int index = Collections.binarySearch(cycle, root, 136 comparator); 137 if (index < 0) { 138 142 index = -index - 2; 143 } 144 145 defaults.put(new Integer (index), defComp); 146 } 147 } 148 } 149 } 150 151 private void enumerateCycle(Container container, List cycle) { 152 if (!(container.isVisible() && container.isDisplayable())) { 153 return; 154 } 155 156 cycle.add(container); 157 158 Component [] components = container.getComponents(); 159 for (int i = 0; i < components.length; i++) { 160 Component comp = components[i]; 161 if ((comp instanceof Container ) 162 && !((Container )comp).isFocusTraversalPolicyProvider() 163 && !((Container )comp).isFocusCycleRoot() 164 && !((comp instanceof JComponent ) 165 && ((JComponent )comp).isManagingFocus())) 166 { 167 enumerateCycle((Container )comp, cycle); 168 } else { 169 cycle.add(comp); 170 } 171 } 172 } 173 174 Container getTopmostProvider(Container focusCycleRoot, Component aComponent) { 175 Container aCont = aComponent.getParent(); 176 Container ftp = null; 177 while (aCont != focusCycleRoot && aCont != null) { 178 if (aCont.isFocusTraversalPolicyProvider()) { 179 ftp = aCont; 180 } 181 aCont = aCont.getParent(); 182 } 183 if (aCont == null) { 184 return null; 185 } 186 return ftp; 187 } 188 189 211 public Component getComponentAfter(Container aContainer, 212 Component aComponent) { 213 if (log.isLoggable(Level.FINE)) log.fine("### Searching in " + aContainer.getName() + " for component after " + aComponent.getName()); 214 215 if (aContainer == null || aComponent == null) { 216 throw new IllegalArgumentException ("aContainer and aComponent cannot be null"); 217 } 218 if (!aContainer.isFocusTraversalPolicyProvider() && !aContainer.isFocusCycleRoot()) { 219 throw new IllegalArgumentException ("aContainer should be focus cycle root or focus traversal policy provider"); 220 } else if (aContainer.isFocusCycleRoot() && !aComponent.isFocusCycleRoot(aContainer)) { 221 throw new IllegalArgumentException ("aContainer is not a focus cycle root of aComponent"); 222 } 223 224 Container ftp = getTopmostProvider(aContainer, aComponent); 226 if (ftp != null) { 227 if (log.isLoggable(Level.FINE)) log.fine("### Asking FTP " + ftp.getName() + " for component after " + aComponent.getName()); 228 FocusTraversalPolicy policy = ftp.getFocusTraversalPolicy(); 230 Component retval = policy.getComponentAfter(ftp, aComponent); 231 if (retval == policy.getFirstComponent(ftp)) { 232 retval = null; 233 } 234 235 if (retval != null) { 236 if (log.isLoggable(Level.FINE)) log.fine("### FTP returned " + retval.getName()); 237 return retval; 238 } 239 aComponent = ftp; 240 } 241 242 List cycle = new ArrayList(); 243 Map defaults = new HashMap(); 244 enumerateAndSortCycle(aContainer, cycle, defaults); 245 246 int index; 247 try { 248 index = Collections.binarySearch(cycle, aComponent, comparator); 249 } catch (ClassCastException e) { 250 if (log.isLoggable(Level.FINE)) log.fine("### Didn't find component " + aComponent.getName() + " in a cycle " + aContainer.getName()); 251 return getFirstComponent(aContainer); 252 } 253 254 if (index < 0) { 255 int i = cycle.indexOf(aComponent); 260 if (i >= 0) { 261 index = i; 262 } else { 263 267 index = -index - 2; 268 } 269 } 270 271 Component defComp = (Component )defaults.get(new Integer (index)); 272 if (defComp != null) { 273 return defComp; 274 } 275 276 do { 277 index++; 278 279 if (index >= cycle.size()) { 280 if (aContainer.isFocusCycleRoot()) { 281 this.cachedRoot = aContainer; 282 this.cachedCycle = cycle; 283 284 Component retval = getFirstComponent(aContainer); 285 286 this.cachedRoot = null; 287 this.cachedCycle = null; 288 289 return retval; 290 } else { 291 return null; 292 } 293 } else { 294 Component comp = (Component )cycle.get(index); 295 if (accept(comp)) { 296 return comp; 297 } else if (comp instanceof Container && ((Container )comp).isFocusTraversalPolicyProvider()) { 298 return ((Container )comp).getFocusTraversalPolicy().getDefaultComponent((Container )comp); 299 } 300 } 301 } while (true); 302 } 303 304 326 public Component getComponentBefore(Container aContainer, 327 Component aComponent) { 328 if (aContainer == null || aComponent == null) { 329 throw new IllegalArgumentException ("aContainer and aComponent cannot be null"); 330 } 331 if (!aContainer.isFocusTraversalPolicyProvider() && !aContainer.isFocusCycleRoot()) { 332 throw new IllegalArgumentException ("aContainer should be focus cycle root or focus traversal policy provider"); 333 } else if (aContainer.isFocusCycleRoot() && !aComponent.isFocusCycleRoot(aContainer)) { 334 throw new IllegalArgumentException ("aContainer is not a focus cycle root of aComponent"); 335 } 336 337 Container ftp = getTopmostProvider(aContainer, aComponent); 339 if (ftp != null) { 340 if (log.isLoggable(Level.FINE)) log.fine("### Asking FTP " + ftp.getName() + " for component after " + aComponent.getName()); 341 FocusTraversalPolicy policy = ftp.getFocusTraversalPolicy(); 343 Component retval = policy.getComponentBefore(ftp, aComponent); 344 if (retval == policy.getLastComponent(ftp)) { 345 retval = null; 346 } 347 if (retval != null) { 348 if (log.isLoggable(Level.FINE)) log.fine("### FTP returned " + retval.getName()); 349 return retval; 350 } 351 aComponent = ftp; 352 } 353 354 355 List cycle = new ArrayList(); 356 Map defaults = new HashMap(); 357 enumerateAndSortCycle(aContainer, cycle, defaults); 358 359 if (log.isLoggable(Level.FINE)) log.fine("### Cycle is " + cycle + ", component is " + aComponent); 360 361 int index; 362 try { 363 index = Collections.binarySearch(cycle, aComponent, comparator); 364 } catch (ClassCastException e) { 365 return getLastComponent(aContainer); 366 } 367 368 if (index < 0) { 369 373 index = -index - 2; 374 } else { 375 index--; 376 } 377 378 if (log.isLoggable(Level.FINE)) log.fine("### Index is " + index); 379 380 if (index >= 0) { 381 Component defComp = (Component )defaults.get(new Integer (index)); 382 if (defComp != null && cycle.get(index) != aContainer) { 383 if (log.isLoggable(Level.FINE)) log.fine("### Returning default " + defComp.getName() + " at " + index); 384 return defComp; 385 } 386 } 387 388 do { 389 if (index < 0) { 390 this.cachedRoot = aContainer; 391 this.cachedCycle = cycle; 392 393 Component retval = getLastComponent(aContainer); 394 395 this.cachedRoot = null; 396 this.cachedCycle = null; 397 398 return retval; 399 } else { 400 Component comp = (Component )cycle.get(index); 401 if (accept(comp)) { 402 return comp; 403 } else if (comp instanceof Container && ((Container )comp).isFocusTraversalPolicyProvider()) { 404 return ((Container )comp).getFocusTraversalPolicy().getLastComponent((Container )comp); 405 } 406 } 407 index--; 408 } while (true); 409 } 410 411 422 public Component getFirstComponent(Container aContainer) { 423 List cycle; 424 425 if (log.isLoggable(Level.FINE)) log.fine("### Getting first component in " + aContainer.getName()); 426 if (aContainer == null) { 427 throw new IllegalArgumentException ("aContainer cannot be null"); 428 } 429 430 if (this.cachedRoot == aContainer) { 431 cycle = this.cachedCycle; 432 } else { 433 cycle = new ArrayList(); 434 enumerateAndSortCycle(aContainer, cycle, null); 435 } 436 437 int size = cycle.size(); 438 if (size == 0) { 439 return null; 440 } 441 442 for (int i= 0; i < cycle.size(); i++) { 443 Component comp = (Component )cycle.get(i); 444 if (accept(comp)) { 445 return comp; 446 } else if (comp instanceof Container && !(comp == aContainer) && ((Container )comp).isFocusTraversalPolicyProvider()) { 447 return ((Container )comp).getFocusTraversalPolicy().getDefaultComponent((Container )comp); 448 } 449 } 450 return null; 451 } 452 453 464 public Component getLastComponent(Container aContainer) { 465 List cycle; 466 if (log.isLoggable(Level.FINE)) log.fine("### Getting last component in " + aContainer.getName()); 467 468 if (aContainer == null) { 469 throw new IllegalArgumentException ("aContainer cannot be null"); 470 } 471 472 if (this.cachedRoot == aContainer) { 473 cycle = this.cachedCycle; 474 } else { 475 cycle = new ArrayList(); 476 enumerateAndSortCycle(aContainer, cycle, null); 477 } 478 479 int size = cycle.size(); 480 if (size == 0) { 481 if (log.isLoggable(Level.FINE)) log.fine("### Cycle is empty"); 482 return null; 483 } 484 if (log.isLoggable(Level.FINE)) log.fine("### Cycle is " + cycle); 485 486 for (int i= cycle.size()-1; i >= 0; i--) { 487 Component comp = (Component )cycle.get(i); 488 if (accept(comp)) { 489 return comp; 490 } else if (comp instanceof Container && !(comp == aContainer) && ((Container )comp).isFocusTraversalPolicyProvider()) { 491 return ((Container )comp).getFocusTraversalPolicy().getLastComponent((Container )comp); 492 } 493 } 494 return null; 495 } 496 497 510 public Component getDefaultComponent(Container aContainer) { 511 return getFirstComponent(aContainer); 512 } 513 514 528 public void setImplicitDownCycleTraversal(boolean 529 implicitDownCycleTraversal) { 530 this.implicitDownCycleTraversal = implicitDownCycleTraversal; 531 } 532 533 546 public boolean getImplicitDownCycleTraversal() { 547 return implicitDownCycleTraversal; 548 } 549 550 556 protected void setComparator(Comparator<? super Component > comparator) { 557 this.comparator = comparator; 558 } 559 560 566 protected Comparator<? super Component > getComparator() { 567 return comparator; 568 } 569 570 580 protected boolean accept(Component aComponent) { 581 return fitnessTestPolicy.accept(aComponent); 582 } 583 } 584 585 class SwingContainerOrderFocusTraversalPolicy 588 extends java.awt.ContainerOrderFocusTraversalPolicy 589 { 590 public boolean accept(Component aComponent) { 591 return super.accept(aComponent); 592 } 593 } 594 | Popular Tags |