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

Source for javax.swing.plaf.basic.BasicSplitPaneUI

 1:  /* BasicSplitPaneUI.java --
 2:  Copyright (C) 2003, 2004, 2005, 2006, 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 javax.swing.plaf.basic;
 40: 
 41:  import java.awt.Canvas;
 42:  import java.awt.Color;
 43:  import java.awt.Component;
 44:  import java.awt.Container;
 45:  import java.awt.Dimension;
 46:  import java.awt.Graphics;
 47:  import java.awt.Insets;
 48:  import java.awt.LayoutManager2;
 49:  import java.awt.Point;
 50:  import java.awt.event.ActionEvent;
 51:  import java.awt.event.ActionListener;
 52:  import java.awt.event.FocusAdapter;
 53:  import java.awt.event.FocusEvent;
 54:  import java.awt.event.FocusListener;
 55:  import java.beans.PropertyChangeEvent;
 56:  import java.beans.PropertyChangeListener;
 57: 
 58:  import javax.swing.AbstractAction;
 59:  import javax.swing.ActionMap;
 60:  import javax.swing.InputMap;
 61:  import javax.swing.JComponent;
 62:  import javax.swing.JSlider;
 63:  import javax.swing.JSplitPane;
 64:  import javax.swing.KeyStroke;
 65:  import javax.swing.LookAndFeel;
 66:  import javax.swing.SwingConstants;
 67:  import javax.swing.SwingUtilities;
 68:  import javax.swing.UIManager;
 69:  import javax.swing.plaf.ActionMapUIResource;
 70:  import javax.swing.plaf.ComponentUI;
 71:  import javax.swing.plaf.SplitPaneUI;
 72:  import javax.swing.plaf.UIResource;
 73: 
 74:  /**
 75:  * This is the Basic Look and Feel implementation of the SplitPaneUI class.
 76:  */
 77:  public class BasicSplitPaneUI extends SplitPaneUI
 78: {
 79:  /**
 80:  * This Layout Manager controls the position and size of the components when
 81:  * the JSplitPane's orientation is HORIZONTAL_SPLIT.
 82:  *
 83:  * @specnote Apparently this class was intended to be protected,
 84:  * but was made public by a compiler bug and is now
 85:  * public for compatibility.
 86:  */
 87:  public class BasicHorizontalLayoutManager implements LayoutManager2
 88:  {
 89:  // 3 components at a time.
 90:  // LEFT/TOP = 0
 91:  // RIGHT/BOTTOM = 1
 92:  // DIVIDER = 2 
 93: 
 94:  /**
 95:  * This array contains the components in the JSplitPane. The left/top
 96:  * component is at index 0, the right/bottom is at 1, and the divider is
 97:  * at 2.
 98:  */
 99:  protected Component[] components = new Component[3];
 100: 
 101:  // These are the _current_ widths of the associated component.
 102: 
 103:  /**
 104:  * This array contains the current width (for HORIZONTAL_SPLIT) or height
 105:  * (for VERTICAL_SPLIT) of the components. The indices are the same as
 106:  * for components.
 107:  */
 108:  protected int[] sizes = new int[3];
 109: 
 110:  /**
 111:  * This is used to determine if we are vertical or horizontal layout.
 112:  * In the JDK, the BasicVerticalLayoutManager seems to have no more
 113:  * methods implemented (as of JDK5), so we keep this state here.
 114:  */
 115:  private int axis;
 116: 
 117:  /**
 118:  * Creates a new instance. This is package private because the reference
 119:  * implementation has no public constructor either. Still, we need to
 120:  * call it from BasicVerticalLayoutManager.
 121:  */
 122:  BasicHorizontalLayoutManager()
 123:  {
 124:  this(SwingConstants.HORIZONTAL);
 125:  }
 126: 
 127:  /**
 128:  * Creates a new instance for a specified axis. This is provided for
 129:  * compatibility, since the BasicVerticalLayoutManager seems to have
 130:  * no more implementation in the RI, according to the specs. So
 131:  * we handle all the axis specific stuff here.
 132:  *
 133:  * @param a the axis, either SwingConstants#HORIZONTAL,
 134:  * or SwingConstants#VERTICAL
 135:  */
 136:  BasicHorizontalLayoutManager(int a)
 137:  {
 138:  axis = a;
 139:  }
 140: 
 141:  /**
 142:  * This method adds the component given to the JSplitPane. The position of
 143:  * the component is given by the constraints object.
 144:  *
 145:  * @param comp The Component to add.
 146:  * @param constraints The constraints that bind the object.
 147:  */
 148:  public void addLayoutComponent(Component comp, Object constraints)
 149:  {
 150:  addLayoutComponent((String) constraints, comp);
 151:  }
 152: 
 153:  /**
 154:  * This method is called to add a Component to the JSplitPane. The
 155:  * placement string determines where the Component will be placed. The
 156:  * string should be one of LEFT, RIGHT, TOP, BOTTOM or null (signals that
 157:  * the component is the divider).
 158:  *
 159:  * @param place The placement of the Component.
 160:  * @param component The Component to add.
 161:  *
 162:  * @throws IllegalArgumentException DOCUMENT ME!
 163:  */
 164:  public void addLayoutComponent(String place, Component component)
 165:  {
 166:  int i = 0;
 167:  if (place == null)
 168:  i = 2;
 169:  else if (place.equals(JSplitPane.TOP) || place.equals(JSplitPane.LEFT))
 170:  i = 0;
 171:  else if (place.equals(JSplitPane.BOTTOM)
 172:  || place.equals(JSplitPane.RIGHT))
 173:  i = 1;
 174:  else
 175:  throw new IllegalArgumentException("Illegal placement in JSplitPane");
 176:  components[i] = component;
 177:  resetSizeAt(i);
 178:  splitPane.revalidate();
 179:  splitPane.repaint();
 180:  }
 181: 
 182:  /**
 183:  * This method returns the width of the JSplitPane minus the insets.
 184:  *
 185:  * @param containerSize The Dimensions of the JSplitPane.
 186:  * @param insets The Insets of the JSplitPane.
 187:  *
 188:  * @return The width of the JSplitPane minus the insets.
 189:  */
 190:  protected int getAvailableSize(Dimension containerSize, Insets insets)
 191:  {
 192:  int size;
 193:  if (axis == SwingConstants.HORIZONTAL)
 194:  size = containerSize.width - insets.left - insets.right;
 195:  else
 196:  size = containerSize.height - insets.top - insets.bottom;
 197:  return size;
 198:  }
 199: 
 200:  /**
 201:  * This method returns the given insets left value. If the given inset is
 202:  * null, then 0 is returned.
 203:  *
 204:  * @param insets The Insets to use with the JSplitPane.
 205:  *
 206:  * @return The inset's left value.
 207:  */
 208:  protected int getInitialLocation(Insets insets)
 209:  {
 210:  int loc = 0;
 211:  if (insets != null)
 212:  {
 213:  if (axis == SwingConstants.HORIZONTAL)
 214:  loc = insets.left;
 215:  else
 216:  loc = insets.top;
 217:  }
 218:  return loc;
 219:  }
 220: 
 221:  /**
 222:  * This specifies how a component is aligned with respect to other
 223:  * components in the x fdirection.
 224:  *
 225:  * @param target The container.
 226:  *
 227:  * @return The component's alignment.
 228:  */
 229:  public float getLayoutAlignmentX(Container target)
 230:  {
 231:  return 0.0f;
 232:  }
 233: 
 234:  /**
 235:  * This specifies how a component is aligned with respect to other
 236:  * components in the y direction.
 237:  *
 238:  * @param target The container.
 239:  *
 240:  * @return The component's alignment.
 241:  */
 242:  public float getLayoutAlignmentY(Container target)
 243:  {
 244:  return 0.0f;
 245:  }
 246: 
 247:  /**
 248:  * This method returns the preferred width of the component.
 249:  *
 250:  * @param c The component to measure.
 251:  *
 252:  * @return The preferred width of the component.
 253:  */
 254:  protected int getPreferredSizeOfComponent(Component c)
 255:  {
 256:  int size = 0;
 257:  Dimension dims = c.getPreferredSize();
 258:  if (axis == SwingConstants.HORIZONTAL)
 259:  {
 260:  if (dims != null)
 261:  size = dims.width;
 262:  }
 263:  else
 264:  {
 265:  if (dims != null)
 266:  size = dims.height;
 267:  }
 268:  return size;
 269:  }
 270: 
 271:  /**
 272:  * This method returns the current width of the component.
 273:  *
 274:  * @param c The component to measure.
 275:  *
 276:  * @return The width of the component.
 277:  */
 278:  protected int getSizeOfComponent(Component c)
 279:  {
 280:  int size;
 281:  if (axis == SwingConstants.HORIZONTAL)
 282:  size = c.getHeight();
 283:  else
 284:  size = c.getWidth();
 285:  return size;
 286:  }
 287: 
 288:  /**
 289:  * This method returns the sizes array.
 290:  *
 291:  * @return The sizes array.
 292:  */
 293:  protected int[] getSizes()
 294:  {
 295:  return sizes;
 296:  }
 297: 
 298:  /**
 299:  * This method invalidates the layout. It does nothing.
 300:  *
 301:  * @param c The container to invalidate.
 302:  */
 303:  public void invalidateLayout(Container c)
 304:  {
 305:  // DO NOTHING
 306:  }
 307: 
 308:  /**
 309:  * This method lays out the components in the container.
 310:  *
 311:  * @param container The container to lay out.
 312:  */
 313:  public void layoutContainer(Container container)
 314:  {
 315:  if (container instanceof JSplitPane)
 316:  {
 317:  JSplitPane split = (JSplitPane) container;
 318:  distributeExtraSpace();
 319:  Insets insets = split.getInsets();
 320:  Dimension dims = split.getSize();
 321:  int loc = getInitialLocation(insets);
 322:  int available = getAvailableSize(dims, insets);
 323:  sizes[0] = split.getDividerLocation();
 324:  sizes[1] = available - sizes[0] - sizes[2];
 325: 
 326:  // According to a Mauve test we only honour the minimum
 327:  // size of the components, when the dividerLocation hasn't
 328:  // been excplicitly set.
 329:  if (! dividerLocationSet)
 330:  {
 331:  sizes[0] = Math.max(sizes[0], minimumSizeOfComponent(0));
 332:  sizes[1] = Math.max(sizes[1], minimumSizeOfComponent(1));
 333:  }
 334:  // The size of the divider won't change.
 335: 
 336:  // Layout component#1.
 337:  setComponentToSize(components[0], sizes[0], loc, insets, dims);
 338:  // Layout divider.
 339:  loc += sizes[0];
 340:  setComponentToSize(components[2], sizes[2], loc, insets, dims);
 341:  // Layout component#2. 
 342:  loc += sizes[2];
 343:  setComponentToSize(components[1], sizes[1], loc, insets, dims);
 344:  }
 345:  }
 346: 
 347:  /**
 348:  * This method returns the maximum size for the container given the
 349:  * components. It returns a new Dimension object that has width and
 350:  * height equal to Integer.MAX_VALUE.
 351:  *
 352:  * @param target The container to measure.
 353:  *
 354:  * @return The maximum size.
 355:  */
 356:  public Dimension maximumLayoutSize(Container target)
 357:  {
 358:  return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 359:  }
 360: 
 361:  /**
 362:  * This method returns the container's minimum size. The minimum width is
 363:  * the sum of all the component's minimum widths. The minimum height is
 364:  * the maximum of all the components' minimum heights.
 365:  *
 366:  * @param target The container to measure.
 367:  *
 368:  * @return The minimum size.
 369:  */
 370:  public Dimension minimumLayoutSize(Container target)
 371:  {
 372:  Dimension dim = new Dimension();
 373:  if (target instanceof JSplitPane)
 374:  {
 375:  int primary = 0;
 376:  int secondary = 0;
 377:  for (int i = 0; i < components.length; i++)
 378:  {
 379:  if (components[i] != null)
 380:  {
 381:  Dimension dims = components[i].getMinimumSize();
 382:  primary += axis == SwingConstants.HORIZONTAL ? dims.width
 383:  : dims.height;
 384:  int sec = axis == SwingConstants.HORIZONTAL ? dims.height
 385:  : dims.width;
 386:  secondary = Math.max(sec, secondary);
 387:  }
 388:  }
 389:  int width = axis == SwingConstants.HORIZONTAL ? primary : secondary;
 390:  int height = axis == SwingConstants.VERTICAL ? secondary : primary;
 391: 
 392:  Insets i = splitPane.getInsets();
 393:  dim.setSize(width + i.left + i.right, height + i.top + i.bottom);
 394:  }
 395:  return dim;
 396:  }
 397: 
 398:  /**
 399:  * This method returns the container's preferred size. The preferred width
 400:  * is the sum of all the component's preferred widths. The preferred
 401:  * height is the maximum of all the components' preferred heights.
 402:  *
 403:  * @param target The container to measure.
 404:  *
 405:  * @return The preferred size.
 406:  */
 407:  public Dimension preferredLayoutSize(Container target)
 408:  {
 409:  Dimension dim = new Dimension();
 410:  if (target instanceof JSplitPane)
 411:  {
 412:  int primary = 0;
 413:  int secondary = 0;
 414:  for (int i = 0; i < components.length; i++)
 415:  {
 416:  if (components[i] != null)
 417:  {
 418:  Dimension dims = components[i].getPreferredSize();
 419:  primary += axis == SwingConstants.HORIZONTAL ? dims.width
 420:  : dims.height;
 421:  int sec = axis == SwingConstants.HORIZONTAL ? dims.height
 422:  : dims.width;
 423:  secondary = Math.max(sec, secondary);
 424:  }
 425:  }
 426:  int width = axis == SwingConstants.HORIZONTAL ? primary : secondary;
 427:  int height = axis == SwingConstants.VERTICAL ? secondary : primary;
 428: 
 429:  Insets i = splitPane.getInsets();
 430:  dim.setSize(width + i.left + i.right, height + i.top + i.bottom);
 431:  }
 432:  return dim;
 433:  }
 434: 
 435:  /**
 436:  * This method removes the component from the layout.
 437:  *
 438:  * @param component The component to remove from the layout.
 439:  */
 440:  public void removeLayoutComponent(Component component)
 441:  {
 442:  for (int i = 0; i < components.length; i++)
 443:  {
 444:  if (component == components[i])
 445:  {
 446:  components[i] = null;
 447:  sizes[i] = 0;
 448:  }
 449:  }
 450:  }
 451: 
 452:  /**
 453:  * This method resets the size of Component to the preferred size.
 454:  *
 455:  * @param index The index of the component to reset.
 456:  */
 457:  protected void resetSizeAt(int index)
 458:  {
 459:  if (components[index] != null)
 460:  sizes[index] = getPreferredSizeOfComponent(components[index]);
 461:  }
 462: 
 463:  /**
 464:  * This method resets the sizes of all the components.
 465:  */
 466:  public void resetToPreferredSizes()
 467:  {
 468:  for (int i = 0; i < components.length; i++)
 469:  resetSizeAt(i);
 470:  }
 471: 
 472:  /**
 473:  * This methods sets the bounds of the given component. The width is the
 474:  * size. The height is the container size minus the top and bottom
 475:  * inset. The x coordinate is the location given. The y coordinate is
 476:  * the top inset.
 477:  *
 478:  * @param c The component to set.
 479:  * @param size The width of the component.
 480:  * @param location The x coordinate.
 481:  * @param insets The insets to use.
 482:  * @param containerSize The height of the container.
 483:  */
 484:  protected void setComponentToSize(Component c, int size, int location,
 485:  Insets insets, Dimension containerSize)
 486:  { 
 487:  if (insets != null)
 488:  {
 489:  if (axis == SwingConstants.HORIZONTAL)
 490:  c.setBounds(location, insets.top, size,
 491:  containerSize.height - insets.top - insets.bottom);
 492:  else
 493:  c.setBounds(insets.left, location,
 494:  containerSize.width - insets.left - insets.right,
 495:  size);
 496:  }
 497:  else
 498:  {
 499:  if (axis == SwingConstants.HORIZONTAL)
 500:  c.setBounds(location, 0, size, containerSize.height);
 501:  else
 502:  c.setBounds(0, location, containerSize.width, size);
 503:  }
 504:  }
 505: 
 506:  /**
 507:  * This method stores the given int array as the new sizes array.
 508:  *
 509:  * @param newSizes The array to use as sizes.
 510:  */
 511:  protected void setSizes(int[] newSizes)
 512:  {
 513:  sizes = newSizes;
 514:  }
 515: 
 516:  /**
 517:  * This method determines the size of each component. It should be called
 518:  * when a new Layout Manager is created for an existing JSplitPane.
 519:  */
 520:  protected void updateComponents()
 521:  {
 522:  Component left = splitPane.getLeftComponent();
 523:  Component right = splitPane.getRightComponent();
 524: 
 525:  if (left != null)
 526:  {
 527:  components[0] = left;
 528:  resetSizeAt(0);
 529:  }
 530:  if (right != null)
 531:  {
 532:  components[1] = right;
 533:  resetSizeAt(1);
 534:  }
 535:  components[2] = divider;
 536:  }
 537: 
 538:  /**
 539:  * This method resizes the left and right components to fit inside the
 540:  * JSplitPane when there is extra space.
 541:  */
 542:  void distributeExtraSpace()
 543:  {
 544:  // FIXME: This needs to be reimplemented correctly.
 545:  }
 546: 
 547:  /**
 548:  * This method returns the minimum width of the component at the given
 549:  * index.
 550:  *
 551:  * @param index The index to check.
 552:  *
 553:  * @return The minimum width.
 554:  */
 555:  int minimumSizeOfComponent(int index)
 556:  {
 557:  Dimension dims = components[index].getMinimumSize();
 558:  int size = 0;
 559:  if (dims != null)
 560:  if (axis == SwingConstants.HORIZONTAL)
 561:  size = dims.width;
 562:  else
 563:  size = dims.height;
 564:  return size;
 565:  }
 566:  } //end BasicHorizontalLayoutManager
 567: 
 568:  /**
 569:  * This class is the Layout Manager for the JSplitPane when the orientation
 570:  * is VERTICAL_SPLIT.
 571:  *
 572:  * @specnote Apparently this class was intended to be protected,
 573:  * but was made public by a compiler bug and is now
 574:  * public for compatibility.
 575:  */
 576:  public class BasicVerticalLayoutManager
 577:  extends BasicHorizontalLayoutManager
 578:  {
 579:  /**
 580:  * Creates a new instance.
 581:  */
 582:  public BasicVerticalLayoutManager()
 583:  {
 584:  super(SwingConstants.VERTICAL);
 585:  }
 586:  }
 587: 
 588:  /**
 589:  * This class handles FocusEvents from the JComponent.
 590:  *
 591:  * @specnote Apparently this class was intended to be protected,
 592:  * but was made public by a compiler bug and is now
 593:  * public for compatibility.
 594:  */
 595:  public class FocusHandler extends FocusAdapter
 596:  {
 597:  /**
 598:  * This method is called when the JSplitPane gains focus.
 599:  *
 600:  * @param ev The FocusEvent.
 601:  */
 602:  public void focusGained(FocusEvent ev)
 603:  {
 604:  // repaint the divider because its background color may change due to
 605:  // the focus state...
 606:  divider.repaint();
 607:  }
 608: 
 609:  /**
 610:  * This method is called when the JSplitPane loses focus.
 611:  *
 612:  * @param ev The FocusEvent.
 613:  */
 614:  public void focusLost(FocusEvent ev)
 615:  {
 616:  // repaint the divider because its background color may change due to
 617:  // the focus state...
 618:  divider.repaint();
 619:  }
 620:  }
 621: 
 622:  /**
 623:  * This is a deprecated class. It is supposed to be used for handling down
 624:  * and right key presses.
 625:  *
 626:  * @specnote Apparently this class was intended to be protected,
 627:  * but was made public by a compiler bug and is now
 628:  * public for compatibility.
 629:  */
 630:  public class KeyboardDownRightHandler implements ActionListener
 631:  {
 632:  /**
 633:  * This method is called when the down or right keys are pressed.
 634:  *
 635:  * @param ev The ActionEvent
 636:  */
 637:  public void actionPerformed(ActionEvent ev)
 638:  {
 639:  // FIXME: implement.
 640:  }
 641:  }
 642: 
 643:  /**
 644:  * This is a deprecated class. It is supposed to be used for handling end
 645:  * key presses.
 646:  *
 647:  * @specnote Apparently this class was intended to be protected,
 648:  * but was made public by a compiler bug and is now
 649:  * public for compatibility.
 650:  */
 651:  public class KeyboardEndHandler implements ActionListener
 652:  {
 653:  /**
 654:  * This method is called when the end key is pressed.
 655:  *
 656:  * @param ev The ActionEvent.
 657:  */
 658:  public void actionPerformed(ActionEvent ev)
 659:  {
 660:  // FIXME: implement.
 661:  }
 662:  }
 663: 
 664:  /**
 665:  * This is a deprecated class. It is supposed to be used for handling home
 666:  * key presses.
 667:  *
 668:  * @specnote Apparently this class was intended to be protected,
 669:  * but was made public by a compiler bug and is now
 670:  * public for compatibility.
 671:  */
 672:  public class KeyboardHomeHandler implements ActionListener
 673:  {
 674:  /**
 675:  * This method is called when the home key is pressed.
 676:  *
 677:  * @param ev The ActionEvent.
 678:  */
 679:  public void actionPerformed(ActionEvent ev)
 680:  {
 681:  // FIXME: implement.
 682:  }
 683:  }
 684: 
 685:  /**
 686:  * This is a deprecated class. It is supposed to be used for handling resize
 687:  * toggles.
 688:  *
 689:  * @specnote Apparently this class was intended to be protected,
 690:  * but was made public by a compiler bug and is now
 691:  * public for compatibility.
 692:  */
 693:  public class KeyboardResizeToggleHandler implements ActionListener
 694:  {
 695:  /**
 696:  * This method is called when a resize is toggled.
 697:  *
 698:  * @param ev The ActionEvent.
 699:  */
 700:  public void actionPerformed(ActionEvent ev)
 701:  {
 702:  // FIXME: implement.
 703:  }
 704:  }
 705: 
 706:  /**
 707:  * This is a deprecated class. It is supposed to be used for handler up and
 708:  * left key presses.
 709:  *
 710:  * @specnote Apparently this class was intended to be protected,
 711:  * but was made public by a compiler bug and is now
 712:  * public for compatibility.
 713:  */
 714:  public class KeyboardUpLeftHandler implements ActionListener
 715:  {
 716:  /**
 717:  * This method is called when the left or up keys are pressed.
 718:  *
 719:  * @param ev The ActionEvent.
 720:  */
 721:  public void actionPerformed(ActionEvent ev)
 722:  {
 723:  // FIXME: implement.
 724:  }
 725:  }
 726: 
 727:  /**
 728:  * This helper class handles PropertyChangeEvents from the JSplitPane. When
 729:  * a property changes, this will update the UI accordingly.
 730:  *
 731:  * @specnote Apparently this class was intended to be protected,
 732:  * but was made public by a compiler bug and is now
 733:  * public for compatibility.
 734:  */
 735:  public class PropertyHandler implements PropertyChangeListener
 736:  {
 737:  /**
 738:  * This method is called whenever one of the JSplitPane's properties
 739:  * change.
 740:  *
 741:  * @param e DOCUMENT ME!
 742:  */
 743:  public void propertyChange(PropertyChangeEvent e)
 744:  {
 745:  if (e.getPropertyName().equals(JSplitPane.DIVIDER_SIZE_PROPERTY))
 746:  {
 747:  int newSize = splitPane.getDividerSize();
 748:  int[] tmpSizes = layoutManager.getSizes();
 749:  dividerSize = tmpSizes[2];
 750:  int newSpace = newSize - tmpSizes[2];
 751:  tmpSizes[2] = newSize;
 752: 
 753:  tmpSizes[0] += newSpace / 2;
 754:  tmpSizes[1] += newSpace / 2;
 755:  
 756:  layoutManager.setSizes(tmpSizes);
 757:  }
 758:  else if (e.getPropertyName().equals(JSplitPane.ORIENTATION_PROPERTY))
 759:  {
 760:  int max = layoutManager.getAvailableSize(splitPane.getSize(),
 761:  splitPane.getInsets());
 762:  int dividerLoc = getDividerLocation(splitPane);
 763:  double prop = ((double) dividerLoc) / max;
 764: 
 765:  resetLayoutManager();
 766:  if (prop <= 1 && prop >= 0)
 767:  splitPane.setDividerLocation(prop);
 768:  }
 769:  // Don't have to deal with continuous_layout - only
 770:  // necessary in dragging modes (and it's checked
 771:  // every time you drag there)
 772:  // Don't have to deal with resize_weight (as there
 773:  // will be no extra space associated with this
 774:  // event - the changes to the weighting will
 775:  // be taken into account the next time the
 776:  // sizes change.)
 777:  // Don't have to deal with divider_location
 778:  // The method in JSplitPane calls our setDividerLocation
 779:  // so we'll know about those anyway.
 780:  // Don't have to deal with last_divider_location
 781:  // Although I'm not sure why, it doesn't seem to
 782:  // have any effect on Sun's JSplitPane.
 783:  // one_touch_expandable changes are dealt with
 784:  // by our divider.
 785:  }
 786:  }
 787: 
 788:  /** The location of the divider when dragging began. */
 789:  protected int beginDragDividerLocation;
 790: 
 791:  /** The size of the divider while dragging. */
 792:  protected int dividerSize;
 793: 
 794:  /** The location where the last drag location ended. */
 795:  transient int lastDragLocation = -1;
 796: 
 797:  /** The distance the divider is moved when moved by keyboard actions. */
 798:  // Sun defines this as 3
 799:  protected static int KEYBOARD_DIVIDER_MOVE_OFFSET = 3;
 800: 
 801:  /** The divider that divides this JSplitPane. */
 802:  protected BasicSplitPaneDivider divider;
 803: 
 804:  /** The listener that listens for PropertyChangeEvents from the JSplitPane. */
 805:  protected PropertyChangeListener propertyChangeListener;
 806: 
 807:  /** The JSplitPane's focus handler. */
 808:  protected FocusListener focusListener;
 809: 
 810:  /** @deprecated The handler for down and right key presses. */
 811:  protected ActionListener keyboardDownRightListener;
 812: 
 813:  /** @deprecated The handler for end key presses. */
 814:  protected ActionListener keyboardEndListener;
 815: 
 816:  /** @deprecated The handler for home key presses. */
 817:  protected ActionListener keyboardHomeListener;
 818: 
 819:  /** @deprecated The handler for toggling resizes. */
 820:  protected ActionListener keyboardResizeToggleListener;
 821: 
 822:  /** @deprecated The handler for up and left key presses. */
 823:  protected ActionListener keyboardUpLeftListener;
 824: 
 825:  /** The JSplitPane's current layout manager. */
 826:  protected BasicHorizontalLayoutManager layoutManager;
 827: 
 828:  /** @deprecated The divider resize toggle key. */
 829:  protected KeyStroke dividerResizeToggleKey;
 830: 
 831:  /** @deprecated The down key. */
 832:  protected KeyStroke downKey;
 833: 
 834:  /** @deprecated The end key. */
 835:  protected KeyStroke endKey;
 836: 
 837:  /** @deprecated The home key. */
 838:  protected KeyStroke homeKey;
 839: 
 840:  /** @deprecated The left key. */
 841:  protected KeyStroke leftKey;
 842: 
 843:  /** @deprecated The right key. */
 844:  protected KeyStroke rightKey;
 845: 
 846:  /** @deprecated The up key. */
 847:  protected KeyStroke upKey;
 848: 
 849:  /** Set to true when dragging heavy weight components. */
 850:  protected boolean draggingHW;
 851: 
 852:  /**
 853:  * The constraints object used when adding the non-continuous divider to the
 854:  * JSplitPane.
 855:  */
 856:  protected static final String NON_CONTINUOUS_DIVIDER
 857:  = "nonContinuousDivider";
 858: 
 859:  /** The dark divider used when dragging in non-continuous layout mode. */
 860:  protected Component nonContinuousLayoutDivider;
 861: 
 862:  /** The JSplitPane that this UI draws. */
 863:  protected JSplitPane splitPane;
 864: 
 865:  /**
 866:  * True, when setDividerLocation() has been called at least
 867:  * once on the JSplitPane, false otherwise.
 868:  *
 869:  * This is package private to avoid a synthetic accessor method.
 870:  */
 871:  boolean dividerLocationSet;
 872: 
 873:  /**
 874:  * Creates a new BasicSplitPaneUI object.
 875:  */
 876:  public BasicSplitPaneUI()
 877:  {
 878:  // Nothing to do here.
 879:  }
 880: 
 881:  /**
 882:  * This method creates a new BasicSplitPaneUI for the given JComponent.
 883:  *
 884:  * @param x The JComponent to create a UI for.
 885:  *
 886:  * @return A new BasicSplitPaneUI.
 887:  */
 888:  public static ComponentUI createUI(JComponent x)
 889:  {
 890:  return new BasicSplitPaneUI();
 891:  }
 892: 
 893:  /**
 894:  * This method installs the BasicSplitPaneUI for the given JComponent.
 895:  *
 896:  * @param c The JComponent to install the UI for.
 897:  */
 898:  public void installUI(JComponent c)
 899:  {
 900:  if (c instanceof JSplitPane)
 901:  {
 902:  splitPane = (JSplitPane) c;
 903:  dividerLocationSet = false;
 904:  installDefaults();
 905:  installListeners();
 906:  installKeyboardActions();
 907:  }
 908:  }
 909: 
 910:  /**
 911:  * This method uninstalls the BasicSplitPaneUI for the given JComponent.
 912:  *
 913:  * @param c The JComponent to uninstall the UI for.
 914:  */
 915:  public void uninstallUI(JComponent c)
 916:  {
 917:  uninstallKeyboardActions();
 918:  uninstallListeners();
 919:  uninstallDefaults();
 920: 
 921:  dividerLocationSet = false;
 922:  splitPane = null;
 923:  }
 924: 
 925:  /**
 926:  * This method installs the defaults given by the Look and Feel.
 927:  */
 928:  protected void installDefaults()
 929:  {
 930:  LookAndFeel.installColors(splitPane, "SplitPane.background",
 931:  "SplitPane.foreground");
 932:  LookAndFeel.installBorder(splitPane, "SplitPane.border");
 933:  divider = createDefaultDivider();
 934:  divider.setBorder(UIManager.getBorder("SplitPaneDivider.border"));
 935:  resetLayoutManager();
 936:  nonContinuousLayoutDivider = createDefaultNonContinuousLayoutDivider();
 937:  splitPane.add(divider, JSplitPane.DIVIDER);
 938: 
 939:  // There is no need to add the nonContinuousLayoutDivider.
 940:  dividerSize = UIManager.getInt("SplitPane.dividerSize");
 941:  splitPane.setDividerSize(dividerSize);
 942:  divider.setDividerSize(dividerSize);
 943:  splitPane.setOpaque(true);
 944:  }
 945: 
 946:  /**
 947:  * This method uninstalls the defaults and nulls any objects created during
 948:  * install.
 949:  */
 950:  protected void uninstallDefaults()
 951:  {
 952:  layoutManager = null;
 953:  splitPane.remove(divider);
 954:  divider = null;
 955:  nonContinuousLayoutDivider = null;
 956: 
 957:  if (splitPane.getBackground() instanceof UIResource)
 958:  splitPane.setBackground(null);
 959:  if (splitPane.getBorder() instanceof UIResource)
 960:  splitPane.setBorder(null);
 961:  }
 962: 
 963:  /**
 964:  * This method installs the listeners needed for this UI to function.
 965:  */
 966:  protected void installListeners()
 967:  {
 968:  propertyChangeListener = createPropertyChangeListener();
 969:  focusListener = createFocusListener();
 970: 
 971:  splitPane.addPropertyChangeListener(propertyChangeListener);
 972:  splitPane.addFocusListener(focusListener);
 973:  }
 974: 
 975:  /**
 976:  * This method uninstalls all listeners registered for the UI.
 977:  */
 978:  protected void uninstallListeners()
 979:  {
 980:  splitPane.removePropertyChangeListener(propertyChangeListener);
 981:  splitPane.removeFocusListener(focusListener);
 982: 
 983:  focusListener = null;
 984:  propertyChangeListener = null;
 985:  }
 986: 
 987:  /**
 988:  * Returns the input map for the specified condition.
 989:  * 
 990:  * @param condition the condition.
 991:  * 
 992:  * @return The input map.
 993:  */
 994:  InputMap getInputMap(int condition) 
 995:  {
 996:  if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
 997:  return (InputMap) UIManager.get("SplitPane.ancestorInputMap");
 998:  return null;
 999:  }
1000: 
1001:  /**
1002:  * Returns the action map for the {@link JSplitPane}. All sliders share
1003:  * a single action map which is created the first time this method is 
1004:  * called, then stored in the UIDefaults table for subsequent access.
1005:  * 
1006:  * @return The shared action map.
1007:  */
1008:  ActionMap getActionMap() 
1009:  {
1010:  ActionMap map = (ActionMap) UIManager.get("SplitPane.actionMap");
1011: 
1012:  if (map == null) // first time here
1013:  {
1014:  map = createActionMap();
1015:  if (map != null)
1016:  UIManager.put("SplitPane.actionMap", map);
1017:  }
1018:  return map;
1019:  }
1020: 
1021:  /**
1022:  * Creates the action map shared by all {@link JSlider} instances.
1023:  * This method is called once by {@link #getActionMap()} when it 
1024:  * finds no action map in the UIDefaults table...after the map is 
1025:  * created, it gets added to the defaults table so that subsequent 
1026:  * calls to {@link #getActionMap()} will return the same shared 
1027:  * instance.
1028:  * 
1029:  * @return The action map.
1030:  */
1031:  ActionMap createActionMap()
1032:  {
1033:  ActionMap map = new ActionMapUIResource();
1034:  map.put("toggleFocus", 
1035:  new AbstractAction("toggleFocus") {
1036:  public void actionPerformed(ActionEvent event)
1037:  {
1038:  // FIXME: What to do here?
1039:  }
1040:  }
1041:  );
1042:  map.put("startResize", 
1043:  new AbstractAction("startResize") {
1044:  public void actionPerformed(ActionEvent event)
1045:  {
1046:  splitPane.requestFocus();
1047:  }
1048:  }
1049:  );
1050:  map.put("selectMax", 
1051:  new AbstractAction("selectMax") {
1052:  public void actionPerformed(ActionEvent event)
1053:  {
1054:  splitPane.setDividerLocation(1.0);
1055:  }
1056:  }
1057:  );
1058:  map.put("selectMin", 
1059:  new AbstractAction("selectMin") {
1060:  public void actionPerformed(ActionEvent event)
1061:  {
1062:  splitPane.setDividerLocation(0.0);
1063:  }
1064:  }
1065:  );
1066:  map.put("negativeIncrement", 
1067:  new AbstractAction("negativeIncrement") {
1068:  public void actionPerformed(ActionEvent event)
1069:  {
1070:  int oldLoc = splitPane.getDividerLocation();
1071:  int newLoc =
1072:  Math.max(oldLoc - KEYBOARD_DIVIDER_MOVE_OFFSET, 0);
1073:  splitPane.setDividerLocation(newLoc);
1074:  }
1075:  }
1076:  );
1077:  map.put("positiveIncrement", 
1078:  new AbstractAction("positiveIncrement") {
1079:  public void actionPerformed(ActionEvent event)
1080:  {
1081:  int oldLoc = splitPane.getDividerLocation();
1082:  int newLoc =
1083:  Math.max(oldLoc + KEYBOARD_DIVIDER_MOVE_OFFSET, 0);
1084:  splitPane.setDividerLocation(newLoc);
1085:  }
1086:  }
1087:  );
1088:  map.put("focusOutBackward",
1089:  new AbstractAction("focusOutBackward") {
1090:  public void actionPerformed(ActionEvent event)
1091:  {
1092:  // FIXME: implement this
1093:  }
1094:  }
1095:  ); 
1096:  map.put("focusOutForward",
1097:  new AbstractAction("focusOutForward") {
1098:  public void actionPerformed(ActionEvent event)
1099:  {
1100:  // FIXME: implement this
1101:  }
1102:  }
1103:  ); 
1104:  return map;
1105:  }
1106: 
1107:  /**
1108:  * Installs any keyboard actions. The list of keys that need to be bound are
1109:  * listed in Basic look and feel's defaults.
1110:  */
1111:  protected void installKeyboardActions()
1112:  {
1113:  InputMap keyMap = getInputMap(
1114:  JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
1115:  SwingUtilities.replaceUIInputMap(splitPane, 
1116:  JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);
1117:  ActionMap map = getActionMap();
1118:  SwingUtilities.replaceUIActionMap(splitPane, map);
1119:  }
1120: 
1121:  /**
1122:  * This method reverses the work done in installKeyboardActions.
1123:  */
1124:  protected void uninstallKeyboardActions()
1125:  {
1126:  SwingUtilities.replaceUIActionMap(splitPane, null);
1127:  SwingUtilities.replaceUIInputMap(splitPane, 
1128:  JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
1129:  }
1130: 
1131:  /**
1132:  * This method creates a new PropertyChangeListener.
1133:  *
1134:  * @return A new PropertyChangeListener.
1135:  */
1136:  protected PropertyChangeListener createPropertyChangeListener()
1137:  {
1138:  return new PropertyHandler();
1139:  }
1140: 
1141:  /**
1142:  * This method creates a new FocusListener.
1143:  *
1144:  * @return A new FocusListener.
1145:  */
1146:  protected FocusListener createFocusListener()
1147:  {
1148:  return new FocusHandler();
1149:  }
1150: 
1151:  /**
1152:  * This method creates a new ActionListener for up and left key presses.
1153:  *
1154:  * @return A new ActionListener for up and left keys.
1155:  *
1156:  * @deprecated 1.3
1157:  */
1158:  protected ActionListener createKeyboardUpLeftListener()
1159:  {
1160:  return new KeyboardUpLeftHandler();
1161:  }
1162: 
1163:  /**
1164:  * This method creates a new ActionListener for down and right key presses.
1165:  *
1166:  * @return A new ActionListener for down and right keys.
1167:  *
1168:  * @deprecated 1.3
1169:  */
1170:  protected ActionListener createKeyboardDownRightListener()
1171:  {
1172:  return new KeyboardDownRightHandler();
1173:  }
1174: 
1175:  /**
1176:  * This method creates a new ActionListener for home key presses.
1177:  *
1178:  * @return A new ActionListener for home keys.
1179:  *
1180:  * @deprecated
1181:  */
1182:  protected ActionListener createKeyboardHomeListener()
1183:  {
1184:  return new KeyboardHomeHandler();
1185:  }
1186: 
1187:  /**
1188:  * This method creates a new ActionListener for end key presses.i
1189:  *
1190:  * @return A new ActionListener for end keys.
1191:  *
1192:  * @deprecated 1.3
1193:  */
1194:  protected ActionListener createKeyboardEndListener()
1195:  {
1196:  return new KeyboardEndHandler();
1197:  }
1198: 
1199:  /**
1200:  * This method creates a new ActionListener for resize toggle key events.
1201:  *
1202:  * @return A new ActionListener for resize toggle keys.
1203:  *
1204:  * @deprecated 1.3
1205:  */
1206:  protected ActionListener createKeyboardResizeToggleListener()
1207:  {
1208:  return new KeyboardResizeToggleHandler();
1209:  }
1210: 
1211:  /**
1212:  * This method returns the orientation of the JSplitPane.
1213:  *
1214:  * @return The orientation of the JSplitPane.
1215:  */
1216:  public int getOrientation()
1217:  {
1218:  return splitPane.getOrientation();
1219:  }
1220: 
1221:  /**
1222:  * This method sets the orientation of the JSplitPane.
1223:  *
1224:  * @param orientation The new orientation of the JSplitPane.
1225:  */
1226:  public void setOrientation(int orientation)
1227:  {
1228:  splitPane.setOrientation(orientation);
1229:  }
1230: 
1231:  /**
1232:  * This method returns true if the JSplitPane is using continuous layout.
1233:  *
1234:  * @return True if the JSplitPane is using continuous layout.
1235:  */
1236:  public boolean isContinuousLayout()
1237:  {
1238:  return splitPane.isContinuousLayout();
1239:  }
1240: 
1241:  /**
1242:  * This method sets the continuous layout property of the JSplitPane.
1243:  *
1244:  * @param b True if the JsplitPane is to use continuous layout.
1245:  */
1246:  public void setContinuousLayout(boolean b)
1247:  {
1248:  splitPane.setContinuousLayout(b);
1249:  }
1250: 
1251:  /**
1252:  * This method returns the last location the divider was dragged to.
1253:  *
1254:  * @return The last location the divider was dragged to.
1255:  */
1256:  public int getLastDragLocation()
1257:  {
1258:  return lastDragLocation;
1259:  }
1260: 
1261:  /**
1262:  * This method sets the last location the divider was dragged to.
1263:  *
1264:  * @param l The last location the divider was dragged to.
1265:  */
1266:  public void setLastDragLocation(int l)
1267:  {
1268:  lastDragLocation = l;
1269:  }
1270: 
1271:  /**
1272:  * This method returns the BasicSplitPaneDivider that divides this
1273:  * JSplitPane.
1274:  *
1275:  * @return The divider for the JSplitPane.
1276:  */
1277:  public BasicSplitPaneDivider getDivider()
1278:  {
1279:  return divider;
1280:  }
1281: 
1282:  /**
1283:  * This method creates a nonContinuousLayoutDivider for use with the
1284:  * JSplitPane in nonContinousLayout mode. The default divider is a gray
1285:  * Canvas.
1286:  *
1287:  * @return The default nonContinousLayoutDivider.
1288:  */
1289:  protected Component createDefaultNonContinuousLayoutDivider()
1290:  {
1291:  if (nonContinuousLayoutDivider == null)
1292:  {
1293:  nonContinuousLayoutDivider = new Canvas();
1294:  Color c = UIManager.getColor("SplitPaneDivider.draggingColor");
1295:  nonContinuousLayoutDivider.setBackground(c);
1296:  }
1297:  return nonContinuousLayoutDivider;
1298:  }
1299: 
1300:  /**
1301:  * This method sets the component to use as the nonContinuousLayoutDivider.
1302:  *
1303:  * @param newDivider The component to use as the nonContinuousLayoutDivider.
1304:  */
1305:  protected void setNonContinuousLayoutDivider(Component newDivider)
1306:  {
1307:  setNonContinuousLayoutDivider(newDivider, true);
1308:  }
1309: 
1310:  /**
1311:  * This method sets the component to use as the nonContinuousLayoutDivider.
1312:  *
1313:  * @param newDivider The component to use as the nonContinuousLayoutDivider.
1314:  * @param rememberSizes FIXME: document.
1315:  */
1316:  protected void setNonContinuousLayoutDivider(Component newDivider,
1317:  boolean rememberSizes)
1318:  {
1319:  // FIXME: use rememberSizes for something
1320:  nonContinuousLayoutDivider = newDivider;
1321:  }
1322: 
1323:  /**
1324:  * This method returns the nonContinuousLayoutDivider.
1325:  *
1326:  * @return The nonContinuousLayoutDivider.
1327:  */
1328:  public Component getNonContinuousLayoutDivider()
1329:  {
1330:  return nonContinuousLayoutDivider;
1331:  }
1332: 
1333:  /**
1334:  * This method returns the JSplitPane that this BasicSplitPaneUI draws.
1335:  *
1336:  * @return The JSplitPane.
1337:  */
1338:  public JSplitPane getSplitPane()
1339:  {
1340:  return splitPane;
1341:  }
1342: 
1343:  /**
1344:  * This method creates the divider used normally with the JSplitPane.
1345:  *
1346:  * @return The default divider.
1347:  */
1348:  public BasicSplitPaneDivider createDefaultDivider()
1349:  {
1350:  if (divider == null)
1351:  divider = new BasicSplitPaneDivider(this);
1352:  return divider;
1353:  }
1354: 
1355:  /**
1356:  * This method is called when JSplitPane's resetToPreferredSizes is called.
1357:  * It resets the sizes of all components in the JSplitPane.
1358:  *
1359:  * @param jc The JSplitPane to reset.
1360:  */
1361:  public void resetToPreferredSizes(JSplitPane jc)
1362:  {
1363:  layoutManager.resetToPreferredSizes();
1364:  }
1365: 
1366:  /**
1367:  * This method sets the location of the divider.
1368:  *
1369:  * @param jc The JSplitPane to set the divider location in.
1370:  * @param location The new location of the divider.
1371:  */
1372:  public void setDividerLocation(JSplitPane jc, int location)
1373:  {
1374:  dividerLocationSet = true;
1375:  splitPane.revalidate();
1376:  splitPane.repaint();
1377:  }
1378: 
1379:  /**
1380:  * This method returns the location of the divider.
1381:  *
1382:  * @param jc The JSplitPane to retrieve the location for.
1383:  *
1384:  * @return The location of the divider.
1385:  */
1386:  public int getDividerLocation(JSplitPane jc)
1387:  {
1388:  int loc;
1389:  if (jc.getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
1390:  loc = divider.getX();
1391:  else
1392:  loc = divider.getY();
1393:  return loc;
1394:  }
1395: 
1396:  /**
1397:  * This method returns the smallest value possible for the location of the
1398:  * divider.
1399:  *
1400:  * @param jc The JSplitPane.
1401:  *
1402:  * @return The minimum divider location.
1403:  */
1404:  public int getMinimumDividerLocation(JSplitPane jc)
1405:  {
1406:  int value = layoutManager.getInitialLocation(jc.getInsets());
1407:  if (layoutManager.components[0] != null)
1408:  value += layoutManager.minimumSizeOfComponent(0);
1409:  return value;
1410:  }
1411: 
1412:  /**
1413:  * This method returns the largest value possible for the location of the
1414:  * divider.
1415:  *
1416:  * @param jc The JSplitPane.
1417:  *
1418:  * @return The maximum divider location.
1419:  */
1420:  public int getMaximumDividerLocation(JSplitPane jc)
1421:  {
1422:  int value = layoutManager.getInitialLocation(jc.getInsets())
1423:  + layoutManager.getAvailableSize(jc.getSize(), jc.getInsets())
1424:  - splitPane.getDividerSize();
1425:  if (layoutManager.components[1] != null)
1426:  value -= layoutManager.minimumSizeOfComponent(1);
1427:  return value;
1428:  }
1429: 
1430:  /**
1431:  * This method is called after the children of the JSplitPane are painted.
1432:  *
1433:  * @param jc The JSplitPane.
1434:  * @param g The Graphics object to paint with.
1435:  */
1436:  public void finishedPaintingChildren(JSplitPane jc, Graphics g)
1437:  {
1438:  if (! splitPane.isContinuousLayout() && nonContinuousLayoutDivider != null
1439:  && nonContinuousLayoutDivider.isVisible())
1440:  javax.swing.SwingUtilities.paintComponent(g, nonContinuousLayoutDivider,
1441:  null,
1442:  nonContinuousLayoutDivider
1443:  .getBounds());
1444:  }
1445: 
1446:  /**
1447:  * This method is called to paint the JSplitPane.
1448:  *
1449:  * @param g The Graphics object to paint with.
1450:  * @param jc The JSplitPane to paint.
1451:  */
1452:  public void paint(Graphics g, JComponent jc)
1453:  {
1454:  // TODO: What should be done here?
1455:  }
1456: 
1457:  /**
1458:  * This method returns the preferred size of the JSplitPane.
1459:  *
1460:  * @param jc The JSplitPane.
1461:  *
1462:  * @return The preferred size of the JSplitPane.
1463:  */
1464:  public Dimension getPreferredSize(JComponent jc)
1465:  {
1466:  return layoutManager.preferredLayoutSize(jc);
1467:  }
1468: 
1469:  /**
1470:  * This method returns the minimum size of the JSplitPane.
1471:  *
1472:  * @param jc The JSplitPane.
1473:  *
1474:  * @return The minimum size of the JSplitPane.
1475:  */
1476:  public Dimension getMinimumSize(JComponent jc)
1477:  {
1478:  return layoutManager.minimumLayoutSize(jc);
1479:  }
1480: 
1481:  /**
1482:  * This method returns the maximum size of the JSplitPane.
1483:  *
1484:  * @param jc The JSplitPane.
1485:  *
1486:  * @return The maximum size of the JSplitPane.
1487:  */
1488:  public Dimension getMaximumSize(JComponent jc)
1489:  {
1490:  return layoutManager.maximumLayoutSize(jc);
1491:  }
1492: 
1493:  /**
1494:  * This method returns the border insets of the current border.
1495:  *
1496:  * @param jc The JSplitPane.
1497:  *
1498:  * @return The current border insets.
1499:  */
1500:  public Insets getInsets(JComponent jc)
1501:  {
1502:  return splitPane.getBorder().getBorderInsets(splitPane);
1503:  }
1504: 
1505:  /**
1506:  * This method resets the current layout manager. The type of layout manager
1507:  * is dependent on the current orientation.
1508:  */
1509:  protected void resetLayoutManager()
1510:  {
1511:  if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
1512:  layoutManager = new BasicHorizontalLayoutManager();
1513:  else
1514:  layoutManager = new BasicVerticalLayoutManager();
1515:  getSplitPane().setLayout(layoutManager);
1516:  layoutManager.updateComponents();
1517: 
1518:  // invalidating by itself does not invalidate the layout.
1519:  getSplitPane().revalidate();
1520:  }
1521: 
1522:  /**
1523:  * This method is called when dragging starts. It resets lastDragLocation
1524:  * and dividerSize.
1525:  */
1526:  protected void startDragging()
1527:  {
1528:  Component left = splitPane.getLeftComponent();
1529:  Component right = splitPane.getRightComponent();
1530:  dividerSize = divider.getDividerSize();
1531:  setLastDragLocation(-1);
1532: 
1533:  if ((left != null && !left.isLightweight())
1534:  || (right != null && !right.isLightweight()))
1535:  draggingHW = true;
1536: 
1537:  if (splitPane.isContinuousLayout())
1538:  nonContinuousLayoutDivider.setVisible(false);
1539:  else
1540:  {
1541:  nonContinuousLayoutDivider.setVisible(true);
1542:  nonContinuousLayoutDivider.setBounds(divider.getBounds());
1543:  }
1544:  }
1545: 
1546:  /**
1547:  * This method is called whenever the divider is dragged. If the JSplitPane
1548:  * is in continuousLayout mode, the divider needs to be moved and the
1549:  * JSplitPane needs to be laid out.
1550:  *
1551:  * @param location The new location of the divider.
1552:  */
1553:  protected void dragDividerTo(int location)
1554:  {
1555:  location = validLocation(location);
1556:  if (beginDragDividerLocation == -1)
1557:  beginDragDividerLocation = location;
1558: 
1559:  if (splitPane.isContinuousLayout())
1560:  splitPane.setDividerLocation(location);
1561:  else
1562:  {
1563:  Point p = nonContinuousLayoutDivider.getLocation();
1564:  if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
1565:  p.x = location;
1566:  else
1567:  p.y = location;
1568:  nonContinuousLayoutDivider.setLocation(p);
1569:  }
1570:  setLastDragLocation(location);
1571:  splitPane.repaint();
1572:  }
1573: 
1574:  /**
1575:  * This method is called when the dragging is finished.
1576:  *
1577:  * @param location The location where the drag finished.
1578:  */
1579:  protected void finishDraggingTo(int location)
1580:  {
1581:  if (nonContinuousLayoutDivider != null)
1582:  nonContinuousLayoutDivider.setVisible(false);
1583:  draggingHW = false;
1584:  location = validLocation(location);
1585:  splitPane.setDividerLocation(location);
1586:  splitPane.setLastDividerLocation(beginDragDividerLocation);
1587:  beginDragDividerLocation = -1;
1588:  }
1589: 
1590:  /**
1591:  * This method returns the width of one of the sides of the divider's border.
1592:  *
1593:  * @return The width of one side of the divider's border.
1594:  *
1595:  * @deprecated 1.3
1596:  */
1597:  protected int getDividerBorderSize()
1598:  {
1599:  if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT)
1600:  return divider.getBorder().getBorderInsets(divider).left;
1601:  else
1602:  return divider.getBorder().getBorderInsets(divider).top;
1603:  }
1604: 
1605:  /**
1606:  * This is a helper method that returns a valid location for the divider
1607:  * when dragging.
1608:  *
1609:  * @param location The location to check.
1610:  *
1611:  * @return A valid location.
1612:  */
1613:  private int validLocation(int location)
1614:  {
1615:  int min = getMinimumDividerLocation(splitPane);
1616:  int max = getMaximumDividerLocation(splitPane);
1617:  if (min > 0 && location < min)
1618:  return min;
1619:  if (max > 0 && location > max)
1620:  return max;
1621:  return location;
1622:  }
1623: }
Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)

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