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     @SuppressWarnings("deprecation")
 425     protected void navigateFocusedComp(int direction)
 426     {
 427         int nComp = toolBar.getComponentCount();
 428         int j;
 429 
 430         switch ( direction )
 431         {
 432             case EAST:
 433             case SOUTH:
 434 
 435                 if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;
 436 
 437                 j = focusedCompIndex + 1;
 438 
 439                 while ( j != focusedCompIndex )
 440                 {
 441                     if ( j >= nComp ) j = 0;
 442                     Component comp = toolBar.getComponentAtIndex( j++ );
 443 
 444                     if ( comp != null && comp.isFocusTraversable() && comp.isEnabled() )
 445                     {
 446                         comp.requestFocus();
 447                         break;
 448                     }
 449                 }
 450 
 451                 break;
 452 
 453             case WEST:
 454             case NORTH:
 455 
 456                 if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;
 457 
 458                 j = focusedCompIndex - 1;
 459 
 460                 while ( j != focusedCompIndex )
 461                 {
 462                     if ( j < 0 ) j = nComp - 1;
 463                     Component comp = toolBar.getComponentAtIndex( j-- );
 464 
 465                     if ( comp != null && comp.isFocusTraversable() && comp.isEnabled() )
 466                     {
 467                         comp.requestFocus();
 468                         break;
 469                     }
 470                 }
 471 
 472                 break;
 473 
 474             default:
 475                 break;
 476         }
 477     }
 478 
 479     /**
 480      * Creates a rollover border for toolbar components. The
 481      * rollover border will be installed if rollover borders are
 482      * enabled.
 483      * <p>
 484      * Override this method to provide an alternate rollover border.
 485      *
 486      * @return a rollover border for toolbar components
 487      * @since 1.4
 488      */
 489     protected Border createRolloverBorder() {
 490         Object border = UIManager.get("ToolBar.rolloverBorder");
 491         if (border != null) {
 492             return (Border)border;
 493         }
 494         UIDefaults table = UIManager.getLookAndFeelDefaults();
 495         return new CompoundBorder(new BasicBorders.RolloverButtonBorder(
 496                                            table.getColor("controlShadow"),
 497                                            table.getColor("controlDkShadow"),
 498                                            table.getColor("controlHighlight"),
 499                                            table.getColor("controlLtHighlight")),
 500                                   new BasicBorders.RolloverMarginBorder());
 501     }
 502 
 503     /**
 504      * Creates the non rollover border for toolbar components. This
 505      * border will be installed as the border for components added
 506      * to the toolbar if rollover borders are not enabled.
 507      * <p>
 508      * Override this method to provide an alternate rollover border.
 509      *
 510      * @return the non rollover border for toolbar components
 511      * @since 1.4
 512      */
 513     protected Border createNonRolloverBorder() {
 514         Object border = UIManager.get("ToolBar.nonrolloverBorder");
 515         if (border != null) {
 516             return (Border)border;
 517         }
 518         UIDefaults table = UIManager.getLookAndFeelDefaults();
 519         return new CompoundBorder(new BasicBorders.ButtonBorder(
 520                                            table.getColor("Button.shadow"),
 521                                            table.getColor("Button.darkShadow"),
 522                                            table.getColor("Button.light"),
 523                                            table.getColor("Button.highlight")),
 524                                   new BasicBorders.RolloverMarginBorder());
 525     }
 526 
 527     /**
 528      * Creates a non rollover border for Toggle buttons in the toolbar.
 529      */
 530     private Border createNonRolloverToggleBorder() {
 531         UIDefaults table = UIManager.getLookAndFeelDefaults();
 532         return new CompoundBorder(new BasicBorders.RadioButtonBorder(
 533                                            table.getColor("ToggleButton.shadow"),
 534                                            table.getColor("ToggleButton.darkShadow"),
 535                                            table.getColor("ToggleButton.light"),
 536                                            table.getColor("ToggleButton.highlight")),
 537                                   new BasicBorders.RolloverMarginBorder());
 538     }
 539 
 540     /**
 541      * No longer used, use BasicToolBarUI.createFloatingWindow(JToolBar)
 542      *
 543      * @param toolbar an instance of {@code JToolBar}
 544      * @return an instance of {@code JFrame}
 545      * @see #createFloatingWindow
 546      */
 547     protected JFrame createFloatingFrame(JToolBar toolbar) {
 548         Window window = SwingUtilities.getWindowAncestor(toolbar);
 549         @SuppressWarnings("serial") // anonymous class
 550         JFrame frame = new JFrame(toolbar.getName(),
 551                                   (window != null) ? window.getGraphicsConfiguration() : null) {
 552             // Override createRootPane() to automatically resize
 553             // the frame when contents change
 554             protected JRootPane createRootPane() {
 555                 @SuppressWarnings("serial") // anonymous class
 556                 JRootPane rootPane = new JRootPane() {
 557                     private boolean packing = false;
 558 
 559                     public void validate() {
 560                         super.validate();
 561                         if (!packing) {
 562                             packing = true;
 563                             pack();
 564                             packing = false;
 565                         }
 566                     }
 567                 };
 568                 rootPane.setOpaque(true);
 569                 return rootPane;
 570             }
 571         };
 572         frame.getRootPane().setName("ToolBar.FloatingFrame");
 573         frame.setResizable(false);
 574         WindowListener wl = createFrameListener();
 575         frame.addWindowListener(wl);
 576         return frame;
 577     }
 578 
 579     /**
 580      * Creates a window which contains the toolbar after it has been
 581      * dragged out from its container
 582      *
 583      * @param toolbar an instance of {@code JToolBar}
 584      * @return a {@code RootPaneContainer} object, containing the toolbar
 585      * @since 1.4
 586      */
 587     protected RootPaneContainer createFloatingWindow(JToolBar toolbar) {
 588         @SuppressWarnings("serial") // Superclass is not serializable across versions
 589         class ToolBarDialog extends JDialog {
 590             public ToolBarDialog(Frame owner, String title, boolean modal) {
 591                 super(owner, title, modal);
 592             }
 593 
 594             public ToolBarDialog(Dialog owner, String title, boolean modal) {
 595                 super(owner, title, modal);
 596             }
 597 
 598             // Override createRootPane() to automatically resize
 599             // the frame when contents change
 600             protected JRootPane createRootPane() {
 601                 @SuppressWarnings("serial") // anonymous class
 602                 JRootPane rootPane = new JRootPane() {
 603                     private boolean packing = false;
 604 
 605                     public void validate() {
 606                         super.validate();
 607                         if (!packing) {
 608                             packing = true;
 609                             pack();
 610                             packing = false;
 611                         }
 612                     }
 613                 };
 614                 rootPane.setOpaque(true);
 615                 return rootPane;
 616             }
 617         }
 618 
 619         JDialog dialog;
 620         Window window = SwingUtilities.getWindowAncestor(toolbar);
 621         if (window instanceof Frame) {
 622             dialog = new ToolBarDialog((Frame)window, toolbar.getName(), false);
 623         } else if (window instanceof Dialog) {
 624             dialog = new ToolBarDialog((Dialog)window, toolbar.getName(), false);
 625         } else {
 626             dialog = new ToolBarDialog((Frame)null, toolbar.getName(), false);
 627         }
 628 
 629         dialog.getRootPane().setName("ToolBar.FloatingWindow");
 630         dialog.setTitle(toolbar.getName());
 631         dialog.setResizable(false);
 632         WindowListener wl = createFrameListener();
 633         dialog.addWindowListener(wl);
 634         return dialog;
 635     }
 636 
 637     /**
 638      * Returns an instance of {@code DragWindow}.
 639      *
 640      * @param toolbar an instance of {@code JToolBar}
 641      * @return an instance of {@code DragWindow}
 642      */
 643     protected DragWindow createDragWindow(JToolBar toolbar) {
 644         Window frame = null;
 645         if(toolBar != null) {
 646             Container p;
 647             for(p = toolBar.getParent() ; p != null && !(p instanceof Window) ;
 648                 p = p.getParent());
 649             if(p != null && p instanceof Window)
 650                 frame = (Window) p;
 651         }
 652         if(floatingToolBar == null) {
 653             floatingToolBar = createFloatingWindow(toolBar);
 654         }
 655         if (floatingToolBar instanceof Window) frame = (Window) floatingToolBar;
 656         DragWindow dragWindow = new DragWindow(frame);
 657         return dragWindow;
 658     }
 659 
 660     /**
 661      * Returns a flag to determine whether rollover button borders
 662      * are enabled.
 663      *
 664      * @return true if rollover borders are enabled; false otherwise
 665      * @see #setRolloverBorders
 666      * @since 1.4
 667      */
 668     public boolean isRolloverBorders() {
 669         return rolloverBorders;
 670     }
 671 
 672     /**
 673      * Sets the flag for enabling rollover borders on the toolbar and it will
 674      * also install the appropriate border depending on the state of the flag.
 675      *
 676      * @param rollover if true, rollover borders are installed.
 677      *        Otherwise non-rollover borders are installed
 678      * @see #isRolloverBorders
 679      * @since 1.4
 680      */
 681     public void setRolloverBorders( boolean rollover ) {
 682         rolloverBorders = rollover;
 683 
 684         if ( rolloverBorders )  {
 685             installRolloverBorders( toolBar );
 686         } else  {
 687             installNonRolloverBorders( toolBar );
 688         }
 689     }
 690 
 691     /**
 692      * Installs rollover borders on all the child components of the JComponent.
 693      * <p>
 694      * This is a convenience method to call <code>setBorderToRollover</code>
 695      * for each child component.
 696      *
 697      * @param c container which holds the child components (usually a JToolBar)
 698      * @see #setBorderToRollover
 699      * @since 1.4
 700      */
 701     protected void installRolloverBorders ( JComponent c )  {
 702         // Put rollover borders on buttons
 703         Component[] components = c.getComponents();
 704 
 705         for (Component component : components) {
 706             if (component instanceof JComponent) {
 707                 ((JComponent) component).updateUI();
 708                 setBorderToRollover(component);
 709             }
 710         }
 711     }
 712 
 713     /**
 714      * Installs non-rollover borders on all the child components of the JComponent.
 715      * A non-rollover border is the border that is installed on the child component
 716      * while it is in the toolbar.
 717      * <p>
 718      * This is a convenience method to call <code>setBorderToNonRollover</code>
 719      * for each child component.
 720      *
 721      * @param c container which holds the child components (usually a JToolBar)
 722      * @see #setBorderToNonRollover
 723      * @since 1.4
 724      */
 725     protected void installNonRolloverBorders ( JComponent c )  {
 726         // Put non-rollover borders on buttons. These borders reduce the margin.
 727         Component[] components = c.getComponents();
 728 
 729         for (Component component : components) {
 730             if (component instanceof JComponent) {
 731                 ((JComponent) component).updateUI();
 732                 setBorderToNonRollover(component);
 733             }
 734         }
 735     }
 736 
 737     /**
 738      * Installs normal borders on all the child components of the JComponent.
 739      * A normal border is the original border that was installed on the child
 740      * component before it was added to the toolbar.
 741      * <p>
 742      * This is a convenience method to call <code>setBorderNormal</code>
 743      * for each child component.
 744      *
 745      * @param c container which holds the child components (usually a JToolBar)
 746      * @see #setBorderToNonRollover
 747      * @since 1.4
 748      */
 749     protected void installNormalBorders ( JComponent c )  {
 750         // Put back the normal borders on buttons
 751         Component[] components = c.getComponents();
 752 
 753         for (Component component : components) {
 754             setBorderToNormal(component);
 755         }
 756     }
 757 
 758     /**
 759      * Sets the border of the component to have a rollover border which
 760      * was created by the {@link #createRolloverBorder} method.
 761      *
 762      * @param c component which will have a rollover border installed
 763      * @see #createRolloverBorder
 764      * @since 1.4
 765      */
 766     protected void setBorderToRollover(Component c) {
 767         if (c instanceof AbstractButton) {
 768             AbstractButton b = (AbstractButton)c;
 769 
 770             Border border = borderTable.get(b);
 771             if (border == null || border instanceof UIResource) {
 772                 borderTable.put(b, b.getBorder());
 773             }
 774 
 775             // Only set the border if its the default border
 776             if (b.getBorder() instanceof UIResource) {
 777                 b.setBorder(getRolloverBorder(b));
 778             }
 779 
 780             rolloverTable.put(b, b.isRolloverEnabled()?
 781                               Boolean.TRUE: Boolean.FALSE);
 782             b.setRolloverEnabled(true);
 783         }
 784     }
 785 
 786     /**
 787      * Returns a rollover border for the button.
 788      *
 789      * @param b the button to calculate the rollover border for
 790      * @return the rollover border
 791      * @see #setBorderToRollover
 792      * @since 1.6
 793      */
 794     protected Border getRolloverBorder(AbstractButton b) {
 795         return rolloverBorder;
 796     }
 797 
 798     /**
 799      * Sets the border of the component to have a non-rollover border which
 800      * was created by the {@link #createNonRolloverBorder} method.
 801      *
 802      * @param c component which will have a non-rollover border installed
 803      * @see #createNonRolloverBorder
 804      * @since 1.4
 805      */
 806     protected void setBorderToNonRollover(Component c) {
 807         if (c instanceof AbstractButton) {
 808             AbstractButton b = (AbstractButton)c;
 809 
 810             Border border = borderTable.get(b);
 811             if (border == null || border instanceof UIResource) {
 812                 borderTable.put(b, b.getBorder());
 813             }
 814 
 815             // Only set the border if its the default border
 816             if (b.getBorder() instanceof UIResource) {
 817                 b.setBorder(getNonRolloverBorder(b));
 818             }
 819             rolloverTable.put(b, b.isRolloverEnabled()?
 820                               Boolean.TRUE: Boolean.FALSE);
 821             b.setRolloverEnabled(false);
 822         }
 823     }
 824 
 825     /**
 826      * Returns a non-rollover border for the button.
 827      *
 828      * @param b the button to calculate the non-rollover border for
 829      * @return the non-rollover border
 830      * @see #setBorderToNonRollover
 831      * @since 1.6
 832      */
 833     protected Border getNonRolloverBorder(AbstractButton b) {
 834         if (b instanceof JToggleButton) {
 835             return nonRolloverToggleBorder;
 836         } else {
 837             return nonRolloverBorder;
 838         }
 839     }
 840 
 841     /**
 842      * Sets the border of the component to have a normal border.
 843      * A normal border is the original border that was installed on the child
 844      * component before it was added to the toolbar.
 845      *
 846      * @param c component which will have a normal border re-installed
 847      * @see #createNonRolloverBorder
 848      * @since 1.4
 849      */
 850     protected void setBorderToNormal(Component c) {
 851         if (c instanceof AbstractButton) {
 852             AbstractButton b = (AbstractButton)c;
 853 
 854             Border border = borderTable.remove(b);
 855             b.setBorder(border);
 856 
 857             Boolean value = rolloverTable.remove(b);
 858             if (value != null) {
 859                 b.setRolloverEnabled(value.booleanValue());
 860             }
 861         }
 862     }
 863 
 864     /**
 865      * Sets the floating location.
 866      *
 867      * @param x an X coordinate
 868      * @param y an Y coordinate
 869      */
 870     public void setFloatingLocation(int x, int y) {
 871         floatingX = x;
 872         floatingY = y;
 873     }
 874 
 875     /**
 876      * Returns {@code true} if the {@code JToolBar} is floating
 877      *
 878      * @return {@code true} if the {@code JToolBar} is floating
 879      */
 880     public boolean isFloating() {
 881         return floating;
 882     }
 883 
 884     /**
 885      * Sets the floating property.
 886      *
 887      * @param b {@code true} if the {@code JToolBar} is floating
 888      * @param p the position
 889      */
 890     @SuppressWarnings("deprecation")
 891     public void setFloating(boolean b, Point p) {
 892         if (toolBar.isFloatable()) {
 893             boolean visible = false;
 894             Window ancestor = SwingUtilities.getWindowAncestor(toolBar);
 895             if (ancestor != null) {
 896                 visible = ancestor.isVisible();
 897             }
 898             if (dragWindow != null)
 899                 dragWindow.setVisible(false);
 900             this.floating = b;
 901             if (floatingToolBar == null) {
 902                 floatingToolBar = createFloatingWindow(toolBar);
 903             }
 904             if (b == true)
 905             {
 906                 if (dockingSource == null)
 907                 {
 908                     dockingSource = toolBar.getParent();
 909                     dockingSource.remove(toolBar);
 910                 }
 911                 constraintBeforeFloating = calculateConstraint();
 912                 if ( propertyListener != null )
 913                     UIManager.addPropertyChangeListener( propertyListener );
 914                 floatingToolBar.getContentPane().add(toolBar,BorderLayout.CENTER);
 915                 if (floatingToolBar instanceof Window) {
 916                     ((Window)floatingToolBar).pack();
 917                     ((Window)floatingToolBar).setLocation(floatingX, floatingY);
 918                     if (visible) {
 919                         ((Window)floatingToolBar).show();
 920                     } else {
 921                         ancestor.addWindowListener(new WindowAdapter() {
 922                             public void windowOpened(WindowEvent e) {
 923                                 ((Window)floatingToolBar).show();
 924                             }
 925                         });
 926                     }
 927                 }
 928             } else {
 929                 if (floatingToolBar == null)
 930                     floatingToolBar = createFloatingWindow(toolBar);
 931                 if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false);
 932                 floatingToolBar.getContentPane().remove(toolBar);
 933                 String constraint = getDockingConstraint(dockingSource,
 934                                                          p);
 935                 if (constraint == null) {
 936                     constraint = BorderLayout.NORTH;
 937                 }
 938                 int orientation = mapConstraintToOrientation(constraint);
 939                 setOrientation(orientation);
 940                 if (dockingSource== null)
 941                     dockingSource = toolBar.getParent();
 942                 if ( propertyListener != null )
 943                     UIManager.removePropertyChangeListener( propertyListener );
 944                 dockingSource.add(constraint, toolBar);
 945             }
 946             dockingSource.invalidate();
 947             Container dockingSourceParent = dockingSource.getParent();
 948             if (dockingSourceParent != null)
 949                 dockingSourceParent.validate();
 950             dockingSource.repaint();
 951         }
 952     }
 953 
 954     private int mapConstraintToOrientation(String constraint)
 955     {
 956         int orientation = toolBar.getOrientation();
 957 
 958         if ( constraint != null )
 959         {
 960             if ( constraint.equals(BorderLayout.EAST) || constraint.equals(BorderLayout.WEST) )
 961                 orientation = JToolBar.VERTICAL;
 962             else if ( constraint.equals(BorderLayout.NORTH) || constraint.equals(BorderLayout.SOUTH) )
 963                 orientation = JToolBar.HORIZONTAL;
 964         }
 965 
 966         return orientation;
 967     }
 968 
 969     /**
 970      * Sets the tool bar's orientation.
 971      *
 972      * @param orientation the new orientation
 973      */
 974     public void setOrientation(int orientation)
 975     {
 976         toolBar.setOrientation( orientation );
 977 
 978         if (dragWindow !=null)
 979             dragWindow.setOrientation(orientation);
 980     }
 981 
 982     /**
 983      * Gets the color displayed when over a docking area
 984      *
 985      * @return the color displayed when over a docking area
 986      */
 987     public Color getDockingColor() {
 988         return dockingColor;
 989     }
 990 
 991     /**
 992      * Sets the color displayed when over a docking area
 993      *
 994      * @param c the new color
 995      */
 996    public void setDockingColor(Color c) {
 997         this.dockingColor = c;
 998     }
 999 
1000     /**
1001      * Gets the color displayed when over a floating area
1002      *
1003      * @return the color displayed when over a floating area
1004      */
1005     public Color getFloatingColor() {
1006         return floatingColor;
1007     }
1008 
1009     /**
1010      * Sets the color displayed when over a floating area
1011      *
1012      * @param c the new color
1013      */
1014     public void setFloatingColor(Color c) {
1015         this.floatingColor = c;
1016     }
1017 
1018     private boolean isBlocked(Component comp, Object constraint) {
1019         if (comp instanceof Container) {
1020             Container cont = (Container)comp;
1021             LayoutManager lm = cont.getLayout();
1022             if (lm instanceof BorderLayout) {
1023                 BorderLayout blm = (BorderLayout)lm;
1024                 Component c = blm.getLayoutComponent(cont, constraint);
1025                 return (c != null && c != toolBar);
1026             }
1027         }
1028         return false;
1029     }
1030 
1031     /**
1032      * Returns {@code true} if the {@code JToolBar} can dock at the given position.
1033      *
1034      * @param c a component
1035      * @param p a position
1036      * @return {@code true} if the {@code JToolBar} can dock at the given position
1037      */
1038     public boolean canDock(Component c, Point p) {
1039         return (p != null && getDockingConstraint(c, p) != null);
1040     }
1041 
1042     private String calculateConstraint() {
1043         String constraint = null;
1044         LayoutManager lm = dockingSource.getLayout();
1045         if (lm instanceof BorderLayout) {
1046             constraint = (String)((BorderLayout)lm).getConstraints(toolBar);
1047         }
1048         return (constraint != null) ? constraint : constraintBeforeFloating;
1049     }
1050 
1051 
1052 
1053     private String getDockingConstraint(Component c, Point p) {
1054         if (p == null) return constraintBeforeFloating;
1055         if (c.contains(p)) {
1056             dockingSensitivity = (toolBar.getOrientation() == JToolBar.HORIZONTAL)
1057                                                 ? toolBar.getSize().height
1058                                                 : toolBar.getSize().width;
1059             // North  (Base distance on height for now!)
1060             if (p.y < dockingSensitivity && !isBlocked(c, BorderLayout.NORTH)) {
1061                 return BorderLayout.NORTH;
1062             }
1063             // East  (Base distance on height for now!)
1064             if (p.x >= c.getWidth() - dockingSensitivity && !isBlocked(c, BorderLayout.EAST)) {
1065                 return BorderLayout.EAST;
1066             }
1067             // West  (Base distance on height for now!)
1068             if (p.x < dockingSensitivity && !isBlocked(c, BorderLayout.WEST)) {
1069                 return BorderLayout.WEST;
1070             }
1071             if (p.y >= c.getHeight() - dockingSensitivity && !isBlocked(c, BorderLayout.SOUTH)) {
1072                 return BorderLayout.SOUTH;
1073             }
1074         }
1075         return null;
1076     }
1077 
1078     /**
1079      * The method is used to drag {@code DragWindow} during the {@code JToolBar}
1080      * is being dragged.
1081      *
1082      * @param position the relative to the {@code JTollBar} position
1083      * @param origin the screen position of {@code JToolBar} before dragging
1084      */
1085     @SuppressWarnings("deprecation")
1086     protected void dragTo(Point position, Point origin)
1087     {
1088         if (toolBar.isFloatable())
1089         {
1090           try
1091           {
1092             if (dragWindow == null)
1093                 dragWindow = createDragWindow(toolBar);
1094             Point offset = dragWindow.getOffset();
1095             if (offset == null) {
1096                 Dimension size = toolBar.getPreferredSize();
1097                 offset = new Point(size.width/2, size.height/2);
1098                 dragWindow.setOffset(offset);
1099             }
1100             Point global = new Point(origin.x+ position.x,
1101                                      origin.y+position.y);
1102             Point dragPoint = new Point(global.x- offset.x,
1103                                         global.y- offset.y);
1104             if (dockingSource == null)
1105                 dockingSource = toolBar.getParent();
1106                 constraintBeforeFloating = calculateConstraint();
1107             Point dockingPosition = dockingSource.getLocationOnScreen();
1108             Point comparisonPoint = new Point(global.x-dockingPosition.x,
1109                                               global.y-dockingPosition.y);
1110             if (canDock(dockingSource, comparisonPoint)) {
1111                 dragWindow.setBackground(getDockingColor());
1112                 String constraint = getDockingConstraint(dockingSource,
1113                                                          comparisonPoint);
1114                 int orientation = mapConstraintToOrientation(constraint);
1115                 dragWindow.setOrientation(orientation);
1116                 dragWindow.setBorderColor(dockingBorderColor);
1117             } else {
1118                 dragWindow.setBackground(getFloatingColor());
1119                 dragWindow.setBorderColor(floatingBorderColor);
1120                 dragWindow.setOrientation(toolBar.getOrientation());
1121             }
1122 
1123             dragWindow.setLocation(dragPoint.x, dragPoint.y);
1124             if (dragWindow.isVisible() == false) {
1125                 Dimension size = toolBar.getPreferredSize();
1126                 dragWindow.setSize(size.width, size.height);
1127                 dragWindow.show();
1128             }
1129           }
1130           catch ( IllegalComponentStateException e )
1131           {
1132           }
1133         }
1134     }
1135 
1136     /**
1137      * The method is called at end of dragging to place the frame in either
1138      * its original place or in its floating frame.
1139      *
1140      * @param position the relative to the {@code JTollBar} position
1141      * @param origin the screen position of {@code JToolBar} before dragging
1142      */
1143     protected void floatAt(Point position, Point origin)
1144     {
1145         if(toolBar.isFloatable())
1146         {
1147           try
1148           {
1149             Point offset = dragWindow.getOffset();
1150             if (offset == null) {
1151                 offset = position;
1152                 dragWindow.setOffset(offset);
1153             }
1154             Point global = new Point(origin.x+ position.x,
1155                                      origin.y+position.y);
1156             setFloatingLocation(global.x-offset.x,
1157                                 global.y-offset.y);
1158             if (dockingSource != null) {
1159                 Point dockingPosition = dockingSource.getLocationOnScreen();
1160                 Point comparisonPoint = new Point(global.x-dockingPosition.x,
1161                                                   global.y-dockingPosition.y);
1162                 if (canDock(dockingSource, comparisonPoint)) {
1163                     setFloating(false, comparisonPoint);
1164                 } else {
1165                     setFloating(true, null);
1166                 }
1167             } else {
1168                 setFloating(true, null);
1169             }
1170             dragWindow.setOffset(null);
1171           }
1172           catch ( IllegalComponentStateException e )
1173           {
1174           }
1175         }
1176     }
1177 
1178     private Handler getHandler() {
1179         if (handler == null) {
1180             handler = new Handler();
1181         }
1182         return handler;
1183     }
1184 
1185     /**
1186      * Returns an instance of {@code ContainerListener}.
1187      *
1188      * @return an instance of {@code ContainerListener}
1189      */
1190     protected ContainerListener createToolBarContListener( )
1191     {
1192         return getHandler();
1193     }
1194 
1195     /**
1196      * Returns an instance of {@code FocusListener}.
1197      *
1198      * @return an instance of {@code FocusListener}
1199      */
1200     protected FocusListener createToolBarFocusListener( )
1201     {
1202         return getHandler();
1203     }
1204 
1205     /**
1206      * Returns an instance of {@code PropertyChangeListener}.
1207      *
1208      * @return an instance of {@code PropertyChangeListener}
1209      */
1210     protected PropertyChangeListener createPropertyListener()
1211     {
1212         return getHandler();
1213     }
1214 
1215     /**
1216      * Returns an instance of {@code MouseInputListener}.
1217      *
1218      * @return an instance of {@code MouseInputListener}
1219      */
1220     protected MouseInputListener createDockingListener( ) {
1221         getHandler().tb = toolBar;
1222         return getHandler();
1223     }
1224 
1225     /**
1226      * Constructs a new instance of {@code WindowListener}.
1227      *
1228      * @return a new instance of {@code WindowListener}
1229      */
1230     protected WindowListener createFrameListener() {
1231         return new FrameListener();
1232     }
1233 
1234     /**
1235      * Paints the contents of the window used for dragging.
1236      *
1237      * @param g Graphics to paint to.
1238      * @throws NullPointerException is <code>g</code> is null
1239      * @since 1.5
1240      */
1241     protected void paintDragWindow(Graphics g) {
1242         g.setColor(dragWindow.getBackground());
1243         int w = dragWindow.getWidth();
1244         int h = dragWindow.getHeight();
1245         g.fillRect(0, 0, w, h);
1246         g.setColor(dragWindow.getBorderColor());
1247         g.drawRect(0, 0, w - 1, h - 1);
1248     }
1249 
1250 
1251     private static class Actions extends UIAction {
1252         private static final String NAVIGATE_RIGHT = "navigateRight";
1253         private static final String NAVIGATE_LEFT = "navigateLeft";
1254         private static final String NAVIGATE_UP = "navigateUp";
1255         private static final String NAVIGATE_DOWN = "navigateDown";
1256 
1257         public Actions(String name) {
1258             super(name);
1259         }
1260 
1261         public void actionPerformed(ActionEvent evt) {
1262             String key = getName();
1263             JToolBar toolBar = (JToolBar)evt.getSource();
1264             BasicToolBarUI ui = (BasicToolBarUI)BasicLookAndFeel.getUIOfType(
1265                      toolBar.getUI(), BasicToolBarUI.class);
1266 
1267             if (NAVIGATE_RIGHT == key) {
1268                 ui.navigateFocusedComp(EAST);
1269             } else if (NAVIGATE_LEFT == key) {
1270                 ui.navigateFocusedComp(WEST);
1271             } else if (NAVIGATE_UP == key) {
1272                 ui.navigateFocusedComp(NORTH);
1273             } else if (NAVIGATE_DOWN == key) {
1274                 ui.navigateFocusedComp(SOUTH);
1275             }
1276         }
1277     }
1278 
1279 
1280     private class Handler implements ContainerListener,
1281             FocusListener, MouseInputListener, PropertyChangeListener {
1282 
1283         //
1284         // ContainerListener
1285         //
1286         public void componentAdded(ContainerEvent evt) {
1287             Component c = evt.getChild();
1288 
1289             if (toolBarFocusListener != null) {
1290                 c.addFocusListener(toolBarFocusListener);
1291             }
1292 
1293             if (isRolloverBorders()) {
1294                 setBorderToRollover(c);
1295             } else {
1296                 setBorderToNonRollover(c);
1297             }
1298         }
1299 
1300         public void componentRemoved(ContainerEvent evt) {
1301             Component c = evt.getChild();
1302 
1303             if (toolBarFocusListener != null) {
1304                 c.removeFocusListener(toolBarFocusListener);
1305             }
1306 
1307             // Revert the button border
1308             setBorderToNormal(c);
1309         }
1310 
1311 
1312         //
1313         // FocusListener
1314         //
1315         public void focusGained(FocusEvent evt) {
1316             Component c = evt.getComponent();
1317             focusedCompIndex = toolBar.getComponentIndex(c);
1318         }
1319 
1320         public void focusLost(FocusEvent evt) { }
1321 
1322 
1323         //
1324         // MouseInputListener (DockingListener)
1325         //
1326         JToolBar tb;
1327         boolean isDragging = false;
1328         Point origin = null;
1329 
1330         public void mousePressed(MouseEvent evt) {
1331             if (!tb.isEnabled()) {
1332                 return;
1333             }
1334             isDragging = false;
1335         }
1336 
1337         public void mouseReleased(MouseEvent evt) {
1338             if (!tb.isEnabled()) {
1339                 return;
1340             }
1341             if (isDragging) {
1342                 Point position = evt.getPoint();
1343                 if (origin == null)
1344                     origin = evt.getComponent().getLocationOnScreen();
1345                 floatAt(position, origin);
1346             }
1347             origin = null;
1348             isDragging = false;
1349         }
1350 
1351         public void mouseDragged(MouseEvent evt) {
1352             if (!tb.isEnabled()) {
1353                 return;
1354             }
1355             isDragging = true;
1356             Point position = evt.getPoint();
1357             if (origin == null) {
1358                 origin = evt.getComponent().getLocationOnScreen();
1359             }
1360             dragTo(position, origin);
1361         }
1362 
1363         public void mouseClicked(MouseEvent evt) {}
1364         public void mouseEntered(MouseEvent evt) {}
1365         public void mouseExited(MouseEvent evt) {}
1366         public void mouseMoved(MouseEvent evt) {}
1367 
1368 
1369         //
1370         // PropertyChangeListener
1371         //
1372         public void propertyChange(PropertyChangeEvent evt) {
1373             String propertyName = evt.getPropertyName();
1374             if (propertyName == "lookAndFeel") {
1375                 toolBar.updateUI();
1376             } else if (propertyName == "orientation") {
1377                 // Search for JSeparator components and change it's orientation
1378                 // to match the toolbar and flip it's orientation.
1379                 Component[] components = toolBar.getComponents();
1380                 int orientation = ((Integer)evt.getNewValue()).intValue();
1381                 JToolBar.Separator separator;
1382 
1383                 for (int i = 0; i < components.length; ++i) {
1384                     if (components[i] instanceof JToolBar.Separator) {
1385                         separator = (JToolBar.Separator)components[i];
1386                         if ((orientation == JToolBar.HORIZONTAL)) {
1387                             separator.setOrientation(JSeparator.VERTICAL);
1388                         } else {
1389                             separator.setOrientation(JSeparator.HORIZONTAL);
1390                         }
1391                         Dimension size = separator.getSeparatorSize();
1392                         if (size != null && size.width != size.height) {
1393                             // Flip the orientation.
1394                             Dimension newSize =
1395                                 new Dimension(size.height, size.width);
1396                             separator.setSeparatorSize(newSize);
1397                         }
1398                     }
1399                 }
1400             } else if (propertyName == IS_ROLLOVER) {
1401                 installNormalBorders(toolBar);
1402                 setRolloverBorders(((Boolean)evt.getNewValue()).booleanValue());
1403             }
1404         }
1405     }
1406 
1407     /**
1408      * The class listens for window events.
1409      */
1410     protected class FrameListener extends WindowAdapter {
1411         public void windowClosing(WindowEvent w) {
1412             if (toolBar.isFloatable()) {
1413                 if (dragWindow != null)
1414                     dragWindow.setVisible(false);
1415                 floating = false;
1416                 if (floatingToolBar == null)
1417                     floatingToolBar = createFloatingWindow(toolBar);
1418                 if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false);
1419                 floatingToolBar.getContentPane().remove(toolBar);
1420                 String constraint = constraintBeforeFloating;
1421                 if (toolBar.getOrientation() == JToolBar.HORIZONTAL) {
1422                     if (constraint == "West" || constraint == "East") {
1423                         constraint = "North";
1424                     }
1425                 } else {
1426                     if (constraint == "North" || constraint == "South") {
1427                         constraint = "West";
1428                     }
1429                 }
1430                 if (dockingSource == null)
1431                     dockingSource = toolBar.getParent();
1432                 if (propertyListener != null)
1433                     UIManager.removePropertyChangeListener(propertyListener);
1434                 dockingSource.add(toolBar, constraint);
1435                 dockingSource.invalidate();
1436                 Container dockingSourceParent = dockingSource.getParent();
1437                 if (dockingSourceParent != null)
1438                         dockingSourceParent.validate();
1439                 dockingSource.repaint();
1440             }
1441         }
1442 
1443     }
1444 
1445     /**
1446      * The class listens for component events.
1447      */
1448     protected class ToolBarContListener implements ContainerListener {
1449         // NOTE: This class exists only for backward compatibility. All
1450         // its functionality has been moved into Handler. If you need to add
1451         // new functionality add it to the Handler, but make sure this
1452         // class calls into the Handler.
1453         public void componentAdded( ContainerEvent e )  {
1454             getHandler().componentAdded(e);
1455         }
1456 
1457         public void componentRemoved( ContainerEvent e ) {
1458             getHandler().componentRemoved(e);
1459         }
1460 
1461     }
1462 
1463     /**
1464      * The class listens for focus events.
1465      */
1466     protected class ToolBarFocusListener implements FocusListener {
1467         // NOTE: This class exists only for backward compatibility. All
1468         // its functionality has been moved into Handler. If you need to add
1469         // new functionality add it to the Handler, but make sure this
1470         // class calls into the Handler.
1471         public void focusGained( FocusEvent e ) {
1472             getHandler().focusGained(e);
1473             }
1474 
1475         public void focusLost( FocusEvent e ) {
1476             getHandler().focusLost(e);
1477             }
1478     }
1479 
1480     /**
1481      * The class listens for property changed events.
1482      */
1483     protected class PropertyListener implements PropertyChangeListener {
1484         // NOTE: This class exists only for backward compatibility. All
1485         // its functionality has been moved into Handler. If you need to add
1486         // new functionality add it to the Handler, but make sure this
1487         // class calls into the Handler.
1488         public void propertyChange( PropertyChangeEvent e ) {
1489             getHandler().propertyChange(e);
1490             }
1491     }
1492 
1493     /**
1494      * This class should be treated as a &quot;protected&quot; inner class.
1495      * Instantiate it only within subclasses of BasicToolBarUI.
1496      */
1497     public class DockingListener implements MouseInputListener {
1498         // NOTE: This class exists only for backward compatibility. All
1499         // its functionality has been moved into Handler. If you need to add
1500         // new functionality add it to the Handler, but make sure this
1501         // class calls into the Handler.
1502         /**
1503          * The instance of {@code JToolBar}.
1504          */
1505         protected JToolBar toolBar;
1506         /**
1507          * {@code true} if the {@code JToolBar} is being dragged.
1508          */
1509         protected boolean isDragging = false;
1510         /**
1511          * The origin point.
1512          */
1513         protected Point origin = null;
1514 
1515         /**
1516          * Constructs a new instance of {@code DockingListener}.
1517          *
1518          * @param t an instance of {@code JToolBar}
1519          */
1520         public DockingListener(JToolBar t) {
1521             this.toolBar = t;
1522             getHandler().tb = t;
1523         }
1524 
1525         public void mouseClicked(MouseEvent e) {
1526         getHandler().mouseClicked(e);
1527     }
1528 
1529         public void mousePressed(MouseEvent e) {
1530         getHandler().tb = toolBar;
1531         getHandler().mousePressed(e);
1532         isDragging = getHandler().isDragging;
1533         }
1534 
1535         public void mouseReleased(MouseEvent e) {
1536         getHandler().tb = toolBar;
1537         getHandler().isDragging = isDragging;
1538         getHandler().origin = origin;
1539         getHandler().mouseReleased(e);
1540         isDragging = getHandler().isDragging;
1541         origin = getHandler().origin;
1542         }
1543 
1544         public void mouseEntered(MouseEvent e) {
1545         getHandler().mouseEntered(e);
1546     }
1547 
1548         public void mouseExited(MouseEvent e) {
1549         getHandler().mouseExited(e);
1550     }
1551 
1552         public void mouseDragged(MouseEvent e) {
1553         getHandler().tb = toolBar;
1554         getHandler().origin = origin;
1555         getHandler().mouseDragged(e);
1556         isDragging = getHandler().isDragging;
1557         origin = getHandler().origin;
1558         }
1559 
1560         public void mouseMoved(MouseEvent e) {
1561         getHandler().mouseMoved(e);
1562         }
1563     }
1564 
1565     /**
1566      * The window which appears during dragging the {@code JToolBar}.
1567      */
1568     @SuppressWarnings("serial") // Same-version serialization only
1569     protected class DragWindow extends Window
1570     {
1571         Color borderColor = Color.gray;
1572         int orientation = toolBar.getOrientation();
1573         Point offset; // offset of the mouse cursor inside the DragWindow
1574 
1575         DragWindow(Window w) {
1576             super(w);
1577         }
1578 
1579     /**
1580      * Returns the orientation of the toolbar window when the toolbar is
1581      * floating. The orientation is either one of <code>JToolBar.HORIZONTAL</code>
1582      * or <code>JToolBar.VERTICAL</code>.
1583      *
1584      * @return the orientation of the toolbar window
1585      * @since 1.6
1586      */
1587     public int getOrientation() {
1588         return orientation;
1589     }
1590 
1591         /**
1592          * Sets the orientation.
1593          *
1594          * @param o the new orientation
1595          */
1596         public void setOrientation(int o) {
1597             if(isShowing()) {
1598                 if (o == this.orientation)
1599                     return;
1600                 this.orientation = o;
1601                 Dimension size = getSize();
1602                 setSize(new Dimension(size.height, size.width));
1603                 if (offset!=null) {
1604                     if( BasicGraphicsUtils.isLeftToRight(toolBar) ) {
1605                         setOffset(new Point(offset.y, offset.x));
1606                     } else if( o == JToolBar.HORIZONTAL ) {
1607                         setOffset(new Point( size.height-offset.y, offset.x));
1608                     } else {
1609                         setOffset(new Point(offset.y, size.width-offset.x));
1610                     }
1611                 }
1612                 repaint();
1613             }
1614         }
1615 
1616         /**
1617          * Returns the offset.
1618          *
1619          * @return the offset
1620          */
1621         public Point getOffset() {
1622             return offset;
1623         }
1624 
1625         /**
1626          * Sets the offset.
1627          *
1628          * @param p the new offset
1629          */
1630         public void setOffset(Point p) {
1631             this.offset = p;
1632         }
1633 
1634         /**
1635          * Sets the border color.
1636          *
1637          * @param c the new border color
1638          */
1639         public void setBorderColor(Color c) {
1640             if (this.borderColor == c)
1641                 return;
1642             this.borderColor = c;
1643             repaint();
1644         }
1645 
1646         /**
1647          * Returns the border color.
1648          *
1649          * @return the border color
1650          */
1651         public Color getBorderColor() {
1652             return this.borderColor;
1653         }
1654 
1655         public void paint(Graphics g) {
1656             paintDragWindow(g);
1657             // Paint the children
1658             super.paint(g);
1659         }
1660         public Insets getInsets() {
1661             return new Insets(1,1,1,1);
1662         }
1663     }
1664 }