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