Source for javax.swing.plaf.basic.BasicToolBarUI

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