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