1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.plaf.basic;
  27 
  28 import javax.swing.*;
  29 import javax.swing.event.*;
  30 import java.awt.*;
  31 import java.awt.event.*;
  32 
  33 import java.beans.*;
  34 
  35 import java.util.Hashtable;
  36 import java.util.HashMap;
  37 
  38 import javax.swing.border.*;
  39 import javax.swing.plaf.*;
  40 import sun.swing.DefaultLookup;
  41 import sun.swing.UIAction;
  42 
  43 
  44 /**
  45  * A Basic L&F implementation of ToolBarUI.  This implementation
  46  * is a "combined" view/controller.
  47  *
  48  * @author Georges Saab
  49  * @author Jeff Shapiro
  50  */
  51 public class BasicToolBarUI extends ToolBarUI implements SwingConstants
  52 {
  53     /**
  54      * The instance of {@code JToolBar}.
  55      */
  56     protected JToolBar toolBar;
  57     private boolean floating;
  58     private int floatingX;
  59     private int floatingY;
  60     private JFrame floatingFrame;
  61     private RootPaneContainer floatingToolBar;
  62     /**
  63      * The instance of {@code DragWindow}.
  64      */
  65     protected DragWindow dragWindow;
  66     private Container dockingSource;
  67     private int dockingSensitivity = 0;
  68     /**
  69      * The index of the focused component.
  70      */
  71     protected int focusedCompIndex = -1;
  72 
  73     /**
  74      * The background color of the docking border.
  75      */
  76     protected Color dockingColor = null;
  77     /**
  78      * The background color of the not docking border.
  79      */
  80     protected Color floatingColor = null;
  81     /**
  82      * The color of the docking border.
  83      */
  84     protected Color dockingBorderColor = null;
  85     /**
  86      * The color of the not docking border.
  87      */
  88     protected Color floatingBorderColor = null;
  89 
  90     /**
  91      * The instance of a {@code MouseInputListener}.
  92      */
  93     protected MouseInputListener dockingListener;
  94     /**
  95      * The instance of a {@code PropertyChangeListener}.
  96      */
  97     protected PropertyChangeListener propertyListener;
  98 
  99     /**
 100      * The instance of a {@code ContainerListener}.
 101      */
 102     protected ContainerListener toolBarContListener;
 103     /**
 104      * The instance of a {@code FocusListener}.
 105      */
 106     protected FocusListener toolBarFocusListener;
 107     private Handler handler;
 108 
 109     /**
 110      * The layout before floating.
 111      */
 112     protected String constraintBeforeFloating = BorderLayout.NORTH;
 113 
 114     // Rollover button implementation.
 115     private static String IS_ROLLOVER = "JToolBar.isRollover";
 116     private static Border rolloverBorder;
 117     private static Border nonRolloverBorder;
 118     private static Border nonRolloverToggleBorder;
 119     private boolean rolloverBorders = false;
 120 
 121     private HashMap<AbstractButton, Border> borderTable = new HashMap<AbstractButton, Border>();
 122     private Hashtable<AbstractButton, Boolean> rolloverTable = new Hashtable<AbstractButton, Boolean>();
 123 
 124 
 125     /**
 126      * As of Java 2 platform v1.3 this previously undocumented field is no
 127      * longer used.
 128      * Key bindings are now defined by the LookAndFeel, please refer to
 129      * the key bindings specification for further details.
 130      *
 131      * @deprecated As of Java 2 platform v1.3.
 132      */
 133     @Deprecated
 134     protected KeyStroke upKey;
 135     /**
 136      * As of Java 2 platform v1.3 this previously undocumented field is no
 137      * longer used.
 138      * Key bindings are now defined by the LookAndFeel, please refer to
 139      * the key bindings specification for further details.
 140      *
 141      * @deprecated As of Java 2 platform v1.3.
 142      */
 143     @Deprecated
 144     protected KeyStroke downKey;
 145     /**
 146      * As of Java 2 platform v1.3 this previously undocumented field is no
 147      * longer used.
 148      * Key bindings are now defined by the LookAndFeel, please refer to
 149      * the key bindings specification for further details.
 150      *
 151      * @deprecated As of Java 2 platform v1.3.
 152      */
 153     @Deprecated
 154     protected KeyStroke leftKey;
 155     /**
 156      * As of Java 2 platform v1.3 this previously undocumented field is no
 157      * longer used.
 158      * Key bindings are now defined by the LookAndFeel, please refer to
 159      * the key bindings specification for further details.
 160      *
 161      * @deprecated As of Java 2 platform v1.3.
 162      */
 163     @Deprecated
 164     protected KeyStroke rightKey;
 165 
 166 
 167     private static String FOCUSED_COMP_INDEX = "JToolBar.focusedCompIndex";
 168 
 169     /**
 170      * Constructs a new instance of {@code BasicToolBarUI}.
 171      *
 172      * @param c a component
 173      * @return a new instance of {@code BasicToolBarUI}
 174      */
 175     public static ComponentUI createUI( JComponent c )
 176     {
 177         return new BasicToolBarUI();
 178     }
 179 
 180     public void installUI( JComponent c )
 181     {
 182         toolBar = (JToolBar) c;
 183 
 184         // Set defaults
 185         installDefaults();
 186         installComponents();
 187         installListeners();
 188         installKeyboardActions();
 189 
 190         // Initialize instance vars
 191         dockingSensitivity = 0;
 192         floating = false;
 193         floatingX = floatingY = 0;
 194         floatingToolBar = null;
 195 
 196         setOrientation( toolBar.getOrientation() );
 197         LookAndFeel.installProperty(c, "opaque", Boolean.TRUE);
 198 
 199         if ( c.getClientProperty( FOCUSED_COMP_INDEX ) != null )
 200         {
 201             focusedCompIndex = ( (Integer) ( c.getClientProperty( FOCUSED_COMP_INDEX ) ) ).intValue();
 202         }
 203     }
 204 
 205     public void uninstallUI( JComponent c )
 206     {
 207 
 208         // Clear defaults
 209         uninstallDefaults();
 210         uninstallComponents();
 211         uninstallListeners();
 212         uninstallKeyboardActions();
 213 
 214         // Clear instance vars
 215         if (isFloating())
 216             setFloating(false, null);
 217 
 218         floatingToolBar = null;
 219         dragWindow = null;
 220         dockingSource = null;
 221 
 222         c.putClientProperty( FOCUSED_COMP_INDEX, Integer.valueOf( focusedCompIndex ) );
 223     }
 224 
 225     /**
 226      * Installs default properties.
 227      */
 228     protected void installDefaults( )
 229     {
 230         LookAndFeel.installBorder(toolBar,"ToolBar.border");
 231         LookAndFeel.installColorsAndFont(toolBar,
 232                                               "ToolBar.background",
 233                                               "ToolBar.foreground",
 234                                               "ToolBar.font");
 235         // Toolbar specific defaults
 236         if ( dockingColor == null || dockingColor instanceof UIResource )
 237             dockingColor = UIManager.getColor("ToolBar.dockingBackground");
 238         if ( floatingColor == null || floatingColor instanceof UIResource )
 239             floatingColor = UIManager.getColor("ToolBar.floatingBackground");
 240         if ( dockingBorderColor == null ||
 241              dockingBorderColor instanceof UIResource )
 242             dockingBorderColor = UIManager.getColor("ToolBar.dockingForeground");
 243         if ( floatingBorderColor == null ||
 244              floatingBorderColor instanceof UIResource )
 245             floatingBorderColor = UIManager.getColor("ToolBar.floatingForeground");
 246 
 247         // ToolBar rollover button borders
 248         Object rolloverProp = toolBar.getClientProperty( IS_ROLLOVER );
 249         if (rolloverProp == null) {
 250             rolloverProp = UIManager.get("ToolBar.isRollover");
 251         }
 252         if ( rolloverProp != null ) {
 253             rolloverBorders = ((Boolean)rolloverProp).booleanValue();
 254         }
 255 
 256         if (rolloverBorder == null) {
 257             rolloverBorder = createRolloverBorder();
 258         }
 259         if (nonRolloverBorder == null) {
 260             nonRolloverBorder = createNonRolloverBorder();
 261         }
 262         if (nonRolloverToggleBorder == null) {
 263             nonRolloverToggleBorder = createNonRolloverToggleBorder();
 264         }
 265 
 266 
 267         setRolloverBorders( isRolloverBorders() );
 268     }
 269 
 270     /**
 271      * Uninstalls default properties.
 272      */
 273     protected void uninstallDefaults( )
 274     {
 275         LookAndFeel.uninstallBorder(toolBar);
 276         dockingColor = null;
 277         floatingColor = null;
 278         dockingBorderColor = null;
 279         floatingBorderColor = null;
 280 
 281         installNormalBorders(toolBar);
 282 
 283         rolloverBorder = null;
 284         nonRolloverBorder = null;
 285         nonRolloverToggleBorder = null;
 286     }
 287 
 288     /**
 289      * Registers components.
 290      */
 291     protected void installComponents( )
 292     {
 293     }
 294 
 295     /**
 296      * Unregisters components.
 297      */
 298     protected void uninstallComponents( )
 299     {
 300     }
 301 
 302     /**
 303      * Registers listeners.
 304      */
 305     protected void installListeners( )
 306     {
 307         dockingListener = createDockingListener( );
 308 
 309         if ( dockingListener != null )
 310         {
 311             toolBar.addMouseMotionListener( dockingListener );
 312             toolBar.addMouseListener( dockingListener );
 313         }
 314 
 315         propertyListener = createPropertyListener();  // added in setFloating
 316         if (propertyListener != null) {
 317             toolBar.addPropertyChangeListener(propertyListener);
 318         }
 319 
 320         toolBarContListener = createToolBarContListener();
 321         if ( toolBarContListener != null ) {
 322             toolBar.addContainerListener( toolBarContListener );
 323         }
 324 
 325         toolBarFocusListener = createToolBarFocusListener();
 326 
 327         if ( toolBarFocusListener != null )
 328         {
 329             // Put focus listener on all components in toolbar
 330             Component[] components = toolBar.getComponents();
 331 
 332             for (Component component : components) {
 333                 component.addFocusListener(toolBarFocusListener);
 334             }
 335         }
 336     }
 337 
 338     /**
 339      * Unregisters listeners.
 340      */
 341     protected void uninstallListeners( )
 342     {
 343         if ( dockingListener != null )
 344         {
 345             toolBar.removeMouseMotionListener(dockingListener);
 346             toolBar.removeMouseListener(dockingListener);
 347 
 348             dockingListener = null;
 349         }
 350 
 351         if ( propertyListener != null )
 352         {
 353             toolBar.removePropertyChangeListener(propertyListener);
 354             propertyListener = null;  // removed in setFloating
 355         }
 356 
 357         if ( toolBarContListener != null )
 358         {
 359             toolBar.removeContainerListener( toolBarContListener );
 360             toolBarContListener = null;
 361         }
 362 
 363         if ( toolBarFocusListener != null )
 364         {
 365             // Remove focus listener from all components in toolbar
 366             Component[] components = toolBar.getComponents();
 367 
 368             for (Component component : components) {
 369                 component.removeFocusListener(toolBarFocusListener);
 370             }
 371 
 372             toolBarFocusListener = null;
 373         }
 374         handler = null;
 375     }
 376 
 377     /**
 378      * Registers keyboard actions.
 379      */
 380     protected void installKeyboardActions( )
 381     {
 382         InputMap km = getInputMap(JComponent.
 383                                   WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
 384 
 385         SwingUtilities.replaceUIInputMap(toolBar, JComponent.
 386                                          WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
 387                                          km);
 388 
 389     LazyActionMap.installLazyActionMap(toolBar, BasicToolBarUI.class,
 390             "ToolBar.actionMap");
 391     }
 392 
 393     InputMap getInputMap(int condition) {
 394         if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
 395             return (InputMap)DefaultLookup.get(toolBar, this,
 396                     "ToolBar.ancestorInputMap");
 397         }
 398         return null;
 399     }
 400 
 401     static void loadActionMap(LazyActionMap map) {
 402         map.put(new Actions(Actions.NAVIGATE_RIGHT));
 403         map.put(new Actions(Actions.NAVIGATE_LEFT));
 404         map.put(new Actions(Actions.NAVIGATE_UP));
 405         map.put(new Actions(Actions.NAVIGATE_DOWN));
 406     }
 407 
 408     /**
 409      * Unregisters keyboard actions.
 410      */
 411     protected void uninstallKeyboardActions( )
 412     {
 413         SwingUtilities.replaceUIActionMap(toolBar, null);
 414         SwingUtilities.replaceUIInputMap(toolBar, JComponent.
 415                                          WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
 416                                          null);
 417     }
 418 
 419     /**
 420      * Navigates the focused component.
 421      *
 422      * @param direction a direction
 423      */
 424     protected void navigateFocusedComp(int direction)
 425     {
 426         int nComp = toolBar.getComponentCount();
 427         int j;
 428 
 429         switch ( direction )
 430         {
 431             case EAST:
 432             case SOUTH:
 433 
 434                 if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;
 435 
 436                 j = focusedCompIndex + 1;
 437 
 438                 while ( j != focusedCompIndex )
 439                 {
 440                     if ( j >= nComp ) j = 0;
 441                     Component comp = toolBar.getComponentAtIndex( j++ );
 442 
 443                     if ( comp != null && comp.isFocusTraversable() && comp.isEnabled() )
 444                     {
 445                         comp.requestFocus();
 446                         break;
 447                     }
 448                 }
 449 
 450                 break;
 451 
 452             case WEST:
 453             case NORTH:
 454 
 455                 if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;
 456 
 457                 j = focusedCompIndex - 1;
 458 
 459                 while ( j != focusedCompIndex )
 460                 {
 461                     if ( j < 0 ) j = nComp - 1;
 462                     Component comp = toolBar.getComponentAtIndex( j-- );
 463 
 464                     if ( comp != null && comp.isFocusTraversable() && comp.isEnabled() )
 465                     {
 466                         comp.requestFocus();
 467                         break;
 468                     }
 469                 }
 470 
 471                 break;
 472 
 473             default:
 474                 break;
 475         }
 476     }
 477 
 478     /**
 479      * Creates a rollover border for toolbar components. The
 480      * rollover border will be installed if rollover borders are
 481      * enabled.
 482      * <p>
 483      * Override this method to provide an alternate rollover border.
 484      *
 485      * @return a rollover border for toolbar components
 486      * @since 1.4
 487      */
 488     protected Border createRolloverBorder() {
 489         Object border = UIManager.get("ToolBar.rolloverBorder");
 490         if (border != null) {
 491             return (Border)border;
 492         }
 493         UIDefaults table = UIManager.getLookAndFeelDefaults();
 494         return new CompoundBorder(new BasicBorders.RolloverButtonBorder(
 495                                            table.getColor("controlShadow"),
 496                                            table.getColor("controlDkShadow"),
 497                                            table.getColor("controlHighlight"),
 498                                            table.getColor("controlLtHighlight")),
 499                                   new BasicBorders.RolloverMarginBorder());
 500     }
 501 
 502     /**
 503      * Creates the non rollover border for toolbar components. This
 504      * border will be installed as the border for components added
 505      * to the toolbar if rollover borders are not enabled.
 506      * <p>
 507      * Override this method to provide an alternate rollover border.
 508      *
 509      * @return the non rollover border for toolbar components
 510      * @since 1.4
 511      */
 512     protected Border createNonRolloverBorder() {
 513         Object border = UIManager.get("ToolBar.nonrolloverBorder");
 514         if (border != null) {
 515             return (Border)border;
 516         }
 517         UIDefaults table = UIManager.getLookAndFeelDefaults();
 518         return new CompoundBorder(new BasicBorders.ButtonBorder(
 519                                            table.getColor("Button.shadow"),
 520                                            table.getColor("Button.darkShadow"),
 521                                            table.getColor("Button.light"),
 522                                            table.getColor("Button.highlight")),
 523                                   new BasicBorders.RolloverMarginBorder());
 524     }
 525 
 526     /**
 527      * Creates a non rollover border for Toggle buttons in the toolbar.
 528      */
 529     private Border createNonRolloverToggleBorder() {
 530         UIDefaults table = UIManager.getLookAndFeelDefaults();
 531         return new CompoundBorder(new BasicBorders.RadioButtonBorder(
 532                                            table.getColor("ToggleButton.shadow"),
 533                                            table.getColor("ToggleButton.darkShadow"),
 534                                            table.getColor("ToggleButton.light"),
 535                                            table.getColor("ToggleButton.highlight")),
 536                                   new BasicBorders.RolloverMarginBorder());
 537     }
 538 
 539     /**
 540      * No longer used, use BasicToolBarUI.createFloatingWindow(JToolBar)
 541      *
 542      * @param toolbar an instance of {@code JToolBar}
 543      * @return an instance of {@code JFrame}
 544      * @see #createFloatingWindow
 545      */
 546     protected JFrame createFloatingFrame(JToolBar toolbar) {
 547         Window window = SwingUtilities.getWindowAncestor(toolbar);
 548         @SuppressWarnings("serial") // anonymous class
 549         JFrame frame = new JFrame(toolbar.getName(),
 550                                   (window != null) ? window.getGraphicsConfiguration() : null) {
 551             // Override createRootPane() to automatically resize
 552             // the frame when contents change
 553             protected JRootPane createRootPane() {
 554                 @SuppressWarnings("serial") // anonymous class
 555                 JRootPane rootPane = new JRootPane() {
 556                     private boolean packing = false;
 557 
 558                     public void validate() {
 559                         super.validate();
 560                         if (!packing) {
 561                             packing = true;
 562                             pack();
 563                             packing = false;
 564                         }
 565                     }
 566                 };
 567                 rootPane.setOpaque(true);
 568                 return rootPane;
 569             }
 570         };
 571         frame.getRootPane().setName("ToolBar.FloatingFrame");
 572         frame.setResizable(false);
 573         WindowListener wl = createFrameListener();
 574         frame.addWindowListener(wl);
 575         return frame;
 576     }
 577 
 578     /**
 579      * Creates a window which contains the toolbar after it has been
 580      * dragged out from its container
 581      *
 582      * @param toolbar an instance of {@code JToolBar}
 583      * @return a {@code RootPaneContainer} object, containing the toolbar
 584      * @since 1.4
 585      */
 586     protected RootPaneContainer createFloatingWindow(JToolBar toolbar) {
 587         @SuppressWarnings("serial") // Superclass is not serializable across versions
 588         class ToolBarDialog extends JDialog {
 589             public ToolBarDialog(Frame owner, String title, boolean modal) {
 590                 super(owner, title, modal);
 591             }
 592 
 593             public ToolBarDialog(Dialog owner, String title, boolean modal) {
 594                 super(owner, title, modal);
 595             }
 596 
 597             // Override createRootPane() to automatically resize
 598             // the frame when contents change
 599             protected JRootPane createRootPane() {
 600                 @SuppressWarnings("serial") // anonymous class
 601                 JRootPane rootPane = new JRootPane() {
 602                     private boolean packing = false;
 603 
 604                     public void validate() {
 605                         super.validate();
 606                         if (!packing) {
 607                             packing = true;
 608                             pack();
 609                             packing = false;
 610                         }
 611                     }
 612                 };
 613                 rootPane.setOpaque(true);
 614                 return rootPane;
 615             }
 616         }
 617 
 618         JDialog dialog;
 619         Window window = SwingUtilities.getWindowAncestor(toolbar);
 620         if (window instanceof Frame) {
 621             dialog = new ToolBarDialog((Frame)window, toolbar.getName(), false);
 622         } else if (window instanceof Dialog) {
 623             dialog = new ToolBarDialog((Dialog)window, toolbar.getName(), false);
 624         } else {
 625             dialog = new ToolBarDialog((Frame)null, toolbar.getName(), false);
 626         }
 627 
 628         dialog.getRootPane().setName("ToolBar.FloatingWindow");
 629         dialog.setTitle(toolbar.getName());
 630         dialog.setResizable(false);
 631         WindowListener wl = createFrameListener();
 632         dialog.addWindowListener(wl);
 633         return dialog;
 634     }
 635 
 636     /**
 637      * Returns an instance of {@code DragWindow}.
 638      *
 639      * @param toolbar an instance of {@code JToolBar}
 640      * @return an instance of {@code DragWindow}
 641      */
 642     protected DragWindow createDragWindow(JToolBar toolbar) {
 643         Window frame = null;
 644         if(toolBar != null) {
 645             Container p;
 646             for(p = toolBar.getParent() ; p != null && !(p instanceof Window) ;
 647                 p = p.getParent());
 648             if(p != null && p instanceof Window)
 649                 frame = (Window) p;
 650         }
 651         if(floatingToolBar == null) {
 652             floatingToolBar = createFloatingWindow(toolBar);
 653         }
 654         if (floatingToolBar instanceof Window) frame = (Window) floatingToolBar;
 655         DragWindow dragWindow = new DragWindow(frame);
 656         return dragWindow;
 657     }
 658 
 659     /**
 660      * Returns a flag to determine whether rollover button borders
 661      * are enabled.
 662      *
 663      * @return true if rollover borders are enabled; false otherwise
 664      * @see #setRolloverBorders
 665      * @since 1.4
 666      */
 667     public boolean isRolloverBorders() {
 668         return rolloverBorders;
 669     }
 670 
 671     /**
 672      * Sets the flag for enabling rollover borders on the toolbar and it will
 673      * also install the appropriate border depending on the state of the flag.
 674      *
 675      * @param rollover if true, rollover borders are installed.
 676      *        Otherwise non-rollover borders are installed
 677      * @see #isRolloverBorders
 678      * @since 1.4
 679      */
 680     public void setRolloverBorders( boolean rollover ) {
 681         rolloverBorders = rollover;
 682 
 683         if ( rolloverBorders )  {
 684             installRolloverBorders( toolBar );
 685         } else  {
 686             installNonRolloverBorders( toolBar );
 687         }
 688     }
 689 
 690     /**
 691      * Installs rollover borders on all the child components of the JComponent.
 692      * <p>
 693      * This is a convenience method to call <code>setBorderToRollover</code>
 694      * for each child component.
 695      *
 696      * @param c container which holds the child components (usually a JToolBar)
 697      * @see #setBorderToRollover
 698      * @since 1.4
 699      */
 700     protected void installRolloverBorders ( JComponent c )  {
 701         // Put rollover borders on buttons
 702         Component[] components = c.getComponents();
 703 
 704         for (Component component : components) {
 705             if (component instanceof JComponent) {
 706                 ((JComponent) component).updateUI();
 707                 setBorderToRollover(component);
 708             }
 709         }
 710     }
 711 
 712     /**
 713      * Installs non-rollover borders on all the child components of the JComponent.
 714      * A non-rollover border is the border that is installed on the child component
 715      * while it is in the toolbar.
 716      * <p>
 717      * This is a convenience method to call <code>setBorderToNonRollover</code>
 718      * for each child component.
 719      *
 720      * @param c container which holds the child components (usually a JToolBar)
 721      * @see #setBorderToNonRollover
 722      * @since 1.4
 723      */
 724     protected void installNonRolloverBorders ( JComponent c )  {
 725         // Put non-rollover borders on buttons. These borders reduce the margin.
 726         Component[] components = c.getComponents();
 727 
 728         for (Component component : components) {
 729             if (component instanceof JComponent) {
 730                 ((JComponent) component).updateUI();
 731                 setBorderToNonRollover(component);
 732             }
 733         }
 734     }
 735 
 736     /**
 737      * Installs normal borders on all the child components of the JComponent.
 738      * A normal border is the original border that was installed on the child
 739      * component before it was added to the toolbar.
 740      * <p>
 741      * This is a convenience method to call <code>setBorderNormal</code>
 742      * for each child component.
 743      *
 744      * @param c container which holds the child components (usually a JToolBar)
 745      * @see #setBorderToNonRollover
 746      * @since 1.4
 747      */
 748     protected void installNormalBorders ( JComponent c )  {
 749         // Put back the normal borders on buttons
 750         Component[] components = c.getComponents();
 751 
 752         for (Component component : components) {
 753             setBorderToNormal(component);
 754         }
 755     }
 756 
 757     /**
 758      * Sets the border of the component to have a rollover border which
 759      * was created by the {@link #createRolloverBorder} method.
 760      *
 761      * @param c component which will have a rollover border installed
 762      * @see #createRolloverBorder
 763      * @since 1.4
 764      */
 765     protected void setBorderToRollover(Component c) {
 766         if (c instanceof AbstractButton) {
 767             AbstractButton b = (AbstractButton)c;
 768 
 769             Border border = borderTable.get(b);
 770             if (border == null || border instanceof UIResource) {
 771                 borderTable.put(b, b.getBorder());
 772             }
 773 
 774             // Only set the border if its the default border
 775             if (b.getBorder() instanceof UIResource) {
 776                 b.setBorder(getRolloverBorder(b));
 777             }
 778 
 779             rolloverTable.put(b, b.isRolloverEnabled()?
 780                               Boolean.TRUE: Boolean.FALSE);
 781             b.setRolloverEnabled(true);
 782         }
 783     }
 784 
 785     /**
 786      * Returns a rollover border for the button.
 787      *
 788      * @param b the button to calculate the rollover border for
 789      * @return the rollover border
 790      * @see #setBorderToRollover
 791      * @since 1.6
 792      */
 793     protected Border getRolloverBorder(AbstractButton b) {
 794         return rolloverBorder;
 795     }
 796 
 797     /**
 798      * Sets the border of the component to have a non-rollover border which
 799      * was created by the {@link #createNonRolloverBorder} method.
 800      *
 801      * @param c component which will have a non-rollover border installed
 802      * @see #createNonRolloverBorder
 803      * @since 1.4
 804      */
 805     protected void setBorderToNonRollover(Component c) {
 806         if (c instanceof AbstractButton) {
 807             AbstractButton b = (AbstractButton)c;
 808 
 809             Border border = borderTable.get(b);
 810             if (border == null || border instanceof UIResource) {
 811                 borderTable.put(b, b.getBorder());
 812             }
 813 
 814             // Only set the border if its the default border
 815             if (b.getBorder() instanceof UIResource) {
 816                 b.setBorder(getNonRolloverBorder(b));
 817             }
 818             rolloverTable.put(b, b.isRolloverEnabled()?
 819                               Boolean.TRUE: Boolean.FALSE);
 820             b.setRolloverEnabled(false);
 821         }
 822     }
 823 
 824     /**
 825      * Returns a non-rollover border for the button.
 826      *
 827      * @param b the button to calculate the non-rollover border for
 828      * @return the non-rollover border
 829      * @see #setBorderToNonRollover
 830      * @since 1.6
 831      */
 832     protected Border getNonRolloverBorder(AbstractButton b) {
 833         if (b instanceof JToggleButton) {
 834             return nonRolloverToggleBorder;
 835         } else {
 836             return nonRolloverBorder;
 837         }
 838     }
 839 
 840     /**
 841      * Sets the border of the component to have a normal border.
 842      * A normal border is the original border that was installed on the child
 843      * component before it was added to the toolbar.
 844      *
 845      * @param c component which will have a normal border re-installed
 846      * @see #createNonRolloverBorder
 847      * @since 1.4
 848      */
 849     protected void setBorderToNormal(Component c) {
 850         if (c instanceof AbstractButton) {
 851             AbstractButton b = (AbstractButton)c;
 852 
 853             Border border = borderTable.remove(b);
 854             b.setBorder(border);
 855 
 856             Boolean value = rolloverTable.remove(b);
 857             if (value != null) {
 858                 b.setRolloverEnabled(value.booleanValue());
 859             }
 860         }
 861     }
 862 
 863     /**
 864      * Sets the floating location.
 865      *
 866      * @param x an X coordinate
 867      * @param y an Y coordinate
 868      */
 869     public void setFloatingLocation(int x, int y) {
 870         floatingX = x;
 871         floatingY = y;
 872     }
 873 
 874     /**
 875      * Returns {@code true} if the {@code JToolBar} is floating
 876      *
 877      * @return {@code true} if the {@code JToolBar} is floating
 878      */
 879     public boolean isFloating() {
 880         return floating;
 881     }
 882 
 883     /**
 884      * Sets the floating property.
 885      *
 886      * @param b {@code true} if the {@code JToolBar} is floating
 887      * @param p the position
 888      */
 889     public void setFloating(boolean b, Point p) {
 890         if (toolBar.isFloatable()) {
 891             boolean visible = false;
 892             Window ancestor = SwingUtilities.getWindowAncestor(toolBar);
 893             if (ancestor != null) {
 894                 visible = ancestor.isVisible();
 895             }
 896             if (dragWindow != null)
 897                 dragWindow.setVisible(false);
 898             this.floating = b;
 899             if (floatingToolBar == null) {
 900                 floatingToolBar = createFloatingWindow(toolBar);
 901             }
 902             if (b == true)
 903             {
 904                 if (dockingSource == null)
 905                 {
 906                     dockingSource = toolBar.getParent();
 907                     dockingSource.remove(toolBar);
 908                 }
 909                 constraintBeforeFloating = calculateConstraint();
 910                 if ( propertyListener != null )
 911                     UIManager.addPropertyChangeListener( propertyListener );
 912                 floatingToolBar.getContentPane().add(toolBar,BorderLayout.CENTER);
 913                 if (floatingToolBar instanceof Window) {
 914                     ((Window)floatingToolBar).pack();
 915                     ((Window)floatingToolBar).setLocation(floatingX, floatingY);
 916                     if (visible) {
 917                         ((Window)floatingToolBar).show();
 918                     } else {
 919                         ancestor.addWindowListener(new WindowAdapter() {
 920                             public void windowOpened(WindowEvent e) {
 921                                 ((Window)floatingToolBar).show();
 922                             }
 923                         });
 924                     }
 925                 }
 926             } else {
 927                 if (floatingToolBar == null)
 928                     floatingToolBar = createFloatingWindow(toolBar);
 929                 if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false);
 930                 floatingToolBar.getContentPane().remove(toolBar);
 931                 String constraint = getDockingConstraint(dockingSource,
 932                                                          p);
 933                 if (constraint == null) {
 934                     constraint = BorderLayout.NORTH;
 935                 }
 936                 int orientation = mapConstraintToOrientation(constraint);
 937                 setOrientation(orientation);
 938                 if (dockingSource== null)
 939                     dockingSource = toolBar.getParent();
 940                 if ( propertyListener != null )
 941                     UIManager.removePropertyChangeListener( propertyListener );
 942                 dockingSource.add(constraint, toolBar);
 943             }
 944             dockingSource.invalidate();
 945             Container dockingSourceParent = dockingSource.getParent();
 946             if (dockingSourceParent != null)
 947                 dockingSourceParent.validate();
 948             dockingSource.repaint();
 949         }
 950     }
 951 
 952     private int mapConstraintToOrientation(String constraint)
 953     {
 954         int orientation = toolBar.getOrientation();
 955 
 956         if ( constraint != null )
 957         {
 958             if ( constraint.equals(BorderLayout.EAST) || constraint.equals(BorderLayout.WEST) )
 959                 orientation = JToolBar.VERTICAL;
 960             else if ( constraint.equals(BorderLayout.NORTH) || constraint.equals(BorderLayout.SOUTH) )
 961                 orientation = JToolBar.HORIZONTAL;
 962         }
 963 
 964         return orientation;
 965     }
 966 
 967     /**
 968      * Sets the tool bar's orientation.
 969      *
 970      * @param orientation the new orientation
 971      */
 972     public void setOrientation(int orientation)
 973     {
 974         toolBar.setOrientation( orientation );
 975 
 976         if (dragWindow !=null)
 977             dragWindow.setOrientation(orientation);
 978     }
 979 
 980     /**
 981      * Gets the color displayed when over a docking area
 982      *
 983      * @return the color displayed when over a docking area
 984      */
 985     public Color getDockingColor() {
 986         return dockingColor;
 987     }
 988 
 989     /**
 990      * Sets the color displayed when over a docking area
 991      *
 992      * @param c the new color
 993      */
 994    public void setDockingColor(Color c) {
 995         this.dockingColor = c;
 996     }
 997 
 998     /**
 999      * Gets the color displayed when over a floating area
1000      *
1001      * @return the color displayed when over a floating area
1002      */
1003     public Color getFloatingColor() {
1004         return floatingColor;
1005     }
1006 
1007     /**
1008      * Sets the color displayed when over a floating area
1009      *
1010      * @param c the new color
1011      */
1012     public void setFloatingColor(Color c) {
1013         this.floatingColor = c;
1014     }
1015 
1016     private boolean isBlocked(Component comp, Object constraint) {
1017         if (comp instanceof Container) {
1018             Container cont = (Container)comp;
1019             LayoutManager lm = cont.getLayout();
1020             if (lm instanceof BorderLayout) {
1021                 BorderLayout blm = (BorderLayout)lm;
1022                 Component c = blm.getLayoutComponent(cont, constraint);
1023                 return (c != null && c != toolBar);
1024             }
1025         }
1026         return false;
1027     }
1028 
1029     /**
1030      * Returns {@code true} if the {@code JToolBar} can dock at the given position.
1031      *
1032      * @param c a component
1033      * @param p a position
1034      * @return {@code true} if the {@code JToolBar} can dock at the given position
1035      */
1036     public boolean canDock(Component c, Point p) {
1037         return (p != null && getDockingConstraint(c, p) != null);
1038     }
1039 
1040     private String calculateConstraint() {
1041         String constraint = null;
1042         LayoutManager lm = dockingSource.getLayout();
1043         if (lm instanceof BorderLayout) {
1044             constraint = (String)((BorderLayout)lm).getConstraints(toolBar);
1045         }
1046         return (constraint != null) ? constraint : constraintBeforeFloating;
1047     }
1048 
1049 
1050 
1051     private String getDockingConstraint(Component c, Point p) {
1052         if (p == null) return constraintBeforeFloating;
1053         if (c.contains(p)) {
1054             dockingSensitivity = (toolBar.getOrientation() == JToolBar.HORIZONTAL)
1055                                                 ? toolBar.getSize().height
1056                                                 : toolBar.getSize().width;
1057             // North  (Base distance on height for now!)
1058             if (p.y < dockingSensitivity && !isBlocked(c, BorderLayout.NORTH)) {
1059                 return BorderLayout.NORTH;
1060             }
1061             // East  (Base distance on height for now!)
1062             if (p.x >= c.getWidth() - dockingSensitivity && !isBlocked(c, BorderLayout.EAST)) {
1063                 return BorderLayout.EAST;
1064             }
1065             // West  (Base distance on height for now!)
1066             if (p.x < dockingSensitivity && !isBlocked(c, BorderLayout.WEST)) {
1067                 return BorderLayout.WEST;
1068             }
1069             if (p.y >= c.getHeight() - dockingSensitivity && !isBlocked(c, BorderLayout.SOUTH)) {
1070                 return BorderLayout.SOUTH;
1071             }
1072         }
1073         return null;
1074     }
1075 
1076     /**
1077      * The method is used to drag {@code DragWindow} during the {@code JToolBar}
1078      * is being dragged.
1079      *
1080      * @param position the relative to the {@code JTollBar} position
1081      * @param origin the screen position of {@code JToolBar} before dragging
1082      */
1083     protected void dragTo(Point position, Point origin)
1084     {
1085         if (toolBar.isFloatable())
1086         {
1087           try
1088           {
1089             if (dragWindow == null)
1090                 dragWindow = createDragWindow(toolBar);
1091             Point offset = dragWindow.getOffset();
1092             if (offset == null) {
1093                 Dimension size = toolBar.getPreferredSize();
1094                 offset = new Point(size.width/2, size.height/2);
1095                 dragWindow.setOffset(offset);
1096             }
1097             Point global = new Point(origin.x+ position.x,
1098                                      origin.y+position.y);
1099             Point dragPoint = new Point(global.x- offset.x,
1100                                         global.y- offset.y);
1101             if (dockingSource == null)
1102                 dockingSource = toolBar.getParent();
1103                 constraintBeforeFloating = calculateConstraint();
1104             Point dockingPosition = dockingSource.getLocationOnScreen();
1105             Point comparisonPoint = new Point(global.x-dockingPosition.x,
1106                                               global.y-dockingPosition.y);
1107             if (canDock(dockingSource, comparisonPoint)) {
1108                 dragWindow.setBackground(getDockingColor());
1109                 String constraint = getDockingConstraint(dockingSource,
1110                                                          comparisonPoint);
1111                 int orientation = mapConstraintToOrientation(constraint);
1112                 dragWindow.setOrientation(orientation);
1113                 dragWindow.setBorderColor(dockingBorderColor);
1114             } else {
1115                 dragWindow.setBackground(getFloatingColor());
1116                 dragWindow.setBorderColor(floatingBorderColor);
1117                 dragWindow.setOrientation(toolBar.getOrientation());
1118             }
1119 
1120             dragWindow.setLocation(dragPoint.x, dragPoint.y);
1121             if (dragWindow.isVisible() == false) {
1122                 Dimension size = toolBar.getPreferredSize();
1123                 dragWindow.setSize(size.width, size.height);
1124                 dragWindow.show();
1125             }
1126           }
1127           catch ( IllegalComponentStateException e )
1128           {
1129           }
1130         }
1131     }
1132 
1133     /**
1134      * The method is called at end of dragging to place the frame in either
1135      * its original place or in its floating frame.
1136      *
1137      * @param position the relative to the {@code JTollBar} position
1138      * @param origin the screen position of {@code JToolBar} before dragging
1139      */
1140     protected void floatAt(Point position, Point origin)
1141     {
1142         if(toolBar.isFloatable())
1143         {
1144           try
1145           {
1146             Point offset = dragWindow.getOffset();
1147             if (offset == null) {
1148                 offset = position;
1149                 dragWindow.setOffset(offset);
1150             }
1151             Point global = new Point(origin.x+ position.x,
1152                                      origin.y+position.y);
1153             setFloatingLocation(global.x-offset.x,
1154                                 global.y-offset.y);
1155             if (dockingSource != null) {
1156                 Point dockingPosition = dockingSource.getLocationOnScreen();
1157                 Point comparisonPoint = new Point(global.x-dockingPosition.x,
1158                                                   global.y-dockingPosition.y);
1159                 if (canDock(dockingSource, comparisonPoint)) {
1160                     setFloating(false, comparisonPoint);
1161                 } else {
1162                     setFloating(true, null);
1163                 }
1164             } else {
1165                 setFloating(true, null);
1166             }
1167             dragWindow.setOffset(null);
1168           }
1169           catch ( IllegalComponentStateException e )
1170           {
1171           }
1172         }
1173     }
1174 
1175     private Handler getHandler() {
1176         if (handler == null) {
1177             handler = new Handler();
1178         }
1179         return handler;
1180     }
1181 
1182     /**
1183      * Returns an instance of {@code ContainerListener}.
1184      *
1185      * @return an instance of {@code ContainerListener}
1186      */
1187     protected ContainerListener createToolBarContListener( )
1188     {
1189         return getHandler();
1190     }
1191 
1192     /**
1193      * Returns an instance of {@code FocusListener}.
1194      *
1195      * @return an instance of {@code FocusListener}
1196      */
1197     protected FocusListener createToolBarFocusListener( )
1198     {
1199         return getHandler();
1200     }
1201 
1202     /**
1203      * Returns an instance of {@code PropertyChangeListener}.
1204      *
1205      * @return an instance of {@code PropertyChangeListener}
1206      */
1207     protected PropertyChangeListener createPropertyListener()
1208     {
1209         return getHandler();
1210     }
1211 
1212     /**
1213      * Returns an instance of {@code MouseInputListener}.
1214      *
1215      * @return an instance of {@code MouseInputListener}
1216      */
1217     protected MouseInputListener createDockingListener( ) {
1218         getHandler().tb = toolBar;
1219         return getHandler();
1220     }
1221 
1222     /**
1223      * Constructs a new instance of {@code WindowListener}.
1224      *
1225      * @return a new instance of {@code WindowListener}
1226      */
1227     protected WindowListener createFrameListener() {
1228         return new FrameListener();
1229     }
1230 
1231     /**
1232      * Paints the contents of the window used for dragging.
1233      *
1234      * @param g Graphics to paint to.
1235      * @throws NullPointerException is <code>g</code> is null
1236      * @since 1.5
1237      */
1238     protected void paintDragWindow(Graphics g) {
1239         g.setColor(dragWindow.getBackground());
1240         int w = dragWindow.getWidth();
1241         int h = dragWindow.getHeight();
1242         g.fillRect(0, 0, w, h);
1243         g.setColor(dragWindow.getBorderColor());
1244         g.drawRect(0, 0, w - 1, h - 1);
1245     }
1246 
1247 
1248     private static class Actions extends UIAction {
1249         private static final String NAVIGATE_RIGHT = "navigateRight";
1250         private static final String NAVIGATE_LEFT = "navigateLeft";
1251         private static final String NAVIGATE_UP = "navigateUp";
1252         private static final String NAVIGATE_DOWN = "navigateDown";
1253 
1254         public Actions(String name) {
1255             super(name);
1256         }
1257 
1258         public void actionPerformed(ActionEvent evt) {
1259             String key = getName();
1260             JToolBar toolBar = (JToolBar)evt.getSource();
1261             BasicToolBarUI ui = (BasicToolBarUI)BasicLookAndFeel.getUIOfType(
1262                      toolBar.getUI(), BasicToolBarUI.class);
1263 
1264             if (NAVIGATE_RIGHT == key) {
1265                 ui.navigateFocusedComp(EAST);
1266             } else if (NAVIGATE_LEFT == key) {
1267                 ui.navigateFocusedComp(WEST);
1268             } else if (NAVIGATE_UP == key) {
1269                 ui.navigateFocusedComp(NORTH);
1270             } else if (NAVIGATE_DOWN == key) {
1271                 ui.navigateFocusedComp(SOUTH);
1272             }
1273         }
1274     }
1275 
1276 
1277     private class Handler implements ContainerListener,
1278             FocusListener, MouseInputListener, PropertyChangeListener {
1279 
1280         //
1281         // ContainerListener
1282         //
1283         public void componentAdded(ContainerEvent evt) {
1284             Component c = evt.getChild();
1285 
1286             if (toolBarFocusListener != null) {
1287                 c.addFocusListener(toolBarFocusListener);
1288             }
1289 
1290             if (isRolloverBorders()) {
1291                 setBorderToRollover(c);
1292             } else {
1293                 setBorderToNonRollover(c);
1294             }
1295         }
1296 
1297         public void componentRemoved(ContainerEvent evt) {
1298             Component c = evt.getChild();
1299 
1300             if (toolBarFocusListener != null) {
1301                 c.removeFocusListener(toolBarFocusListener);
1302             }
1303 
1304             // Revert the button border
1305             setBorderToNormal(c);
1306         }
1307 
1308 
1309         //
1310         // FocusListener
1311         //
1312         public void focusGained(FocusEvent evt) {
1313             Component c = evt.getComponent();
1314             focusedCompIndex = toolBar.getComponentIndex(c);
1315         }
1316 
1317         public void focusLost(FocusEvent evt) { }
1318 
1319 
1320         //
1321         // MouseInputListener (DockingListener)
1322         //
1323         JToolBar tb;
1324         boolean isDragging = false;
1325         Point origin = null;
1326 
1327         public void mousePressed(MouseEvent evt) {
1328             if (!tb.isEnabled()) {
1329                 return;
1330             }
1331             isDragging = false;
1332         }
1333 
1334         public void mouseReleased(MouseEvent evt) {
1335             if (!tb.isEnabled()) {
1336                 return;
1337             }
1338             if (isDragging) {
1339                 Point position = evt.getPoint();
1340                 if (origin == null)
1341                     origin = evt.getComponent().getLocationOnScreen();
1342                 floatAt(position, origin);
1343             }
1344             origin = null;
1345             isDragging = false;
1346         }
1347 
1348         public void mouseDragged(MouseEvent evt) {
1349             if (!tb.isEnabled()) {
1350                 return;
1351             }
1352             isDragging = true;
1353             Point position = evt.getPoint();
1354             if (origin == null) {
1355                 origin = evt.getComponent().getLocationOnScreen();
1356             }
1357             dragTo(position, origin);
1358         }
1359 
1360         public void mouseClicked(MouseEvent evt) {}
1361         public void mouseEntered(MouseEvent evt) {}
1362         public void mouseExited(MouseEvent evt) {}
1363         public void mouseMoved(MouseEvent evt) {}
1364 
1365 
1366         //
1367         // PropertyChangeListener
1368         //
1369         public void propertyChange(PropertyChangeEvent evt) {
1370             String propertyName = evt.getPropertyName();
1371             if (propertyName == "lookAndFeel") {
1372                 toolBar.updateUI();
1373             } else if (propertyName == "orientation") {
1374                 // Search for JSeparator components and change it's orientation
1375                 // to match the toolbar and flip it's orientation.
1376                 Component[] components = toolBar.getComponents();
1377                 int orientation = ((Integer)evt.getNewValue()).intValue();
1378                 JToolBar.Separator separator;
1379 
1380                 for (int i = 0; i < components.length; ++i) {
1381                     if (components[i] instanceof JToolBar.Separator) {
1382                         separator = (JToolBar.Separator)components[i];
1383                         if ((orientation == JToolBar.HORIZONTAL)) {
1384                             separator.setOrientation(JSeparator.VERTICAL);
1385                         } else {
1386                             separator.setOrientation(JSeparator.HORIZONTAL);
1387                         }
1388                         Dimension size = separator.getSeparatorSize();
1389                         if (size != null && size.width != size.height) {
1390                             // Flip the orientation.
1391                             Dimension newSize =
1392                                 new Dimension(size.height, size.width);
1393                             separator.setSeparatorSize(newSize);
1394                         }
1395                     }
1396                 }
1397             } else if (propertyName == IS_ROLLOVER) {
1398                 installNormalBorders(toolBar);
1399                 setRolloverBorders(((Boolean)evt.getNewValue()).booleanValue());
1400             }
1401         }
1402     }
1403 
1404     /**
1405      * The class listens for window events.
1406      */
1407     protected class FrameListener extends WindowAdapter {
1408         public void windowClosing(WindowEvent w) {
1409             if (toolBar.isFloatable()) {
1410                 if (dragWindow != null)
1411                     dragWindow.setVisible(false);
1412                 floating = false;
1413                 if (floatingToolBar == null)
1414                     floatingToolBar = createFloatingWindow(toolBar);
1415                 if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false);
1416                 floatingToolBar.getContentPane().remove(toolBar);
1417                 String constraint = constraintBeforeFloating;
1418                 if (toolBar.getOrientation() == JToolBar.HORIZONTAL) {
1419                     if (constraint == "West" || constraint == "East") {
1420                         constraint = "North";
1421                     }
1422                 } else {
1423                     if (constraint == "North" || constraint == "South") {
1424                         constraint = "West";
1425                     }
1426                 }
1427                 if (dockingSource == null)
1428                     dockingSource = toolBar.getParent();
1429                 if (propertyListener != null)
1430                     UIManager.removePropertyChangeListener(propertyListener);
1431                 dockingSource.add(toolBar, constraint);
1432                 dockingSource.invalidate();
1433                 Container dockingSourceParent = dockingSource.getParent();
1434                 if (dockingSourceParent != null)
1435                         dockingSourceParent.validate();
1436                 dockingSource.repaint();
1437             }
1438         }
1439 
1440     }
1441 
1442     /**
1443      * The class listens for component events.
1444      */
1445     protected class ToolBarContListener implements ContainerListener {
1446         // NOTE: This class exists only for backward compatibility. All
1447         // its functionality has been moved into Handler. If you need to add
1448         // new functionality add it to the Handler, but make sure this
1449         // class calls into the Handler.
1450         public void componentAdded( ContainerEvent e )  {
1451             getHandler().componentAdded(e);
1452         }
1453 
1454         public void componentRemoved( ContainerEvent e ) {
1455             getHandler().componentRemoved(e);
1456         }
1457 
1458     }
1459 
1460     /**
1461      * The class listens for focus events.
1462      */
1463     protected class ToolBarFocusListener implements FocusListener {
1464         // NOTE: This class exists only for backward compatibility. All
1465         // its functionality has been moved into Handler. If you need to add
1466         // new functionality add it to the Handler, but make sure this
1467         // class calls into the Handler.
1468         public void focusGained( FocusEvent e ) {
1469             getHandler().focusGained(e);
1470             }
1471 
1472         public void focusLost( FocusEvent e ) {
1473             getHandler().focusLost(e);
1474             }
1475     }
1476 
1477     /**
1478      * The class listens for property changed events.
1479      */
1480     protected class PropertyListener implements PropertyChangeListener {
1481         // NOTE: This class exists only for backward compatibility. All
1482         // its functionality has been moved into Handler. If you need to add
1483         // new functionality add it to the Handler, but make sure this
1484         // class calls into the Handler.
1485         public void propertyChange( PropertyChangeEvent e ) {
1486             getHandler().propertyChange(e);
1487             }
1488     }
1489 
1490     /**
1491      * This class should be treated as a &quot;protected&quot; inner class.
1492      * Instantiate it only within subclasses of BasicToolBarUI.
1493      */
1494     public class DockingListener implements MouseInputListener {
1495         // NOTE: This class exists only for backward compatibility. All
1496         // its functionality has been moved into Handler. If you need to add
1497         // new functionality add it to the Handler, but make sure this
1498         // class calls into the Handler.
1499         /**
1500          * The instance of {@code JToolBar}.
1501          */
1502         protected JToolBar toolBar;
1503         /**
1504          * {@code true} if the {@code JToolBar} is being dragged.
1505          */
1506         protected boolean isDragging = false;
1507         /**
1508          * The origin point.
1509          */
1510         protected Point origin = null;
1511 
1512         /**
1513          * Constructs a new instance of {@code DockingListener}.
1514          *
1515          * @param t an instance of {@code JToolBar}
1516          */
1517         public DockingListener(JToolBar t) {
1518             this.toolBar = t;
1519             getHandler().tb = t;
1520         }
1521 
1522         public void mouseClicked(MouseEvent e) {
1523         getHandler().mouseClicked(e);
1524     }
1525 
1526         public void mousePressed(MouseEvent e) {
1527         getHandler().tb = toolBar;
1528         getHandler().mousePressed(e);
1529         isDragging = getHandler().isDragging;
1530         }
1531 
1532         public void mouseReleased(MouseEvent e) {
1533         getHandler().tb = toolBar;
1534         getHandler().isDragging = isDragging;
1535         getHandler().origin = origin;
1536         getHandler().mouseReleased(e);
1537         isDragging = getHandler().isDragging;
1538         origin = getHandler().origin;
1539         }
1540 
1541         public void mouseEntered(MouseEvent e) {
1542         getHandler().mouseEntered(e);
1543     }
1544 
1545         public void mouseExited(MouseEvent e) {
1546         getHandler().mouseExited(e);
1547     }
1548 
1549         public void mouseDragged(MouseEvent e) {
1550         getHandler().tb = toolBar;
1551         getHandler().origin = origin;
1552         getHandler().mouseDragged(e);
1553         isDragging = getHandler().isDragging;
1554         origin = getHandler().origin;
1555         }
1556 
1557         public void mouseMoved(MouseEvent e) {
1558         getHandler().mouseMoved(e);
1559         }
1560     }
1561 
1562     /**
1563      * The window which appears during dragging the {@code JToolBar}.
1564      */
1565     @SuppressWarnings("serial") // Same-version serialization only
1566     protected class DragWindow extends Window
1567     {
1568         Color borderColor = Color.gray;
1569         int orientation = toolBar.getOrientation();
1570         Point offset; // offset of the mouse cursor inside the DragWindow
1571 
1572         DragWindow(Window w) {
1573             super(w);
1574         }
1575 
1576     /**
1577      * Returns the orientation of the toolbar window when the toolbar is
1578      * floating. The orientation is either one of <code>JToolBar.HORIZONTAL</code>
1579      * or <code>JToolBar.VERTICAL</code>.
1580      *
1581      * @return the orientation of the toolbar window
1582      * @since 1.6
1583      */
1584     public int getOrientation() {
1585         return orientation;
1586     }
1587 
1588         /**
1589          * Sets the orientation.
1590          *
1591          * @param o the new orientation
1592          */
1593         public void setOrientation(int o) {
1594             if(isShowing()) {
1595                 if (o == this.orientation)
1596                     return;
1597                 this.orientation = o;
1598                 Dimension size = getSize();
1599                 setSize(new Dimension(size.height, size.width));
1600                 if (offset!=null) {
1601                     if( BasicGraphicsUtils.isLeftToRight(toolBar) ) {
1602                         setOffset(new Point(offset.y, offset.x));
1603                     } else if( o == JToolBar.HORIZONTAL ) {
1604                         setOffset(new Point( size.height-offset.y, offset.x));
1605                     } else {
1606                         setOffset(new Point(offset.y, size.width-offset.x));
1607                     }
1608                 }
1609                 repaint();
1610             }
1611         }
1612 
1613         /**
1614          * Returns the offset.
1615          *
1616          * @return the offset
1617          */
1618         public Point getOffset() {
1619             return offset;
1620         }
1621 
1622         /**
1623          * Sets the offset.
1624          *
1625          * @param p the new offset
1626          */
1627         public void setOffset(Point p) {
1628             this.offset = p;
1629         }
1630 
1631         /**
1632          * Sets the border color.
1633          *
1634          * @param c the new border color
1635          */
1636         public void setBorderColor(Color c) {
1637             if (this.borderColor == c)
1638                 return;
1639             this.borderColor = c;
1640             repaint();
1641         }
1642 
1643         /**
1644          * Returns the border color.
1645          *
1646          * @return the border color
1647          */
1648         public Color getBorderColor() {
1649             return this.borderColor;
1650         }
1651 
1652         public void paint(Graphics g) {
1653             paintDragWindow(g);
1654             // Paint the children
1655             super.paint(g);
1656         }
1657         public Insets getInsets() {
1658             return new Insets(1,1,1,1);
1659         }
1660     }
1661 }