jdk/src/share/classes/javax/swing/SortingFocusTraversalPolicy.java
changeset 3938 ef327bd847c0
parent 3082 24c8d93ac1e1
child 5506 202f599c92aa
equal deleted inserted replaced
3934:487e1aa949c4 3938:ef327bd847c0
    27 import java.awt.Component;
    27 import java.awt.Component;
    28 import java.awt.Container;
    28 import java.awt.Container;
    29 import java.awt.Window;
    29 import java.awt.Window;
    30 import java.util.*;
    30 import java.util.*;
    31 import java.awt.FocusTraversalPolicy;
    31 import java.awt.FocusTraversalPolicy;
    32 import java.util.logging.*;
    32 import sun.util.logging.PlatformLogger;
    33 
    33 
    34 /**
    34 /**
    35  * A FocusTraversalPolicy that determines traversal order by sorting the
    35  * A FocusTraversalPolicy that determines traversal order by sorting the
    36  * Components of a focus traversal cycle based on a given Comparator. Portions
    36  * Components of a focus traversal cycle based on a given Comparator. Portions
    37  * of the Component hierarchy that are not visible and displayable will not be
    37  * of the Component hierarchy that are not visible and displayable will not be
    62     extends InternalFrameFocusTraversalPolicy
    62     extends InternalFrameFocusTraversalPolicy
    63 {
    63 {
    64     private Comparator<? super Component> comparator;
    64     private Comparator<? super Component> comparator;
    65     private boolean implicitDownCycleTraversal = true;
    65     private boolean implicitDownCycleTraversal = true;
    66 
    66 
    67     private Logger log = Logger.getLogger("javax.swing.SortingFocusTraversalPolicy");
    67     private PlatformLogger log = PlatformLogger.getLogger("javax.swing.SortingFocusTraversalPolicy");
    68 
    68 
    69     /**
    69     /**
    70      * Used by getComponentAfter and getComponentBefore for efficiency. In
    70      * Used by getComponentAfter and getComponentBefore for efficiency. In
    71      * order to maintain compliance with the specification of
    71      * order to maintain compliance with the specification of
    72      * FocusTraversalPolicy, if traversal wraps, we should invoke
    72      * FocusTraversalPolicy, if traversal wraps, we should invoke
   113     private int getComponentIndex(List<Component> cycle, Component aComponent) {
   113     private int getComponentIndex(List<Component> cycle, Component aComponent) {
   114         int index;
   114         int index;
   115         try {
   115         try {
   116             index = Collections.binarySearch(cycle, aComponent, comparator);
   116             index = Collections.binarySearch(cycle, aComponent, comparator);
   117         } catch (ClassCastException e) {
   117         } catch (ClassCastException e) {
   118             if (log.isLoggable(Level.FINE)) {
   118             if (log.isLoggable(PlatformLogger.FINE)) {
   119                 log.log(Level.FINE, "### During the binary search for " + aComponent + " the exception occured: ", e);
   119                 log.fine("### During the binary search for " + aComponent + " the exception occured: ", e);
   120             }
   120             }
   121             return -1;
   121             return -1;
   122         }
   122         }
   123         if (index < 0) {
   123         if (index < 0) {
   124             // Fix for 5070991.
   124             // Fix for 5070991.
   191 
   191 
   192             if (cont.isFocusCycleRoot()) {
   192             if (cont.isFocusCycleRoot()) {
   193                 if (getImplicitDownCycleTraversal()) {
   193                 if (getImplicitDownCycleTraversal()) {
   194                     retComp = cont.getFocusTraversalPolicy().getDefaultComponent(cont);
   194                     retComp = cont.getFocusTraversalPolicy().getDefaultComponent(cont);
   195 
   195 
   196                     if (retComp != null && log.isLoggable(Level.FINE)) {
   196                     if (retComp != null && log.isLoggable(PlatformLogger.FINE)) {
   197                         log.fine("### Transfered focus down-cycle to " + retComp +
   197                         log.fine("### Transfered focus down-cycle to " + retComp +
   198                                  " in the focus cycle root " + cont);
   198                                  " in the focus cycle root " + cont);
   199                     }
   199                     }
   200                 } else {
   200                 } else {
   201                     return null;
   201                     return null;
   203             } else if (cont.isFocusTraversalPolicyProvider()) {
   203             } else if (cont.isFocusTraversalPolicyProvider()) {
   204                 retComp = (traversalDirection == FORWARD_TRAVERSAL ?
   204                 retComp = (traversalDirection == FORWARD_TRAVERSAL ?
   205                            cont.getFocusTraversalPolicy().getDefaultComponent(cont) :
   205                            cont.getFocusTraversalPolicy().getDefaultComponent(cont) :
   206                            cont.getFocusTraversalPolicy().getLastComponent(cont));
   206                            cont.getFocusTraversalPolicy().getLastComponent(cont));
   207 
   207 
   208                 if (retComp != null && log.isLoggable(Level.FINE)) {
   208                 if (retComp != null && log.isLoggable(PlatformLogger.FINE)) {
   209                     log.fine("### Transfered focus to " + retComp + " in the FTP provider " + cont);
   209                     log.fine("### Transfered focus to " + retComp + " in the FTP provider " + cont);
   210                 }
   210                 }
   211             }
   211             }
   212         }
   212         }
   213         return retComp;
   213         return retComp;
   234      * @throws IllegalArgumentException if aContainer is not a focus cycle
   234      * @throws IllegalArgumentException if aContainer is not a focus cycle
   235      *         root of aComponent or a focus traversal policy provider, or if either aContainer or
   235      *         root of aComponent or a focus traversal policy provider, or if either aContainer or
   236      *         aComponent is null
   236      *         aComponent is null
   237      */
   237      */
   238     public Component getComponentAfter(Container aContainer, Component aComponent) {
   238     public Component getComponentAfter(Container aContainer, Component aComponent) {
   239         if (log.isLoggable(Level.FINE)) {
   239         if (log.isLoggable(PlatformLogger.FINE)) {
   240             log.fine("### Searching in " + aContainer + " for component after " + aComponent);
   240             log.fine("### Searching in " + aContainer + " for component after " + aComponent);
   241         }
   241         }
   242 
   242 
   243         if (aContainer == null || aComponent == null) {
   243         if (aContainer == null || aComponent == null) {
   244             throw new IllegalArgumentException("aContainer and aComponent cannot be null");
   244             throw new IllegalArgumentException("aContainer and aComponent cannot be null");
   258         }
   258         }
   259 
   259 
   260         // See if the component is inside of policy provider.
   260         // See if the component is inside of policy provider.
   261         Container provider = getTopmostProvider(aContainer, aComponent);
   261         Container provider = getTopmostProvider(aContainer, aComponent);
   262         if (provider != null) {
   262         if (provider != null) {
   263             if (log.isLoggable(Level.FINE)) {
   263             if (log.isLoggable(PlatformLogger.FINE)) {
   264                 log.fine("### Asking FTP " + provider + " for component after " + aComponent);
   264                 log.fine("### Asking FTP " + provider + " for component after " + aComponent);
   265             }
   265             }
   266 
   266 
   267             // FTP knows how to find component after the given. We don't.
   267             // FTP knows how to find component after the given. We don't.
   268             FocusTraversalPolicy policy = provider.getFocusTraversalPolicy();
   268             FocusTraversalPolicy policy = provider.getFocusTraversalPolicy();
   269             Component afterComp = policy.getComponentAfter(provider, aComponent);
   269             Component afterComp = policy.getComponentAfter(provider, aComponent);
   270 
   270 
   271             // Null result means that we overstepped the limit of the FTP's cycle.
   271             // Null result means that we overstepped the limit of the FTP's cycle.
   272             // In that case we must quit the cycle, otherwise return the component found.
   272             // In that case we must quit the cycle, otherwise return the component found.
   273             if (afterComp != null) {
   273             if (afterComp != null) {
   274                 if (log.isLoggable(Level.FINE)) log.fine("### FTP returned " + afterComp);
   274                 if (log.isLoggable(PlatformLogger.FINE)) log.fine("### FTP returned " + afterComp);
   275                 return afterComp;
   275                 return afterComp;
   276             }
   276             }
   277             aComponent = provider;
   277             aComponent = provider;
   278         }
   278         }
   279 
   279 
   280         List<Component> cycle = getFocusTraversalCycle(aContainer);
   280         List<Component> cycle = getFocusTraversalCycle(aContainer);
   281 
   281 
   282         if (log.isLoggable(Level.FINE)) log.fine("### Cycle is " + cycle + ", component is " + aComponent);
   282         if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Cycle is " + cycle + ", component is " + aComponent);
   283 
   283 
   284         int index = getComponentIndex(cycle, aComponent);
   284         int index = getComponentIndex(cycle, aComponent);
   285 
   285 
   286         if (index < 0) {
   286         if (index < 0) {
   287             if (log.isLoggable(Level.FINE)) {
   287             if (log.isLoggable(PlatformLogger.FINE)) {
   288                 log.fine("### Didn't find component " + aComponent + " in a cycle " + aContainer);
   288                 log.fine("### Didn't find component " + aComponent + " in a cycle " + aContainer);
   289             }
   289             }
   290             return getFirstComponent(aContainer);
   290             return getFirstComponent(aContainer);
   291         }
   291         }
   292 
   292 
   347         }
   347         }
   348 
   348 
   349         // See if the component is inside of policy provider.
   349         // See if the component is inside of policy provider.
   350         Container provider = getTopmostProvider(aContainer, aComponent);
   350         Container provider = getTopmostProvider(aContainer, aComponent);
   351         if (provider != null) {
   351         if (provider != null) {
   352             if (log.isLoggable(Level.FINE)) {
   352             if (log.isLoggable(PlatformLogger.FINE)) {
   353                 log.fine("### Asking FTP " + provider + " for component after " + aComponent);
   353                 log.fine("### Asking FTP " + provider + " for component after " + aComponent);
   354             }
   354             }
   355 
   355 
   356             // FTP knows how to find component after the given. We don't.
   356             // FTP knows how to find component after the given. We don't.
   357             FocusTraversalPolicy policy = provider.getFocusTraversalPolicy();
   357             FocusTraversalPolicy policy = provider.getFocusTraversalPolicy();
   358             Component beforeComp = policy.getComponentBefore(provider, aComponent);
   358             Component beforeComp = policy.getComponentBefore(provider, aComponent);
   359 
   359 
   360             // Null result means that we overstepped the limit of the FTP's cycle.
   360             // Null result means that we overstepped the limit of the FTP's cycle.
   361             // In that case we must quit the cycle, otherwise return the component found.
   361             // In that case we must quit the cycle, otherwise return the component found.
   362             if (beforeComp != null) {
   362             if (beforeComp != null) {
   363                 if (log.isLoggable(Level.FINE)) log.fine("### FTP returned " + beforeComp);
   363                 if (log.isLoggable(PlatformLogger.FINE)) log.fine("### FTP returned " + beforeComp);
   364                 return beforeComp;
   364                 return beforeComp;
   365             }
   365             }
   366             aComponent = provider;
   366             aComponent = provider;
   367 
   367 
   368             // If the provider is traversable it's returned.
   368             // If the provider is traversable it's returned.
   371             }
   371             }
   372         }
   372         }
   373 
   373 
   374         List<Component> cycle = getFocusTraversalCycle(aContainer);
   374         List<Component> cycle = getFocusTraversalCycle(aContainer);
   375 
   375 
   376         if (log.isLoggable(Level.FINE)) log.fine("### Cycle is " + cycle + ", component is " + aComponent);
   376         if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Cycle is " + cycle + ", component is " + aComponent);
   377 
   377 
   378         int index = getComponentIndex(cycle, aComponent);
   378         int index = getComponentIndex(cycle, aComponent);
   379 
   379 
   380         if (index < 0) {
   380         if (index < 0) {
   381             if (log.isLoggable(Level.FINE)) {
   381             if (log.isLoggable(PlatformLogger.FINE)) {
   382                 log.fine("### Didn't find component " + aComponent + " in a cycle " + aContainer);
   382                 log.fine("### Didn't find component " + aComponent + " in a cycle " + aContainer);
   383             }
   383             }
   384             return getLastComponent(aContainer);
   384             return getLastComponent(aContainer);
   385         }
   385         }
   386 
   386 
   422      * @throws IllegalArgumentException if aContainer is null
   422      * @throws IllegalArgumentException if aContainer is null
   423      */
   423      */
   424     public Component getFirstComponent(Container aContainer) {
   424     public Component getFirstComponent(Container aContainer) {
   425         List<Component> cycle;
   425         List<Component> cycle;
   426 
   426 
   427         if (log.isLoggable(Level.FINE)) log.fine("### Getting first component in " + aContainer);
   427         if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Getting first component in " + aContainer);
   428         if (aContainer == null) {
   428         if (aContainer == null) {
   429             throw new IllegalArgumentException("aContainer cannot be null");
   429             throw new IllegalArgumentException("aContainer cannot be null");
   430         }
   430         }
   431 
   431 
   432         if (this.cachedRoot == aContainer) {
   432         if (this.cachedRoot == aContainer) {
   434         } else {
   434         } else {
   435             cycle = getFocusTraversalCycle(aContainer);
   435             cycle = getFocusTraversalCycle(aContainer);
   436         }
   436         }
   437 
   437 
   438         if (cycle.size() == 0) {
   438         if (cycle.size() == 0) {
   439             if (log.isLoggable(Level.FINE)) log.fine("### Cycle is empty");
   439             if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Cycle is empty");
   440             return null;
   440             return null;
   441         }
   441         }
   442         if (log.isLoggable(Level.FINE)) log.fine("### Cycle is " + cycle);
   442         if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Cycle is " + cycle);
   443 
   443 
   444         for (Component comp : cycle) {
   444         for (Component comp : cycle) {
   445             if (accept(comp)) {
   445             if (accept(comp)) {
   446                 return comp;
   446                 return comp;
   447             } else if (comp != aContainer &&
   447             } else if (comp != aContainer &&
   464      *         or null if no suitable Component can be found
   464      *         or null if no suitable Component can be found
   465      * @throws IllegalArgumentException if aContainer is null
   465      * @throws IllegalArgumentException if aContainer is null
   466      */
   466      */
   467     public Component getLastComponent(Container aContainer) {
   467     public Component getLastComponent(Container aContainer) {
   468         List<Component> cycle;
   468         List<Component> cycle;
   469         if (log.isLoggable(Level.FINE)) log.fine("### Getting last component in " + aContainer);
   469         if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Getting last component in " + aContainer);
   470 
   470 
   471         if (aContainer == null) {
   471         if (aContainer == null) {
   472             throw new IllegalArgumentException("aContainer cannot be null");
   472             throw new IllegalArgumentException("aContainer cannot be null");
   473         }
   473         }
   474 
   474 
   477         } else {
   477         } else {
   478             cycle = getFocusTraversalCycle(aContainer);
   478             cycle = getFocusTraversalCycle(aContainer);
   479         }
   479         }
   480 
   480 
   481         if (cycle.size() == 0) {
   481         if (cycle.size() == 0) {
   482             if (log.isLoggable(Level.FINE)) log.fine("### Cycle is empty");
   482             if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Cycle is empty");
   483             return null;
   483             return null;
   484         }
   484         }
   485         if (log.isLoggable(Level.FINE)) log.fine("### Cycle is " + cycle);
   485         if (log.isLoggable(PlatformLogger.FINE)) log.fine("### Cycle is " + cycle);
   486 
   486 
   487         for (int i= cycle.size() - 1; i >= 0; i--) {
   487         for (int i= cycle.size() - 1; i >= 0; i--) {
   488             Component comp = cycle.get(i);
   488             Component comp = cycle.get(i);
   489             if (accept(comp)) {
   489             if (accept(comp)) {
   490                 return comp;
   490                 return comp;