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

Source for java.awt.CardLayout

 1:  /* CardLayout.java -- Card-based layout engine
 2:  Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation
 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:  import java.util.Enumeration;
 43:  import java.util.Hashtable;
 44: 
 45:  /**
 46:  * This class implements a card-based layout scheme. Each included
 47:  * component is treated as a card. Only one card can be shown at a
 48:  * time. This class includes methods for changing which card is
 49:  * shown.
 50:  *
 51:  * @author Tom Tromey (tromey@redhat.com)
 52:  * @author Aaron M. Renn (arenn@urbanophile.com)
 53:  */
 54:  public class CardLayout implements LayoutManager2, Serializable
 55: {
 56:  private static final long serialVersionUID = -4328196481005934313L;
 57: 
 58:  /**
 59:  * Initializes a new instance of <code>CardLayout</code> with horizontal
 60:  * and vertical gaps of 0.
 61:  */
 62:  public CardLayout ()
 63:  {
 64:  this (0, 0);
 65:  }
 66: 
 67:  /**
 68:  * Create a new <code>CardLayout</code> object with the specified
 69:  * horizontal and vertical gaps.
 70:  *
 71:  * @param hgap The horizontal gap
 72:  * @param vgap The vertical gap
 73:  */
 74:  public CardLayout (int hgap, int vgap)
 75:  {
 76:  this.hgap = hgap;
 77:  this.vgap = vgap;
 78:  this.tab = new Hashtable ();
 79:  }
 80: 
 81:  /**
 82:  * Add a new component to the layout. The constraint must be a
 83:  * string which is used to name the component. This string can
 84:  * later be used to refer to the particular component.
 85:  *
 86:  * @param comp The component to add
 87:  * @param constraints The name by which the component can later be called
 88:  * 
 89:  * @exception IllegalArgumentException If `constraints' is not a
 90:  * <code>String</code>
 91:  */
 92:  public void addLayoutComponent (Component comp, Object constraints)
 93:  {
 94:  if (! (constraints instanceof String))
 95:  throw new IllegalArgumentException ("Object " + constraints
 96:  + " is not a string");
 97:  addLayoutComponent ((String) constraints, comp);
 98:  }
 99: 
 100:  /**
 101:  * Add a new component to the layout. The name can be used later
 102:  * to refer to the component.
 103:  * 
 104:  * @param name The name by which the component can later be called
 105:  * @param comp The component to add
 106:  * 
 107:  * @deprecated This method is deprecated in favor of
 108:  * <code>addLayoutComponent(Component, Object)</code>.
 109:  */
 110:  public void addLayoutComponent (String name, Component comp)
 111:  {
 112:  tab.put (name, comp);
 113:  // First component added is the default component.
 114:  comp.setVisible(tab.size() == 1);
 115:  }
 116: 
 117:  /**
 118:  * Cause the first component in the container to be displayed.
 119:  *
 120:  * @param parent The parent container, not <code>null</code>.
 121:  */
 122:  public void first (Container parent)
 123:  {
 124:  gotoComponent (parent, FIRST);
 125:  }
 126: 
 127:  /**
 128:  * Return this layout manager's horizontal gap.
 129:  *
 130:  * @return the horizontal gap
 131:  */
 132:  public int getHgap ()
 133:  {
 134:  return hgap;
 135:  }
 136: 
 137:  /**
 138:  * Return this layout manager's x alignment. This method always
 139:  * returns Component.CENTER_ALIGNMENT.
 140:  * 
 141:  * @param parent Container using this layout manager instance
 142:  *
 143:  * @return the x-axis alignment
 144:  */
 145:  public float getLayoutAlignmentX (Container parent)
 146:  {
 147:  return Component.CENTER_ALIGNMENT;
 148:  }
 149: 
 150:  /**
 151:  * Returns this layout manager's y alignment. This method always
 152:  * returns Component.CENTER_ALIGNMENT.
 153:  * 
 154:  * @param parent Container using this layout manager instance
 155:  *
 156:  * @return the y-axis alignment
 157:  */
 158:  public float getLayoutAlignmentY (Container parent)
 159:  {
 160:  return Component.CENTER_ALIGNMENT;
 161:  }
 162: 
 163:  /**
 164:  * Return this layout manager's vertical gap.
 165:  *
 166:  * @return the vertical gap
 167:  */
 168:  public int getVgap ()
 169:  {
 170:  return vgap;
 171:  }
 172: 
 173:  /**
 174:  * Invalidate this layout manager's state.
 175:  */
 176:  public void invalidateLayout (Container target)
 177:  {
 178:  // Do nothing.
 179:  }
 180: 
 181:  /**
 182:  * Cause the last component in the container to be displayed.
 183:  * 
 184:  * @param parent The parent container, not <code>null</code>.
 185:  */
 186:  public void last (Container parent)
 187:  {
 188:  gotoComponent (parent, LAST);
 189:  }
 190: 
 191:  /**
 192:  * Lays out the container. This is done by resizing the child components
 193:  * to be the same size as the parent, less insets and gaps.
 194:  *
 195:  * @param parent The parent container.
 196:  */ 
 197:  public void layoutContainer (Container parent)
 198:  {
 199:  synchronized (parent.getTreeLock ())
 200:  {
 201:  int width = parent.width;
 202:  int height = parent.height;
 203: 
 204:  Insets ins = parent.getInsets ();
 205: 
 206:  int num = parent.ncomponents;
 207:  Component[] comps = parent.component;
 208: 
 209:  int x = ins.left + hgap;
 210:  int y = ins.top + vgap;
 211:  width = width - 2 * hgap - ins.left - ins.right;
 212:  height = height - 2 * vgap - ins.top - ins.bottom;
 213: 
 214:  for (int i = 0; i < num; ++i)
 215:  comps[i].setBounds (x, y, width, height);
 216:  }
 217:  }
 218: 
 219:  /**
 220:  * Get the maximum layout size of the container.
 221:  * 
 222:  * @param target The parent container
 223:  *
 224:  * @return the maximum layout size
 225:  */
 226:  public Dimension maximumLayoutSize (Container target)
 227:  {
 228:  if (target == null || target.ncomponents == 0)
 229:  return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 230:  // The JCL says that this returns Integer.MAX_VALUE for both
 231:  // dimensions. But that just seems wrong to me.
 232:  return getSize (target, MAX);
 233:  }
 234: 
 235:  /**
 236:  * Get the minimum layout size of the container.
 237:  * 
 238:  * @param target The parent container
 239:  *
 240:  * @return the minimum layout size
 241:  */
 242:  public Dimension minimumLayoutSize (Container target)
 243:  {
 244:  return getSize (target, MIN);
 245:  }
 246: 
 247:  /**
 248:  * Cause the next component in the container to be displayed. If
 249:  * this current card is the last one in the deck, the first
 250:  * component is displayed.
 251:  * 
 252:  * @param parent The parent container, not <code>null</code>.
 253:  */
 254:  public void next (Container parent)
 255:  {
 256:  gotoComponent (parent, NEXT);
 257:  }
 258: 
 259:  /**
 260:  * Get the preferred layout size of the container.
 261:  * 
 262:  * @param parent The parent container
 263:  *
 264:  * @return the preferred layout size
 265:  */
 266:  public Dimension preferredLayoutSize (Container parent)
 267:  {
 268:  return getSize (parent, PREF);
 269:  }
 270: 
 271:  /**
 272:  * Cause the previous component in the container to be displayed.
 273:  * If this current card is the first one in the deck, the last
 274:  * component is displayed.
 275:  * 
 276:  * @param parent The parent container, not <code>null</code>.
 277:  */
 278:  public void previous (Container parent)
 279:  {
 280:  gotoComponent (parent, PREV);
 281:  }
 282: 
 283:  /**
 284:  * Remove the indicated component from this layout manager.
 285:  * 
 286:  * @param comp The component to remove
 287:  */
 288:  public void removeLayoutComponent (Component comp)
 289:  {
 290:  Enumeration e = tab.keys ();
 291:  while (e.hasMoreElements ())
 292:  {
 293:  Object key = e.nextElement ();
 294:  if (tab.get (key) == comp)
 295:  {
 296:  tab.remove (key);
 297:  Container parent = comp.getParent();
 298:  next(parent);
 299:  break;
 300:  }
 301:  }
 302:  }
 303: 
 304:  /**
 305:  * Set this layout manager's horizontal gap.
 306:  * 
 307:  * @param hgap The new gap
 308:  */
 309:  public void setHgap (int hgap)
 310:  {
 311:  this.hgap = hgap;
 312:  }
 313: 
 314:  /**
 315:  * Set this layout manager's vertical gap.
 316:  * 
 317:  * @param vgap The new gap
 318:  */
 319:  public void setVgap (int vgap)
 320:  {
 321:  this.vgap = vgap;
 322:  }
 323: 
 324:  /**
 325:  * Cause the named component to be shown. If the component name is
 326:  * unknown or <code>null</code>, this method does nothing.
 327:  * 
 328:  * @param parent The parent container, not <code>null</code>.
 329:  * @param name The name of the component to show 
 330:  */
 331:  public void show (Container parent, String name)
 332:  {
 333:  if (name == null)
 334:  return;
 335:  
 336:  if (parent.getLayout() != this)
 337:  throw new IllegalArgumentException("parent's layout is not this CardLayout");
 338:  
 339:  Object target = tab.get (name);
 340:  if (target != null)
 341:  {
 342:  int num = parent.ncomponents;
 343:  // This is more efficient than calling getComponents().
 344:  Component[] comps = parent.component;
 345:  for (int i = 0; i < num; ++i)
 346:  {
 347:  if (comps[i].isVisible())
 348:  {
 349:  if (target == comps[i])
 350:  return;
 351:  comps[i].setVisible (false);
 352:  }
 353:  }
 354:  ((Component) target).setVisible (true);
 355:  parent.validate();
 356:  }
 357:  }
 358: 
 359:  /**
 360:  * Returns a string representation of this layout manager.
 361:  *
 362:  * @return A string representation of this object.
 363:  */
 364:  public String toString ()
 365:  {
 366:  return getClass ().getName () + "[hgap=" + hgap + ",vgap=" + vgap + "]";
 367:  }
 368: 
 369:  /**
 370:  * This implements first(), last(), next(), and previous().
 371:  * 
 372:  * @param parent The parent container
 373:  * @param what The type of goto: FIRST, LAST, NEXT or PREV
 374:  * 
 375:  * @throws IllegalArgumentException if parent has not this 
 376:  * CardLayout set as its layout.
 377:  */
 378:  private void gotoComponent (Container parent, int what)
 379:  {
 380:  if (parent.getLayout() != this)
 381:  throw new IllegalArgumentException("parent's layout is not this CardLayout");
 382:  
 383:  synchronized (parent.getTreeLock ())
 384:  {
 385:  int num = parent.ncomponents;
 386:  // This is more efficient than calling getComponents().
 387:  Component[] comps = parent.component;
 388: 
 389:  if (num == 1)
 390:  {
 391:  comps[0].setVisible(true);
 392:  return;
 393:  }
 394: 
 395:  int choice = -1;
 396: 
 397:  if (what == FIRST)
 398:  choice = 0;
 399:  else if (what == LAST)
 400:  choice = num - 1;
 401: 
 402:  for (int i = 0; i < num; ++i)
 403:  {
 404:  if (comps[i].isVisible ())
 405:  {
 406:  if (choice == i)
 407:  {
 408:  // Do nothing if we're already looking at the right
 409:  // component.
 410:  return;
 411:  }
 412:  else if (what == PREV)
 413:  {
 414:  choice = i - 1;
 415:  if (choice < 0)
 416:  choice = num - 1;
 417:  }
 418:  else if (what == NEXT)
 419:  {
 420:  choice = i + 1;
 421:  if (choice == num)
 422:  choice = 0;
 423:  }
 424:  comps[i].setVisible (false);
 425:  
 426:  if (choice >= 0)
 427:  break;
 428:  } else 
 429:  {
 430:  comps[i].setVisible(true);
 431:  }
 432:  }
 433: 
 434:  if (choice >= 0 && choice < num)
 435:  comps[choice].setVisible (true);
 436:  }
 437:  }
 438: 
 439:  // Compute the size according to WHAT.
 440:  private Dimension getSize (Container parent, int what)
 441:  {
 442:  synchronized (parent.getTreeLock ())
 443:  {
 444:  int w = 0, h = 0, num = parent.ncomponents;
 445:  Component[] comps = parent.component;
 446: 
 447:  for (int i = 0; i < num; ++i)
 448:  {
 449:  Dimension d;
 450: 
 451:  if (what == MIN)
 452:  d = comps[i].getMinimumSize ();
 453:  else if (what == MAX)
 454:  d = comps[i].getMaximumSize ();
 455:  else
 456:  d = comps[i].getPreferredSize ();
 457: 
 458:  w = Math.max (d.width, w);
 459:  h = Math.max (d.height, h);
 460:  }
 461: 
 462:  Insets i = parent.getInsets ();
 463:  w += 2 * hgap + i.right + i.left;
 464:  h += 2 * vgap + i.bottom + i.top;
 465: 
 466:  // Handle overflow.
 467:  if (w < 0)
 468:  w = Integer.MAX_VALUE;
 469:  if (h < 0)
 470:  h = Integer.MAX_VALUE;
 471: 
 472:  return new Dimension (w, h);
 473:  }
 474:  }
 475: 
 476:  /**
 477:  * @serial Horizontal gap value.
 478:  */
 479:  private int hgap;
 480: 
 481:  /**
 482:  * @serial Vertical gap value.
 483:  */
 484:  private int vgap;
 485: 
 486:  /**
 487:  * @serial Table of named components.
 488:  */
 489:  private Hashtable tab;
 490: 
 491:  // These constants are used by the private gotoComponent method.
 492:  private static final int FIRST = 0;
 493:  private static final int LAST = 1;
 494:  private static final int NEXT = 2;
 495:  private static final int PREV = 3;
 496: 
 497:  // These constants are used by the private getSize method.
 498:  private static final int MIN = 0;
 499:  private static final int MAX = 1;
 500:  private static final int PREF = 2;
 501: }
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

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