Source for javax.swing.plaf.basic.BasicToolBarUI

   1: /* BasicToolBarUI.java --
   2:    Copyright (C) 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.BorderLayout;
  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.Point;
  49: import java.awt.Rectangle;
  50: import java.awt.Window;
  51: import java.awt.event.ActionEvent;
  52: import java.awt.event.ContainerEvent;
  53: import java.awt.event.ContainerListener;
  54: import java.awt.event.FocusEvent;
  55: import java.awt.event.FocusListener;
  56: import java.awt.event.MouseEvent;
  57: import java.awt.event.WindowAdapter;
  58: import java.awt.event.WindowEvent;
  59: import java.awt.event.WindowListener;
  60: import java.beans.PropertyChangeEvent;
  61: import java.beans.PropertyChangeListener;
  62: import java.util.Hashtable;
  63: 
  64: import javax.swing.AbstractAction;
  65: import javax.swing.AbstractButton;
  66: import javax.swing.Action;
  67: import javax.swing.ActionMap;
  68: import javax.swing.InputMap;
  69: import javax.swing.JButton;
  70: import javax.swing.JComponent;
  71: import javax.swing.JDialog;
  72: import javax.swing.JFrame;
  73: import javax.swing.JToolBar;
  74: import javax.swing.KeyStroke;
  75: import javax.swing.LookAndFeel;
  76: import javax.swing.RootPaneContainer;
  77: import javax.swing.SwingConstants;
  78: import javax.swing.SwingUtilities;
  79: import javax.swing.UIManager;
  80: import javax.swing.border.Border;
  81: import javax.swing.border.CompoundBorder;
  82: import javax.swing.event.MouseInputListener;
  83: import javax.swing.plaf.ActionMapUIResource;
  84: import javax.swing.plaf.ComponentUI;
  85: import javax.swing.plaf.ToolBarUI;
  86: import javax.swing.plaf.UIResource;
  87: import javax.swing.plaf.basic.BasicBorders.ButtonBorder;
  88: 
  89: /**
  90:  * This is the Basic Look and Feel UI class for JToolBar.
  91:  */
  92: public class BasicToolBarUI extends ToolBarUI implements SwingConstants
  93: {
  94: 
  95:   /**
  96:    * Implements the keyboard actions for JToolBar.
  97:    */
  98:   static class ToolBarAction
  99:     extends AbstractAction
 100:   {
 101:     /**
 102:      * Performs the action.
 103:      */
 104:     public void actionPerformed(ActionEvent event)
 105:     {
 106:       Object cmd = getValue("__command__");
 107:       JToolBar toolBar = (JToolBar) event.getSource();
 108:       BasicToolBarUI ui = (BasicToolBarUI) toolBar.getUI();
 109: 
 110:       if (cmd.equals("navigateRight"))
 111:         ui.navigateFocusedComp(EAST);
 112:       else if (cmd.equals("navigateLeft"))
 113:           ui.navigateFocusedComp(WEST);
 114:       else if (cmd.equals("navigateUp"))
 115:           ui.navigateFocusedComp(NORTH);
 116:       else if (cmd.equals("navigateDown"))
 117:         ui.navigateFocusedComp(SOUTH);
 118:       else
 119:         assert false : "Shouldn't reach here";
 120:     }
 121:   }
 122: 
 123:   /** Static owner of all DragWindows.
 124:    * This is package-private to avoid an accessor method.  */
 125:   static JFrame owner = new JFrame();
 126: 
 127:   /** The border used when the JToolBar is in nonrollover mode. */
 128:   private static Border nonRolloverBorder;
 129: 
 130:   /** The border used when the JToolBar is in rollover mode. */
 131:   private static Border rolloverBorder;
 132: 
 133:   /** The last known BorderLayout constraint before floating. */
 134:   protected String constraintBeforeFloating;
 135: 
 136:   /** The last known orientation of the JToolBar before floating.
 137:    * This is package-private to avoid an accessor method.  */
 138:   int lastGoodOrientation;
 139: 
 140:   /** The color of the border when it is dockable. */
 141:   protected Color dockingBorderColor;
 142: 
 143:   /** The background color of the JToolBar when it is dockable. */
 144:   protected Color dockingColor;
 145: 
 146:   /** The docking listener responsible for mouse events on the JToolBar. */
 147:   protected MouseInputListener dockingListener;
 148: 
 149:   /** The window used for dragging the JToolBar. */
 150:   protected BasicToolBarUI.DragWindow dragWindow;
 151: 
 152:   /** The color of the border when it is not dockable. */
 153:   protected Color floatingBorderColor;
 154: 
 155:   /** The background color of the JToolBar when it is not dockable. */
 156:   protected Color floatingColor;
 157: 
 158:   /** The index of the focused component. */
 159:   protected int focusedCompIndex;
 160: 
 161:   /** The PropertyChangeListener for the JToolBar. */
 162:   protected PropertyChangeListener propertyListener;
 163: 
 164:   /** The JToolBar this UI delegate is responsible for. */
 165:   protected JToolBar toolBar;
 166: 
 167:   /** The Container listener for the JToolBar. */
 168:   protected ContainerListener toolBarContListener;
 169: 
 170:   /** The Focus listener for the JToolBar. */
 171:   protected FocusListener toolBarFocusListener;
 172: 
 173:   /**
 174:    * @deprecated since JDK1.3.
 175:    */
 176:   protected KeyStroke leftKey;
 177: 
 178:   /**
 179:    * @deprecated since JDK1.3.
 180:    */
 181:   protected KeyStroke rightKey;
 182: 
 183:   /**
 184:    * @deprecated since JDK1.3.
 185:    */
 186:   protected KeyStroke upKey;
 187: 
 188:   /**
 189:    * @deprecated since JDK1.3.
 190:    */
 191:   protected KeyStroke downKey;
 192: 
 193:   /**
 194:    * The floating window that is responsible for holding the JToolBar when it
 195:    * is dragged outside of its original parent.
 196:    */
 197:   private transient Window floatFrame;
 198: 
 199:   /** The original parent of the JToolBar.
 200:    * This is package-private to avoid an accessor method.  */
 201:   transient Container origParent;
 202: 
 203:   /** A hashtable of components and their original borders.
 204:    * This is package-private to avoid an accessor method.  */
 205:   transient Hashtable borders;
 206: 
 207:   /** A window listener for the floatable frame. */
 208:   private transient WindowListener windowListener;
 209: 
 210:   /** A set of cached bounds of the JToolBar.
 211:    * This is package-private to avoid an accessor method.  */
 212:   transient Dimension cachedBounds;
 213: 
 214:   /** The cached orientation of the JToolBar.
 215:    * This is package-private to avoid an accessor method.  */
 216:   transient int cachedOrientation;
 217: 
 218:   /**
 219:    * This method creates a new <code>BasicToolBarUI</code> object for the given JToolBar.
 220:    */
 221:   public BasicToolBarUI()
 222:   {
 223:     // Do nothing here.
 224:   }
 225: 
 226:   /**
 227:    * This method returns whether the JToolBar can dock at the given position.
 228:    *
 229:    * @param c The component to try to dock in.
 230:    * @param p The position of the mouse cursor relative to the given
 231:    *        component.
 232:    *
 233:    * @return Whether the JToolBar can dock.
 234:    */
 235:   public boolean canDock(Component c, Point p)
 236:   {
 237:     return areaOfClick(c, p) != -1;
 238:   }
 239: 
 240:   /**
 241:    * This helper method returns the position of the JToolBar if it can dock.
 242:    *
 243:    * @param c The component to try to dock in.
 244:    * @param p The position of the mouse cursor relative to the given
 245:    *        component.
 246:    *
 247:    * @return One of the SwingConstants directions or -1 if the JToolBar can't
 248:    *         dock.
 249:    */
 250:   private int areaOfClick(Component c, Point p)
 251:   {
 252:     // Has to dock in immediate parent, not eventual root container.
 253:     Rectangle pBounds = c.getBounds();
 254: 
 255:     // XXX: In Sun's implementation, the space the toolbar has to dock is dependent on the size it had last.
 256:     Dimension d = toolBar.getSize();
 257:     int limit = Math.min(d.width, d.height);
 258: 
 259:     // The order of checking is 1. top 2. bottom 3. left 4. right
 260:     if (! pBounds.contains(p))
 261:       return -1;
 262: 
 263:     if (p.y < limit)
 264:       return SwingConstants.NORTH;
 265: 
 266:     if (p.y > (pBounds.height - limit))
 267:       return SwingConstants.SOUTH;
 268: 
 269:     if (p.x < limit)
 270:       return SwingConstants.WEST;
 271: 
 272:     if (p.x > (pBounds.width - limit))
 273:       return SwingConstants.EAST;
 274: 
 275:     return -1;
 276:   }
 277: 
 278:   /**
 279:    * This method creates a new DockingListener for the JToolBar.
 280:    *
 281:    * @return A new DockingListener for the JToolBar.
 282:    */
 283:   protected MouseInputListener createDockingListener()
 284:   {
 285:     return new DockingListener(toolBar);
 286:   }
 287: 
 288:   /**
 289:    * This method creates a new DragWindow for the given JToolBar.
 290:    *
 291:    * @param toolbar The JToolBar to create a DragWindow for.
 292:    *
 293:    * @return A new DragWindow.
 294:    */
 295:   protected BasicToolBarUI.DragWindow createDragWindow(JToolBar toolbar)
 296:   {
 297:     return new DragWindow();
 298:   }
 299: 
 300:   /**
 301:    * This method creates a new floating frame for the JToolBar. By default,
 302:    * this UI uses createFloatingWindow instead. This method of creating a
 303:    * floating frame is deprecated.
 304:    *
 305:    * @param toolbar The JToolBar to create a floating frame for.
 306:    *
 307:    * @return A new floating frame.
 308:    */
 309:   protected JFrame createFloatingFrame(JToolBar toolbar)
 310:   {
 311:     // FIXME: Though deprecated, this should still work.
 312:     return null;
 313:   }
 314: 
 315:   /**
 316:    * This method creates a new floating window for the JToolBar. This is the
 317:    * method used by default to create a floating container for the JToolBar.
 318:    *
 319:    * @param toolbar The JToolBar to create a floating window for.
 320:    *
 321:    * @return A new floating window.
 322:    */
 323:   protected RootPaneContainer createFloatingWindow(JToolBar toolbar)
 324:   {
 325:     // This one is used by default though.
 326:     return new ToolBarDialog();
 327:   }
 328: 
 329:   /**
 330:    * This method creates a new WindowListener for the JToolBar.
 331:    *
 332:    * @return A new WindowListener.
 333:    */
 334:   protected WindowListener createFrameListener()
 335:   {
 336:     return new FrameListener();
 337:   }
 338: 
 339:   /**
 340:    * This method creates a new nonRolloverBorder for JButtons when the
 341:    * JToolBar's rollover property is set to false.
 342:    *
 343:    * @return A new NonRolloverBorder.
 344:    */
 345:   protected Border createNonRolloverBorder()
 346:   {
 347:     Border b = UIManager.getBorder("ToolBar.nonrolloverBorder");
 348:     
 349:     if (b == null)
 350:       {
 351:         b = new CompoundBorder(
 352:             new ButtonBorder(UIManager.getColor("Button.shadow"),
 353:                              UIManager.getColor("Button.darkShadow"),
 354:                              UIManager.getColor("Button.light"),
 355:                              UIManager.getColor("Button.highlight")),
 356:             BasicBorders.getMarginBorder());
 357:       }
 358:     
 359:     return b;  }
 360: 
 361:   /**
 362:    * This method creates a new PropertyChangeListener for the JToolBar.
 363:    *
 364:    * @return A new PropertyChangeListener.
 365:    */
 366:   protected PropertyChangeListener createPropertyListener()
 367:   {
 368:     return new PropertyListener();
 369:   }
 370: 
 371:   /**
 372:    * This method creates a new rollover border for JButtons when the
 373:    * JToolBar's rollover property is set to true.
 374:    *
 375:    * @return A new rollover border.
 376:    */
 377:   protected Border createRolloverBorder()
 378:   {
 379:     Border b = UIManager.getBorder("ToolBar.rolloverBorder");
 380:     
 381:     if (b == null)
 382:       {
 383:         b = new CompoundBorder(
 384:             new ButtonBorder(UIManager.getColor("Button.shadow"),
 385:                              UIManager.getColor("Button.darkShadow"),
 386:                              UIManager.getColor("Button.light"),
 387:                              UIManager.getColor("Button.highlight")),
 388:             BasicBorders.getMarginBorder());
 389:       }
 390:     
 391:     return b;
 392:   }
 393: 
 394:   /**
 395:    * This method creates a new Container listener for the JToolBar.
 396:    *
 397:    * @return A new Container listener.
 398:    */
 399:   protected ContainerListener createToolBarContListener()
 400:   {
 401:     return new ToolBarContListener();
 402:   }
 403: 
 404:   /**
 405:    * This method creates a new FocusListener for the JToolBar.
 406:    *
 407:    * @return A new FocusListener for the JToolBar.
 408:    */
 409:   protected FocusListener createToolBarFocusListener()
 410:   {
 411:     return new ToolBarFocusListener();
 412:   }
 413: 
 414:   /**
 415:    * This method creates a new UI delegate for the given JComponent.
 416:    *
 417:    * @param c The JComponent to create a UI delegate for.
 418:    *
 419:    * @return A new UI delegate.
 420:    */
 421:   public static ComponentUI createUI(JComponent c)
 422:   {
 423:     return new BasicToolBarUI();
 424:   }
 425: 
 426:   /**
 427:    * This method is called to drag the DragWindow around when the JToolBar is
 428:    * being dragged around.
 429:    *
 430:    * @param position The mouse cursor coordinates relative to the JToolBar.
 431:    * @param origin The screen position of the JToolBar.
 432:    */
 433:   protected void dragTo(Point position, Point origin)
 434:   {
 435:     int loc = areaOfClick(origParent,
 436:                           SwingUtilities.convertPoint(toolBar, position,
 437:                                                       origParent));
 438: 
 439:     if (loc != -1)
 440:       {
 441:     dragWindow.setBorderColor(dockingBorderColor);
 442:     dragWindow.setBackground(dockingColor);
 443:       }
 444:     else
 445:       {
 446:     dragWindow.setBorderColor(floatingBorderColor);
 447:     dragWindow.setBackground(floatingColor);
 448:       }
 449: 
 450:     int w = 0;
 451:     int h = 0;
 452: 
 453:     boolean tmp = (loc == SwingConstants.NORTH)
 454:                   || (loc == SwingConstants.SOUTH) || (loc == -1);
 455: 
 456:     cachedOrientation = toolBar.getOrientation();
 457:     cachedBounds = toolBar.getSize();
 458:     if (((cachedOrientation == SwingConstants.HORIZONTAL) && tmp)
 459:         || ((cachedOrientation == VERTICAL) && ! tmp))
 460:       {
 461:     w = cachedBounds.width;
 462:     h = cachedBounds.height;
 463:       }
 464:     else
 465:       {
 466:     w = cachedBounds.height;
 467:     h = cachedBounds.width;
 468:       }
 469: 
 470:     Point p = dragWindow.getOffset();
 471:     Insets insets = toolBar.getInsets();
 472: 
 473:     dragWindow.setBounds((origin.x + position.x) - p.x
 474:                          - ((insets.left + insets.right) / 2),
 475:                          (origin.y + position.y) - p.y
 476:                          - ((insets.top + insets.bottom) / 2), w, h);
 477: 
 478:     if (! dragWindow.isVisible())
 479:       dragWindow.show();
 480:   }
 481: 
 482:   /**
 483:    * This method is used at the end of a drag session to place the frame in
 484:    * either its original parent as a docked JToolBar or in its floating
 485:    * frame.
 486:    *
 487:    * @param position The position of the mouse cursor relative to the
 488:    *        JToolBar.
 489:    * @param origin The screen position of the JToolBar before the drag session
 490:    *        started.
 491:    */
 492:   protected void floatAt(Point position, Point origin)
 493:   {
 494:     Point p = new Point(position);
 495:     int aoc = areaOfClick(origParent,
 496:                           SwingUtilities.convertPoint(toolBar, p, origParent));
 497: 
 498:     Container oldParent = toolBar.getParent();
 499: 
 500:     oldParent.remove(toolBar);
 501:     oldParent.doLayout();
 502:     oldParent.repaint();
 503: 
 504:     Container newParent;
 505: 
 506:     if (aoc == -1)
 507:       newParent = ((RootPaneContainer) floatFrame).getContentPane();
 508:     else
 509:       {
 510:     floatFrame.hide();
 511:     newParent = origParent;
 512:       }
 513: 
 514:     String constraint;
 515:     switch (aoc)
 516:       {
 517:       case SwingConstants.EAST:
 518:     constraint = BorderLayout.EAST;
 519:     break;
 520:       case SwingConstants.NORTH:
 521:     constraint = BorderLayout.NORTH;
 522:     break;
 523:       case SwingConstants.SOUTH:
 524:     constraint = BorderLayout.SOUTH;
 525:     break;
 526:       case SwingConstants.WEST:
 527:     constraint = BorderLayout.WEST;
 528:     break;
 529:       default:
 530:     constraint = BorderLayout.CENTER;
 531:     break;
 532:       }
 533: 
 534:     int newOrientation = SwingConstants.HORIZONTAL;
 535:     if ((aoc != -1)
 536:         && ((aoc == SwingConstants.EAST) || (aoc == SwingConstants.WEST)))
 537:       newOrientation = SwingConstants.VERTICAL;
 538: 
 539:     if (aoc != -1)
 540:       {
 541:     constraintBeforeFloating = constraint;
 542:     lastGoodOrientation = newOrientation;
 543:       }
 544: 
 545:     newParent.add(toolBar, constraint);
 546: 
 547:     setFloating(aoc == -1, null);
 548:     toolBar.setOrientation(newOrientation);
 549: 
 550:     Insets insets = floatFrame.getInsets();
 551:     Dimension dims = toolBar.getPreferredSize();
 552:     p = dragWindow.getOffset();
 553:     setFloatingLocation((position.x + origin.x) - p.x
 554:                         - ((insets.left + insets.right) / 2),
 555:                         (position.y + origin.y) - p.y
 556:                         - ((insets.top + insets.bottom) / 2));
 557: 
 558:     if (aoc == -1)
 559:       {
 560:     floatFrame.pack();
 561:     floatFrame.setSize(dims.width + insets.left + insets.right,
 562:                        dims.height + insets.top + insets.bottom);
 563:     floatFrame.show();
 564:       }
 565: 
 566:     newParent.invalidate();
 567:     newParent.validate();
 568:     newParent.repaint();
 569:   }
 570: 
 571:   /**
 572:    * This method returns the docking color.
 573:    *
 574:    * @return The docking color.
 575:    */
 576:   public Color getDockingColor()
 577:   {
 578:     return dockingColor;
 579:   }
 580: 
 581:   /**
 582:    * This method returns the Color which is displayed when over a floating
 583:    * area.
 584:    *
 585:    * @return The color which is displayed when over a floating area.
 586:    */
 587:   public Color getFloatingColor()
 588:   {
 589:     return floatingColor;
 590:   }
 591: 
 592:   /**
 593:    * This method returns the maximum size of the given JComponent for this UI.
 594:    *
 595:    * @param c The JComponent to find the maximum size for.
 596:    *
 597:    * @return The maximum size for this UI.
 598:    */
 599:   public Dimension getMaximumSize(JComponent c)
 600:   {
 601:     return getPreferredSize(c);
 602:   }
 603: 
 604:   /**
 605:    * This method returns the minimum size of the given JComponent for this UI.
 606:    *
 607:    * @param c The JComponent to find a minimum size for.
 608:    *
 609:    * @return The minimum size for this UI.
 610:    */
 611:   public Dimension getMinimumSize(JComponent c)
 612:   {
 613:     return getPreferredSize(c);
 614:   }
 615: 
 616:   /**
 617:    * This method installs the needed components for the JToolBar.
 618:    */
 619:   protected void installComponents()
 620:   {
 621:     floatFrame = (Window) createFloatingWindow(toolBar);
 622: 
 623:     dragWindow = createDragWindow(toolBar);
 624: 
 625:     nonRolloverBorder = createNonRolloverBorder();
 626:     rolloverBorder = createRolloverBorder();
 627: 
 628:     borders = new Hashtable();
 629:     setRolloverBorders(toolBar.isRollover());
 630: 
 631:     fillHashtable();
 632:   }
 633: 
 634:   /**
 635:    * This method installs the defaults as specified by the look and feel.
 636:    */
 637:   protected void installDefaults()
 638:   {
 639:     LookAndFeel.installBorder(toolBar, "ToolBar.border");
 640:     LookAndFeel.installColorsAndFont(toolBar, "ToolBar.background",
 641:                                      "ToolBar.foreground", "ToolBar.font");
 642: 
 643:     dockingBorderColor = UIManager.getColor("ToolBar.dockingForeground");
 644:     dockingColor = UIManager.getColor("ToolBar.dockingBackground");
 645: 
 646:     floatingBorderColor = UIManager.getColor("ToolBar.floatingForeground");
 647:     floatingColor = UIManager.getColor("ToolBar.floatingBackground");
 648:   }
 649: 
 650:   /**
 651:    * This method installs the keyboard actions for the JToolBar as specified
 652:    * by the look and feel.
 653:    */
 654:   protected void installKeyboardActions()
 655:   {
 656:     // Install the input map.
 657:     InputMap inputMap =
 658:       (InputMap) SharedUIDefaults.get("ToolBar.ancestorInputMap");
 659:     SwingUtilities.replaceUIInputMap(toolBar,
 660:                                  JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
 661:                                  inputMap);
 662: 
 663:     // FIXME: The JDK uses a LazyActionMap for parentActionMap
 664:     SwingUtilities.replaceUIActionMap(toolBar, getActionMap());
 665:   }
 666: 
 667:   /**
 668:    * Fetches the action map from  the UI defaults, or create a new one
 669:    * if the action map hasn't been initialized.
 670:    *
 671:    * @return the action map
 672:    */
 673:   private ActionMap getActionMap()
 674:   {
 675:     ActionMap am = (ActionMap) UIManager.get("ToolBar.actionMap");
 676:     if (am == null)
 677:       {
 678:         am = createDefaultActions();
 679:         UIManager.getLookAndFeelDefaults().put("ToolBar.actionMap", am);
 680:       }
 681:     return am;
 682:   }
 683: 
 684:   private ActionMap createDefaultActions()
 685:   {
 686:     ActionMapUIResource am = new ActionMapUIResource();
 687:     Action action = new ToolBarAction();
 688: 
 689:     am.put("navigateLeft", action);
 690:     am.put("navigateRight", action);
 691:     am.put("navigateUp", action);
 692:     am.put("navigateDown", action);
 693: 
 694:     return am;
 695:   }
 696: 
 697:   /**
 698:    * This method installs listeners for the JToolBar.
 699:    */
 700:   protected void installListeners()
 701:   {
 702:     dockingListener = createDockingListener();
 703:     toolBar.addMouseListener(dockingListener);
 704:     toolBar.addMouseMotionListener(dockingListener);
 705: 
 706:     propertyListener = createPropertyListener();
 707:     toolBar.addPropertyChangeListener(propertyListener);
 708: 
 709:     toolBarContListener = createToolBarContListener();
 710:     toolBar.addContainerListener(toolBarContListener);
 711: 
 712:     windowListener = createFrameListener();
 713:     floatFrame.addWindowListener(windowListener);
 714: 
 715:     toolBarFocusListener = createToolBarFocusListener();
 716:     if (toolBarFocusListener != null)
 717:       {
 718:         int count = toolBar.getComponentCount();
 719:         for (int i = 0; i < count; i++)
 720:           toolBar.getComponent(i).addFocusListener(toolBarFocusListener);
 721:       }
 722:   }
 723: 
 724:   /**
 725:    * This method installs non rollover borders for each component inside the
 726:    * given JComponent.
 727:    *
 728:    * @param c The JComponent whose children need to have non rollover borders
 729:    *        installed.
 730:    */
 731:   protected void installNonRolloverBorders(JComponent c)
 732:   {
 733:     Component[] components = toolBar.getComponents();
 734: 
 735:     for (int i = 0; i < components.length; i++)
 736:       setBorderToNonRollover(components[i]);
 737:   }
 738: 
 739:   /**
 740:    * This method installs normal (or their original) borders for each
 741:    * component inside the given JComponent.
 742:    *
 743:    * @param c The JComponent whose children need to have their original
 744:    *        borders installed.
 745:    */
 746:   protected void installNormalBorders(JComponent c)
 747:   {
 748:     Component[] components = toolBar.getComponents();
 749: 
 750:     for (int i = 0; i < components.length; i++)
 751:       setBorderToNormal(components[i]);
 752:   }
 753: 
 754:   /**
 755:    * This method install rollover borders for each component inside the given
 756:    * JComponent.
 757:    *
 758:    * @param c The JComponent whose children need to have rollover borders
 759:    *        installed.
 760:    */
 761:   protected void installRolloverBorders(JComponent c)
 762:   {
 763:     Component[] components = toolBar.getComponents();
 764: 
 765:     for (int i = 0; i < components.length; i++)
 766:       setBorderToRollover(components[i]);
 767:   }
 768: 
 769:   /**
 770:    * This method fills the borders hashtable with a list of components that
 771:    * are JButtons and their borders.
 772:    */
 773:   private void fillHashtable()
 774:   {
 775:     Component[] c = toolBar.getComponents();
 776: 
 777:     for (int i = 0; i < c.length; i++)
 778:       {
 779:     if (c[i] instanceof JButton)
 780:       {
 781:         // Don't really care about anything other than JButtons
 782:         JButton b = (JButton) c[i];
 783: 
 784:         if (b.getBorder() != null)
 785:           borders.put(b, b.getBorder());
 786:       }
 787:       }
 788:   }
 789: 
 790:   /**
 791:    * This method installs the UI for the given JComponent.
 792:    *
 793:    * @param c The JComponent to install a UI for.
 794:    */
 795:   public void installUI(JComponent c)
 796:   {
 797:     super.installUI(c);
 798: 
 799:     if (c instanceof JToolBar)
 800:       {
 801:     toolBar = (JToolBar) c;
 802:     installDefaults();
 803:     installComponents();
 804:     installListeners();
 805:     installKeyboardActions();
 806:       }
 807:   }
 808: 
 809:   /**
 810:    * This method returns whether the JToolBar is floating.
 811:    *
 812:    * @return Whether the JToolBar is floating.
 813:    */
 814:   public boolean isFloating()
 815:   {
 816:     return floatFrame.isVisible();
 817:   }
 818: 
 819:   /**
 820:    * This method returns whether rollover borders have been set.
 821:    *
 822:    * @return Whether rollover borders have been set.
 823:    */
 824:   public boolean isRolloverBorders()
 825:   {
 826:     return toolBar.isRollover();
 827:   }
 828: 
 829:   /**
 830:    * This method navigates in the given direction giving focus to the next
 831:    * component in the given direction.
 832:    *
 833:    * @param direction The direction to give focus to.
 834:    */
 835:   protected void navigateFocusedComp(int direction)
 836:   {
 837:     int count = toolBar.getComponentCount();
 838:     switch (direction)
 839:     {
 840:       case EAST:
 841:       case SOUTH:
 842:         if (focusedCompIndex >= 0 && focusedCompIndex < count)
 843:           {
 844:             int i = focusedCompIndex + 1;
 845:             boolean focusRequested = false;
 846:             // Find component to focus and request focus on it.
 847:             while (i != focusedCompIndex && ! focusRequested)
 848:               {
 849:                 if (i >= count)
 850:                   i = 0;
 851:                 Component comp = toolBar.getComponentAtIndex(i++);
 852:                 if (comp != null && comp.isFocusable()
 853:                     && comp.isEnabled())
 854:                   {
 855:                     comp.requestFocus();
 856:                     focusRequested = true;
 857:                   }
 858:               }
 859:           }
 860:         break;
 861:       case WEST:
 862:       case NORTH:
 863:         if (focusedCompIndex >= 0 && focusedCompIndex < count)
 864:           {
 865:             int i = focusedCompIndex - 1;
 866:             boolean focusRequested = false;
 867:             // Find component to focus and request focus on it.
 868:             while (i != focusedCompIndex && ! focusRequested)
 869:               {
 870:                 if (i < 0)
 871:                   i = count - 1;
 872:                 Component comp = toolBar.getComponentAtIndex(i--);
 873:                 if (comp != null && comp.isFocusable()
 874:                     && comp.isEnabled())
 875:                   {
 876:                     comp.requestFocus();
 877:                     focusRequested = true;
 878:                   }
 879:               }
 880:           }
 881:         break;
 882:       default:
 883:         break;
 884:     }
 885:   }
 886: 
 887:   /**
 888:    * This method sets the border of the given component to a non rollover
 889:    * border.
 890:    *
 891:    * @param c The Component whose border needs to be set.
 892:    */
 893:   protected void setBorderToNonRollover(Component c)
 894:   {
 895:     if (c instanceof AbstractButton)
 896:       {
 897:     AbstractButton b = (AbstractButton) c;
 898:     b.setRolloverEnabled(false);
 899: 
 900:         // Save old border in hashtable.
 901:         borders.put(b, b.getBorder());
 902:         
 903:     b.setBorder(nonRolloverBorder);
 904:       }
 905:   }
 906: 
 907:   /**
 908:    * This method sets the border of the given component to its original value.
 909:    *
 910:    * @param c The Component whose border needs to be set.
 911:    */
 912:   protected void setBorderToNormal(Component c)
 913:   {
 914:     if (c instanceof AbstractButton)
 915:       {
 916:         AbstractButton b = (AbstractButton) c;
 917:         b.setRolloverEnabled(true);
 918:         b.setBorder((Border) borders.remove(b));
 919:       }
 920:   }
 921: 
 922:   /**
 923:    * This method sets the border of the given component to a rollover border.
 924:    *
 925:    * @param c The Component whose border needs to be set.
 926:    */
 927:   protected void setBorderToRollover(Component c)
 928:   {
 929:     if (c instanceof AbstractButton)
 930:       {
 931:         AbstractButton b = (AbstractButton) c;
 932:         b.setRolloverEnabled(false);
 933:         
 934:         // Save old border in hashtable.
 935:         borders.put(b, b.getBorder());
 936:         
 937:         b.setBorder(rolloverBorder);
 938:       }
 939:   }
 940: 
 941:   /**
 942:    * This method sets the docking color.
 943:    *
 944:    * @param c The docking color.
 945:    */
 946:   public void setDockingColor(Color c)
 947:   {
 948:     dockingColor = c;
 949:   }
 950: 
 951:   /**
 952:    * This method sets the floating property for the JToolBar.
 953:    *
 954:    * @param b Whether the JToolBar is floating.
 955:    * @param p FIXME
 956:    */
 957:   public void setFloating(boolean b, Point p)
 958:   {
 959:     // FIXME: use p for something. It's not location
 960:     // since we already have setFloatingLocation.
 961:     floatFrame.setVisible(b);
 962:   }
 963: 
 964:   /**
 965:    * This method sets the color displayed when the JToolBar is not in a
 966:    * dockable area.
 967:    *
 968:    * @param c The floating color.
 969:    */
 970:   public void setFloatingColor(Color c)
 971:   {
 972:     floatingColor = c;
 973:   }
 974: 
 975:   /**
 976:    * This method sets the floating location of the JToolBar.
 977:    *
 978:    * @param x The x coordinate for the floating frame.
 979:    * @param y The y coordinate for the floating frame.
 980:    */
 981:   public void setFloatingLocation(int x, int y)
 982:   {
 983:     // x,y are the coordinates of the new JFrame created to store the toolbar
 984:     // XXX: The floating location is bogus is not floating.
 985:     floatFrame.setLocation(x, y);
 986:     floatFrame.invalidate();
 987:     floatFrame.validate();
 988:     floatFrame.repaint();
 989:   }
 990: 
 991:   /**
 992:    * This is a convenience method for changing the orientation of the
 993:    * JToolBar.
 994:    *
 995:    * @param orientation The new orientation.
 996:    */
 997:   public void setOrientation(int orientation)
 998:   {
 999:     toolBar.setOrientation(orientation);
1000:   }
1001: 
1002:   /**
1003:    * This method changes the child components to have rollover borders if the
1004:    * given parameter is true. Otherwise, the components are set to have non
1005:    * rollover borders.
1006:    *
1007:    * @param rollover Whether the children will have rollover borders.
1008:    */
1009:   public void setRolloverBorders(boolean rollover)
1010:   {
1011:     if (rollover)
1012:       installRolloverBorders(toolBar);
1013:     else
1014:       installNonRolloverBorders(toolBar);
1015:   }
1016: 
1017:   /**
1018:    * This method uninstall UI installed components from the JToolBar.
1019:    */
1020:   protected void uninstallComponents()
1021:   {
1022:     installNormalBorders(toolBar);
1023:     borders = null;
1024:     cachedBounds = null;
1025: 
1026:     floatFrame = null;
1027:     dragWindow = null;
1028:   }
1029: 
1030:   /**
1031:    * This method removes the defaults installed by the Look and Feel.
1032:    */
1033:   protected void uninstallDefaults()
1034:   {
1035:     toolBar.setBackground(null);
1036:     toolBar.setForeground(null);
1037:     toolBar.setFont(null);
1038: 
1039:     dockingBorderColor = null;
1040:     dockingColor = null;
1041:     floatingBorderColor = null;
1042:     floatingColor = null;
1043:   }
1044: 
1045:   /**
1046:    * This method uninstalls keyboard actions installed by the UI.
1047:    */
1048:   protected void uninstallKeyboardActions()
1049:   {
1050:     SwingUtilities.replaceUIInputMap(toolBar, JComponent.
1051:                                      WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
1052:     SwingUtilities.replaceUIActionMap(toolBar, null);
1053:   }
1054: 
1055:   /**
1056:    * This method uninstalls listeners installed by the UI.
1057:    */
1058:   protected void uninstallListeners()
1059:   {
1060:     if (toolBarFocusListener != null)
1061:       {
1062:         int count = toolBar.getComponentCount();
1063:         for (int i = 0; i < count; i++)
1064:           toolBar.getComponent(i).removeFocusListener(toolBarFocusListener);
1065:         toolBarFocusListener = null;
1066:       }
1067: 
1068:     floatFrame.removeWindowListener(windowListener);
1069:     windowListener = null;
1070: 
1071:     toolBar.removeContainerListener(toolBarContListener);
1072:     toolBarContListener = null;
1073: 
1074:     toolBar.removeMouseMotionListener(dockingListener);
1075:     toolBar.removeMouseListener(dockingListener);
1076:     dockingListener = null;
1077:   }
1078: 
1079:   /**
1080:    * This method uninstalls the UI.
1081:    *
1082:    * @param c The JComponent that is having this UI removed.
1083:    */
1084:   public void uninstallUI(JComponent c)
1085:   {
1086:     uninstallKeyboardActions();
1087:     uninstallListeners();
1088:     uninstallComponents();
1089:     uninstallDefaults();
1090:     toolBar = null;
1091:   }
1092: 
1093:   /**
1094:    * This is the MouseHandler class that allows the user to drag the JToolBar
1095:    * in and out of the parent and dock it if it can.
1096:    */
1097:   public class DockingListener implements MouseInputListener
1098:   {
1099:     /** Whether the JToolBar is being dragged. */
1100:     protected boolean isDragging;
1101: 
1102:     /**
1103:      * The origin point. This point is saved from the beginning press and is
1104:      * used until the end of the drag session.
1105:      */
1106:     protected Point origin;
1107: 
1108:     /** The JToolBar being dragged. */
1109:     protected JToolBar toolBar;
1110: 
1111:     /**
1112:      * Creates a new DockingListener object.
1113:      *
1114:      * @param t The JToolBar this DockingListener is being used for.
1115:      */
1116:     public DockingListener(JToolBar t)
1117:     {
1118:       toolBar = t;
1119:     }
1120: 
1121:     /**
1122:      * This method is called when the mouse is clicked.
1123:      *
1124:      * @param e The MouseEvent.
1125:      */
1126:     public void mouseClicked(MouseEvent e)
1127:     {
1128:       // Nothing to do here.
1129:     }
1130: 
1131:     /**
1132:      * This method is called when the mouse is dragged. It delegates the drag
1133:      * painting to the dragTo method.
1134:      *
1135:      * @param e The MouseEvent.
1136:      */
1137:     public void mouseDragged(MouseEvent e)
1138:     {
1139:       if (isDragging)
1140:     dragTo(e.getPoint(), origin);
1141:     }
1142: 
1143:     /**
1144:      * This method is called when the mouse enters the JToolBar.
1145:      *
1146:      * @param e The MouseEvent.
1147:      */
1148:     public void mouseEntered(MouseEvent e)
1149:     {
1150:       // Nothing to do here.
1151:     }
1152: 
1153:     /**
1154:      * This method is called when the mouse exits the JToolBar.
1155:      *
1156:      * @param e The MouseEvent.
1157:      */
1158:     public void mouseExited(MouseEvent e)
1159:     {
1160:       // Nothing to do here.
1161:     }
1162: 
1163:     /**
1164:      * This method is called when the mouse is moved in the JToolBar.
1165:      *
1166:      * @param e The MouseEvent.
1167:      */
1168:     public void mouseMoved(MouseEvent e)
1169:     {
1170:       // Nothing to do here.
1171:     }
1172: 
1173:     /**
1174:      * This method is called when the mouse is pressed in the JToolBar. If the
1175:      * press doesn't occur in a place where it causes the JToolBar to be
1176:      * dragged, it returns. Otherwise, it starts a drag session.
1177:      *
1178:      * @param e The MouseEvent.
1179:      */
1180:     public void mousePressed(MouseEvent e)
1181:     {
1182:       if (! toolBar.isFloatable())
1183:     return;
1184: 
1185:       Point ssd = e.getPoint();
1186:       Insets insets = toolBar.getInsets();
1187: 
1188:       // Verify that this click occurs in the top inset.
1189:       if (toolBar.getOrientation() == SwingConstants.HORIZONTAL)
1190:         {
1191:       if (e.getX() > insets.left)
1192:         return;
1193:         }
1194:       else
1195:         {
1196:       if (e.getY() > insets.top)
1197:         return;
1198:         }
1199: 
1200:       origin = new Point(0, 0);
1201:       if (toolBar.isShowing())
1202:         SwingUtilities.convertPointToScreen(ssd, toolBar);
1203: 
1204:       if (! (SwingUtilities.getAncestorOfClass(Window.class, toolBar) instanceof UIResource))
1205:     // Need to know who keeps the toolBar if it gets dragged back into it.
1206:     origParent = toolBar.getParent();
1207:       
1208:       if (toolBar.isShowing())
1209:         SwingUtilities.convertPointToScreen(origin, toolBar);
1210: 
1211:       isDragging = true;
1212: 
1213:       if (dragWindow != null)
1214:     dragWindow.setOffset(new Point(cachedBounds.width / 2, 
1215:             cachedBounds.height / 2));
1216: 
1217:       dragTo(e.getPoint(), origin);
1218:     }
1219: 
1220:     /**
1221:      * This method is called when the mouse is released from the JToolBar.
1222:      *
1223:      * @param e The MouseEvent.
1224:      */
1225:     public void mouseReleased(MouseEvent e)
1226:     {
1227:       if (! isDragging || ! toolBar.isFloatable())
1228:     return;
1229: 
1230:       isDragging = false;
1231:       floatAt(e.getPoint(), origin);
1232:       dragWindow.hide();
1233:     }
1234:   }
1235: 
1236:   /**
1237:    * This is the window that appears when the JToolBar is being dragged
1238:    * around.
1239:    */
1240:   protected class DragWindow extends Window
1241:   {
1242:     /**
1243:      * The current border color. It changes depending on whether the JToolBar
1244:      * is over a place that allows it to dock.
1245:      */
1246:     private Color borderColor;
1247: 
1248:     /** The between the mouse and the top left corner of the window. */
1249:     private Point offset;
1250: 
1251:     /**
1252:      * Creates a new DragWindow object.
1253:      * This is package-private to avoid an accessor method.
1254:      */
1255:     DragWindow()
1256:     {
1257:       super(owner);
1258:     }
1259: 
1260:     /**
1261:      * The color that the border should be.
1262:      *
1263:      * @return The border color.
1264:      */
1265:     public Color getBorderColor()
1266:     {
1267:       if (borderColor == null)
1268:     return Color.BLACK;
1269: 
1270:       return borderColor;
1271:     }
1272: 
1273:     /**
1274:      * This method returns the insets for the DragWindow.
1275:      *
1276:      * @return The insets for the DragWindow.
1277:      */
1278:     public Insets getInsets()
1279:     {
1280:       // This window has no decorations, so insets are empty.
1281:       return new Insets(0, 0, 0, 0);
1282:     }
1283: 
1284:     /**
1285:      * This method returns the mouse offset from the top left corner of the
1286:      * DragWindow.
1287:      *
1288:      * @return The mouse offset.
1289:      */
1290:     public Point getOffset()
1291:     {
1292:       return offset;
1293:     }
1294: 
1295:     /**
1296:      * This method paints the DragWindow.
1297:      *
1298:      * @param g The Graphics object to paint with.
1299:      */
1300:     public void paint(Graphics g)
1301:     {
1302:       //  No visiting children necessary.
1303:       Color saved = g.getColor();
1304:       Rectangle b = getBounds();
1305: 
1306:       g.setColor(getBorderColor());
1307:       g.drawRect(0, 0, b.width - 1, b.height - 1);
1308: 
1309:       g.setColor(saved);
1310:     }
1311: 
1312:     /**
1313:      * This method changes the border color.
1314:      *
1315:      * @param c The new border color.
1316:      */
1317:     public void setBorderColor(Color c)
1318:     {
1319:       borderColor = c;
1320:     }
1321: 
1322:     /**
1323:      * This method changes the mouse offset.
1324:      *
1325:      * @param p The new mouse offset.
1326:      */
1327:     public void setOffset(Point p)
1328:     {
1329:       offset = p;
1330:     }
1331: 
1332:     /**
1333:      * Sets the orientation of the toolbar and the
1334:      * drag window.
1335:      *
1336:      * @param o - the new orientation of the toolbar and drag
1337:      * window.
1338:      */
1339:     public void setOrientation(int o)
1340:     {
1341:       toolBar.setOrientation(o);
1342:       if (dragWindow != null) 
1343:         dragWindow.setOrientation(o);
1344:     }
1345:   }
1346: 
1347:   /**
1348:    * This helper class listens for Window events from the floatable window and
1349:    * if it is closed, returns the JToolBar to the last known good location.
1350:    */
1351:   protected class FrameListener extends WindowAdapter
1352:   {
1353:     /**
1354:      * This method is called when the floating window is closed.
1355:      *
1356:      * @param e The WindowEvent.
1357:      */
1358:     public void windowClosing(WindowEvent e)
1359:     {
1360:       Container parent = toolBar.getParent();
1361:       parent.remove(toolBar);
1362: 
1363:       if (origParent != null)
1364:         {
1365:       origParent.add(toolBar,
1366:                      (constraintBeforeFloating != null)
1367:                      ? constraintBeforeFloating : BorderLayout.NORTH);
1368:       toolBar.setOrientation(lastGoodOrientation);
1369:         }
1370: 
1371:       origParent.invalidate();
1372:       origParent.validate();
1373:       origParent.repaint();
1374:     }
1375:   }
1376: 
1377:   /**
1378:    * This helper class listens for PropertyChangeEvents from the JToolBar.
1379:    */
1380:   protected class PropertyListener implements PropertyChangeListener
1381:   {
1382:     /**
1383:      * This method is called when a property from the JToolBar is changed.
1384:      *
1385:      * @param e The PropertyChangeEvent.
1386:      */
1387:     public void propertyChange(PropertyChangeEvent e)
1388:     {
1389:       // FIXME: need name properties so can change floatFrame title.
1390:       if (e.getPropertyName().equals("rollover") && toolBar != null)
1391:         setRolloverBorders(toolBar.isRollover());
1392:     }
1393:   }
1394: 
1395:   /**
1396:    * This helper class listens for components added to and removed from the
1397:    * JToolBar.
1398:    */
1399:   protected class ToolBarContListener implements ContainerListener
1400:   {
1401:     /**
1402:      * This method is responsible for setting rollover or non rollover for new
1403:      * buttons added to the JToolBar.
1404:      *
1405:      * @param e The ContainerEvent.
1406:      */
1407:     public void componentAdded(ContainerEvent e)
1408:     {
1409:       if (e.getChild() instanceof JButton)
1410:         {
1411:       JButton b = (JButton) e.getChild();
1412: 
1413:       if (b.getBorder() != null)
1414:         borders.put(b, b.getBorder());
1415:         }
1416: 
1417:       if (isRolloverBorders())
1418:     setBorderToRollover(e.getChild());
1419:       else
1420:     setBorderToNonRollover(e.getChild());
1421: 
1422:       cachedBounds = toolBar.getPreferredSize();
1423:       cachedOrientation = toolBar.getOrientation();
1424: 
1425:       Component c = e.getChild();
1426:       if (toolBarFocusListener != null)
1427:         c.addFocusListener(toolBarFocusListener);
1428:     }
1429: 
1430:     /**
1431:      * This method is responsible for giving the child components their
1432:      * original borders when they are removed.
1433:      *
1434:      * @param e The ContainerEvent.
1435:      */
1436:     public void componentRemoved(ContainerEvent e)
1437:     {
1438:       setBorderToNormal(e.getChild());
1439:       cachedBounds = toolBar.getPreferredSize();
1440:       cachedOrientation = toolBar.getOrientation();
1441: 
1442:       Component c = e.getChild();
1443:       if (toolBarFocusListener != null)
1444:         c.removeFocusListener(toolBarFocusListener);
1445:     }
1446:   }
1447: 
1448:   /**
1449:    * This is the floating window that is returned when getFloatingWindow is
1450:    * called.
1451:    */
1452:   private class ToolBarDialog extends JDialog implements UIResource
1453:   {
1454:     /**
1455:      * Creates a new ToolBarDialog object with the name given by the JToolBar.
1456:      */
1457:     public ToolBarDialog()
1458:     {
1459:       super();
1460:       setName((toolBar.getName() != null) ? toolBar.getName() : "");
1461:     }
1462:   }
1463: 
1464:   /**
1465:    * DOCUMENT ME!
1466:    */
1467:   protected class ToolBarFocusListener implements FocusListener
1468:   {
1469:     /**
1470:      * Creates a new ToolBarFocusListener object.
1471:      */
1472:     protected ToolBarFocusListener()
1473:     {
1474:       // Nothing to do here.
1475:     }
1476: 
1477:     /**
1478:      * Receives notification when the toolbar or one of it's component
1479:      * receives the keyboard input focus.
1480:      * 
1481:      * @param e the focus event
1482:      */
1483:     public void focusGained(FocusEvent e)
1484:     {
1485:       Component c = e.getComponent();
1486:       focusedCompIndex = toolBar.getComponentIndex(c);
1487:     }
1488: 
1489:     /**
1490:      * Receives notification when the toolbar or one of it's component
1491:      * looses the keyboard input focus.
1492:      * 
1493:      * @param e the focus event
1494:      */
1495:     public void focusLost(FocusEvent e)
1496:     {
1497:       // Do nothing here.
1498:     }
1499:   }
1500: 
1501:   /**
1502:    * This helper class acts as the border for the JToolBar.
1503:    */
1504:   private static class ToolBarBorder implements Border
1505:   {
1506:     /** The size of the larger, draggable side of the border. */
1507:     private static final int offset = 10;
1508: 
1509:     /** The other sides. */
1510:     private static final int regular = 2;
1511: 
1512:     /**
1513:      * This method returns the border insets for the JToolBar.
1514:      *
1515:      * @param c The Component to find insets for.
1516:      *
1517:      * @return The border insets.
1518:      */
1519:     public Insets getBorderInsets(Component c)
1520:     {
1521:       if (c instanceof JToolBar)
1522:         {
1523:       JToolBar tb = (JToolBar) c;
1524:       int orientation = tb.getOrientation();
1525: 
1526:       if (! tb.isFloatable())
1527:         return new Insets(regular, regular, regular, regular);
1528:       else if (orientation == SwingConstants.HORIZONTAL)
1529:         return new Insets(regular, offset, regular, regular);
1530:       else
1531:         return new Insets(offset, regular, regular, regular);
1532:         }
1533: 
1534:       return new Insets(0, 0, 0, 0);
1535:     }
1536: 
1537:     /**
1538:      * This method returns whether the border is opaque.
1539:      *
1540:      * @return Whether the border is opaque.
1541:      */
1542:     public boolean isBorderOpaque()
1543:     {
1544:       return false;
1545:     }
1546: 
1547:     /**
1548:      * This method paints the ribbed area of the border.
1549:      *
1550:      * @param g The Graphics object to paint with.
1551:      * @param x The x coordinate of the area.
1552:      * @param y The y coordinate of the area.
1553:      * @param w The width of the area.
1554:      * @param h The height of the area.
1555:      * @param size The size of the bump.
1556:      * @param c The color of the bumps.
1557:      */
1558:     private void paintBumps(Graphics g, int x, int y, int w, int h, int size,
1559:                             Color c)
1560:     {
1561:       Color saved = g.getColor();
1562:       g.setColor(c);
1563: 
1564:       int hgap = 2 * size;
1565:       int vgap = 4 * size;
1566:       int count = 0;
1567: 
1568:       for (int i = x; i < (w + x); i += hgap)
1569:     for (int j = ((count++ % 2) == 0) ? y : (y + (2 * size)); j < (h + y);
1570:          j += vgap)
1571:       g.fillRect(i, j, size, size);
1572: 
1573:       g.setColor(saved);
1574:     }
1575: 
1576:     /**
1577:      * This method paints the border around the given Component.
1578:      *
1579:      * @param c The Component whose border is being painted.
1580:      * @param g The Graphics object to paint with.
1581:      * @param x The x coordinate of the component.
1582:      * @param y The y coordinate of the component.
1583:      * @param width The width of the component.
1584:      * @param height The height of the component.
1585:      */
1586:     public void paintBorder(Component c, Graphics g, int x, int y, int width,
1587:                             int height)
1588:     {
1589:       if (c instanceof JToolBar)
1590:         {
1591:       JToolBar tb = (JToolBar) c;
1592: 
1593:       int orientation = tb.getOrientation();
1594: 
1595:       if (orientation == SwingConstants.HORIZONTAL)
1596:         {
1597:           paintBumps(g, x, y, offset, height, 1, Color.WHITE);
1598:           paintBumps(g, x + 1, y + 1, offset - 1, height - 1, 1, Color.GRAY);
1599:         }
1600:       else
1601:         {
1602:           paintBumps(g, x, y, width, offset, 1, Color.WHITE);
1603:           paintBumps(g, x + 1, y + 1, width - 1, offset - 1, 1, Color.GRAY);
1604:         }
1605:         }
1606:     }
1607:   }
1608: }