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