Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.awt.ContainerOrderFocusTraversalPolicy

 1:  /* ContainerOrderFocusTraversalPolicy.java -- 
 2:  Copyright (C) 2002, 2005 Free Software Foundation, Inc.
 3: 
 4: This file is part of GNU Classpath.
 5: 
 6: GNU Classpath is free software; you can redistribute it and/or modify
 7: it under the terms of the GNU General Public License as published by
 8: the Free Software Foundation; either version 2, or (at your option)
 9: any later version.
 10: 
 11: GNU Classpath is distributed in the hope that it will be useful, but
 12: WITHOUT ANY WARRANTY; without even the implied warranty of
 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 14: General Public License for more details.
 15: 
 16: You should have received a copy of the GNU General Public License
 17: along with GNU Classpath; see the file COPYING. If not, write to the
 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 19: 02110-1301 USA.
 20: 
 21: Linking this library statically or dynamically with other modules is
 22: making a combined work based on this library. Thus, the terms and
 23: conditions of the GNU General Public License cover the whole
 24: combination.
 25: 
 26: As a special exception, the copyright holders of this library give you
 27: permission to link this library with independent modules to produce an
 28: executable, regardless of the license terms of these independent
 29: modules, and to copy and distribute the resulting executable under
 30: terms of your choice, provided that you also meet, for each linked
 31: independent module, the terms and conditions of the license of that
 32: module. An independent module is a module which is not derived from
 33: or based on this library. If you modify this library, you may extend
 34: this exception to your version of the library, but you are not
 35: obligated to do so. If you do not wish to do so, delete this
 36: exception statement from your version. */
 37: 
 38: 
 39:  package java.awt;
 40: 
 41:  import java.io.Serializable;
 42: 
 43:  /**
 44:  * ContainerOrderFocusTraversalPolicy defines a focus traversal order
 45:  * based on the order in which Components were packed in a Container.
 46:  * This policy performs a pre-order traversal of the Component
 47:  * hierarchy starting from a given focus cycle root. Portions of the
 48:  * hierarchy that are not visible and displayable are skipped.
 49:  *
 50:  * By default, this policy transfers focus down-cycle implicitly.
 51:  * That is, if a forward traversal is requested on a focus cycle root
 52:  * and the focus cycle root has focusable children, the focus will
 53:  * automatically be transfered down to the lower focus cycle.
 54:  *
 55:  * The default implementation of accept accepts only Components that
 56:  * are visible, displayable, enabled and focusable. Derived classes
 57:  * can override these acceptance criteria by overriding accept.
 58:  *
 59:  * @author Michael Koch
 60:  * @author Thomas Fitzsimmons (fitzsim@redhat.com)
 61:  * @since 1.4
 62:  */
 63:  public class ContainerOrderFocusTraversalPolicy extends FocusTraversalPolicy
 64:  implements Serializable
 65: {
 66:  /**
 67:  * Compatible to JDK 1.4+
 68:  */
 69:  static final long serialVersionUID = 486933713763926351L;
 70: 
 71:  /**
 72:  * True if implicit down cycling is enabled.
 73:  */
 74:  private boolean implicitDownCycleTraversal = true;
 75: 
 76:  /**
 77:  * Creates the <code>ContainerOrderFocusTraversalPolicy</code> object.
 78:  */
 79:  public ContainerOrderFocusTraversalPolicy ()
 80:  {
 81:  // Nothing to do here
 82:  }
 83: 
 84:  /**
 85:  * Returns the Component that should receive the focus after current.
 86:  * root must be a focus cycle root of current.
 87:  *
 88:  * @param root a focus cycle root of current
 89:  * @param current a (possibly indirect) child of root, or root itself
 90:  *
 91:  * @return the next Component in the focus traversal order for root,
 92:  * or null if no acceptable Component exists.
 93:  *
 94:  * @exception IllegalArgumentException If root is not a focus cycle
 95:  * root of current, or if either root or current is null.
 96:  */
 97:  public Component getComponentAfter (Container root, Component current)
 98:  {
 99:  if (root == null)
 100:  throw new IllegalArgumentException ("focus cycle root is null");
 101:  if (current == null)
 102:  throw new IllegalArgumentException ("current component is null");
 103: 
 104:  if (!root.isFocusCycleRoot ())
 105:  throw new IllegalArgumentException ("root is not a focus cycle root");
 106: 
 107:  Container ancestor = current.getFocusCycleRootAncestor ();
 108:  Container prevAncestor = ancestor;
 109:  while (ancestor != root)
 110:  {
 111:  ancestor = current.getFocusCycleRootAncestor ();
 112:  if (ancestor == prevAncestor)
 113:  {
 114:  // We've reached the top focus cycle root ancestor. Check
 115:  // if it is root.
 116:  if (ancestor == null)
 117:  ancestor = root;
 118:  else if (ancestor != root)
 119:  throw new IllegalArgumentException ("the given container is not"
 120:  + " a focus cycle root of the"
 121:  + " current component");
 122:  else
 123:  break;
 124:  }
 125:  prevAncestor = ancestor;
 126:  }
 127: 
 128:  // FIXME: is this the right thing to do here? It moves the context
 129:  // for traversal up one focus traversal cycle. We'll need a test
 130:  // for this.
 131:  if ((Component) root == current)
 132:  root = current.getFocusCycleRootAncestor ();
 133: 
 134:  // Check if we've reached the top of the component hierarchy. If
 135:  // so then we want to loop around to the first component in the
 136:  // focus traversal cycle.
 137:  if (current instanceof Window)
 138:  return getFirstComponent ((Container) current);
 139: 
 140:  Container parent = current.getParent ();
 141:  synchronized (parent.getTreeLock ())
 142:  {
 143:  Component[] components = parent.getComponents ();
 144:  int componentIndex = 0;
 145:  int numComponents = parent.getComponentCount ();
 146: 
 147:  // Find component's index.
 148:  for (int i = 0; i < numComponents; i++)
 149:  {
 150:  if (components[i].equals(current))
 151:  componentIndex = i;
 152:  }
 153: 
 154:  // Search forward for the next acceptable component. 
 155:  // Search through all components at least one time
 156:  // i.e. start at componentIndex + 1 --> nComponents -1 --> 0 ---> componentIndex
 157:  int i = componentIndex + 1;
 158:  int end = numComponents - 1;
 159:  Component next = getNextAvailableComponent(components, i, end);
 160:  if (next != null)
 161:  return next;
 162:  
 163:  // Now check remainder of components from 0 to componentIndex
 164:  i = 0;
 165:  end = componentIndex;
 166:  next = getNextAvailableComponent(components, i, end);
 167:  if (next != null)
 168:  return next; 
 169:  
 170:  // No focusable components after current in its Container. So go
 171:  // to the next Component after current's Container (parent).
 172:  Component result = getComponentAfter (root, parent);
 173:  return result;
 174:  }
 175:  }
 176:  
 177:  /**
 178:  * Gets the next available component in the array between the given range.
 179:  * 
 180:  * @param components - the array of components.
 181:  * @param start - where to start
 182:  * @param end - where to end
 183:  * @return next component if found
 184:  */
 185:  private Component getNextAvailableComponent(Component[] components, int start, int end)
 186:  {
 187:  while (start <= end)
 188:  {
 189:  Component c = components[start];
 190: 
 191:  if (c.visible && c.isDisplayable() && c.enabled && c.focusable)
 192:  return c;
 193: 
 194:  if (c instanceof Container)
 195:  {
 196:  Component result = getFirstComponent((Container) c);
 197: 
 198:  if (result != null && implicitDownCycleTraversal && result.visible
 199:  && result.isDisplayable() && result.enabled && result.focusable)
 200:  return result;
 201:  }
 202:  start++;
 203:  }
 204: 
 205:  return null;
 206:  }
 207: 
 208:  /**
 209:  * Gets the previous available component in the array between the given range.
 210:  * 
 211:  * @param components - the array of components.
 212:  * @param start - where to start
 213:  * @param end - where to end
 214:  * @return previous component if found
 215:  */
 216:  Component getPrevAvailableComponent(Component[] components, int start, int end)
 217:  {
 218:  while (start >= end) 
 219:  {
 220:  Component c = components[start];
 221:  if (c.visible && c.isDisplayable() && c.enabled && c.focusable)
 222:  return c;
 223: 
 224:  if (c instanceof Container)
 225:  {
 226:  Component result = getLastComponent((Container) c);
 227: 
 228:  if (result != null
 229:  && (result.visible && result.isDisplayable() && result.enabled && result.focusable))
 230:  return result;
 231:  }
 232:  start--;
 233:  }
 234:  return null;
 235:  }
 236: 
 237:  /**
 238:  * Returns the Component that should receive the focus before
 239:  * <code>current</code>. <code>root</code> must be a focus cycle root of
 240:  * current.
 241:  * 
 242:  * @param root a focus cycle root of current
 243:  * @param current a (possibly indirect) child of root, or root itself
 244:  * @return the previous Component in the focus traversal order for root, or
 245:  * null if no acceptable Component exists.
 246:  * @exception IllegalArgumentException If root is not a focus cycle root of
 247:  * current, or if either root or current is null.
 248:  */
 249:  public Component getComponentBefore (Container root, Component current)
 250:  {
 251:  if (root == null)
 252:  throw new IllegalArgumentException ("focus cycle root is null");
 253:  if (current == null)
 254:  throw new IllegalArgumentException ("current component is null");
 255: 
 256:  if (!root.isFocusCycleRoot ())
 257:  throw new IllegalArgumentException ("root is not a focus cycle root");
 258: 
 259:  Container ancestor = current.getFocusCycleRootAncestor ();
 260:  Container prevAncestor = ancestor;
 261:  while (ancestor != root)
 262:  {
 263:  ancestor = current.getFocusCycleRootAncestor ();
 264:  if (ancestor == prevAncestor)
 265:  {
 266:  // We've reached the top focus cycle root ancestor. Check
 267:  // if it is root.
 268:  if (ancestor == null)
 269:  ancestor = root;
 270:  else if (ancestor != root)
 271:  throw new IllegalArgumentException ("the given container is not"
 272:  + " a focus cycle root of the"
 273:  + " current component");
 274:  else
 275:  break;
 276:  }
 277:  prevAncestor = ancestor;
 278:  }
 279: 
 280:  // FIXME: is this the right thing to do here? It moves the context
 281:  // for traversal up one focus traversal cycle. We'll need a test
 282:  // for this.
 283:  if ((Component) root == current)
 284:  root = current.getFocusCycleRootAncestor ();
 285: 
 286:  // Check if we've reached the top of the component hierarchy. If
 287:  // so then we want to loop around to the last component in the
 288:  // focus traversal cycle.
 289:  if (current instanceof Window)
 290:  return getLastComponent ((Container) current);
 291: 
 292:  Container parent = current.getParent ();
 293: 
 294:  synchronized (parent.getTreeLock ())
 295:  {
 296:  Component[] components = parent.getComponents ();
 297:  int componentIndex = 0;
 298:  int numComponents = parent.getComponentCount ();
 299: 
 300:  // Find component's index.
 301:  for (int i = 0; i < numComponents; i++)
 302:  {
 303:  if (components[i] == current)
 304:  componentIndex = i;
 305:  }
 306: 
 307:  // Search through all components at least one time
 308:  // i.e. start at componentIndex - 1 --> 0 --> numComponents -1 ---> componentIndex
 309:  int i = componentIndex - 1;
 310:  int end = 0;
 311:  Component prev = getPrevAvailableComponent(components, i, end);
 312:  if (prev != null)
 313:  return prev;
 314:  
 315:  // Now check remainder of components
 316:  i = numComponents -1;
 317:  end = componentIndex;
 318:  prev = getPrevAvailableComponent(components, i, end);
 319:  if (prev != null)
 320:  return prev; 
 321: 
 322:  // No focusable components before current in its Container. So go
 323:  // to the previous Component before current's Container (parent).
 324:  Component result = getComponentBefore (root, parent);
 325: 
 326:  return result;
 327:  }
 328:  }
 329: 
 330:  /**
 331:  * Returns the first Component of root that should receive the focus.
 332:  *
 333:  * @param root a focus cycle root
 334:  *
 335:  * @return the first Component in the focus traversal order for
 336:  * root, or null if no acceptable Component exists.
 337:  *
 338:  * @exception IllegalArgumentException If root is null.
 339:  */
 340:  public Component getFirstComponent(Container root)
 341:  {
 342:  if (root == null)
 343:  throw new IllegalArgumentException ();
 344: 
 345:  if (!root.isVisible ()
 346:  || !root.isDisplayable ())
 347:  return null;
 348: 
 349:  if (accept(root))
 350:  return root;
 351: 
 352:  int ncomponents = root.getComponentCount();
 353:  for (int i = 0; i < ncomponents; i++)
 354:  {
 355:  Component component = root.getComponent(i);
 356:  if (component instanceof Container
 357:  && !((Container) component).isFocusCycleRoot())
 358:  {
 359:  Component first = null;
 360:  Container cont = (Container) component;
 361:  if (cont.isFocusTraversalPolicyProvider())
 362:  {
 363:  FocusTraversalPolicy childPol = cont.getFocusTraversalPolicy();
 364:  first = childPol.getFirstComponent(cont);
 365:  }
 366:  else
 367:  first = getFirstComponent(cont);
 368:  if (first != null)
 369:  return first;
 370:  }
 371:  else if (accept(component))
 372:  return component;
 373:  }
 374: 
 375:  return null;
 376:  }
 377: 
 378:  /**
 379:  * Returns the last Component of root that should receive the focus.
 380:  *
 381:  * @param root a focus cycle root
 382:  *
 383:  * @return the last Component in the focus traversal order for
 384:  * root, or null if no acceptable Component exists.
 385:  *
 386:  * @exception IllegalArgumentException If root is null.
 387:  */
 388:  public Component getLastComponent (Container root)
 389:  {
 390:  if (root == null)
 391:  throw new IllegalArgumentException ();
 392: 
 393:  if (!root.isVisible ()
 394:  || !root.isDisplayable ())
 395:  return null;
 396: 
 397:  if (root.visible && root.isDisplayable() && root.enabled
 398:  && root.focusable)
 399:  return root;
 400: 
 401:  Component[] componentArray = root.getComponents ();
 402:  
 403:  for (int i = componentArray.length - 1; i >= 0; i--)
 404:  {
 405:  Component component = componentArray [i];
 406:  
 407:  if (component.visible && component.isDisplayable() && component.enabled
 408:  && component.focusable)
 409:  return component;
 410: 
 411:  if (component instanceof Container)
 412:  {
 413:  Component result = getLastComponent ((Container) component);
 414: 
 415:  if (result != null &&
 416:  result.visible && result.isDisplayable() && result.enabled
 417:  && result.focusable)
 418:  return result;
 419:  }
 420:  }
 421: 
 422:  return null;
 423:  }
 424: 
 425:  /**
 426:  * Returns the default Component of root that should receive the focus.
 427:  *
 428:  * @param root a focus cycle root
 429:  *
 430:  * @return the default Component in the focus traversal order for
 431:  * root, or null if no acceptable Component exists.
 432:  *
 433:  * @exception IllegalArgumentException If root is null.
 434:  */
 435:  public Component getDefaultComponent (Container root)
 436:  {
 437:  return getFirstComponent (root);
 438:  }
 439: 
 440:  /**
 441:  * Set whether or not implicit down cycling is enabled. If it is,
 442:  * then initiating a forward focus traversal operation onto a focus
 443:  * cycle root, the focus will be implicitly transferred into the
 444:  * root container's focus cycle.
 445:  *
 446:  * @param value the setting for implicit down cycling
 447:  */
 448:  public void setImplicitDownCycleTraversal (boolean value)
 449:  {
 450:  implicitDownCycleTraversal = value;
 451:  }
 452: 
 453:  /**
 454:  * Check whether or not implicit down cycling is enabled. If it is,
 455:  * then initiating a forward focus traversal operation onto a focus
 456:  * cycle root, the focus will be implicitly transferred into the
 457:  * root container's focus cycle.
 458:  *
 459:  * @return true if the focus will be transferred down-cycle
 460:  * implicitly
 461:  */
 462:  public boolean getImplicitDownCycleTraversal ()
 463:  {
 464:  return implicitDownCycleTraversal;
 465:  }
 466: 
 467:  /**
 468:  * Check whether the given Component is an acceptable target for the
 469:  * keyboard input focus.
 470:  *
 471:  * @param current the Component to check
 472:  *
 473:  * @return true if current is acceptable, false otherwise
 474:  */
 475:  protected boolean accept (Component current)
 476:  {
 477:  return (current.visible
 478:  && current.isDisplayable ()
 479:  && current.enabled
 480:  && current.focusable);
 481:  }
 482: }
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

AltStyle によって変換されたページ (->オリジナル) /