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