1. /*
  2. * @(#)BasicToolBarUI.java 1.87 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.plaf.basic;
  8. import javax.swing.*;
  9. import javax.swing.event.*;
  10. import java.awt.BorderLayout;
  11. import java.awt.Color;
  12. import java.awt.Component;
  13. import java.awt.Container;
  14. import java.awt.Dialog;
  15. import java.awt.Dimension;
  16. import java.awt.Frame;
  17. import java.awt.Graphics;
  18. import java.awt.HeadlessException;
  19. import java.awt.Insets;
  20. import java.awt.Point;
  21. import java.awt.Rectangle;
  22. import java.awt.Window;
  23. import java.awt.event.*;
  24. import java.awt.IllegalComponentStateException;
  25. import java.beans.*;
  26. import java.util.Hashtable;
  27. import java.util.HashMap;
  28. import javax.swing.border.*;
  29. import javax.swing.plaf.*;
  30. /**
  31. * A Basic L&F implementation of ToolBarUI. This implementation
  32. * is a "combined" view/controller.
  33. * <p>
  34. *
  35. * @version 1.87 01/23/03
  36. * @author Georges Saab
  37. * @author Jeff Shapiro
  38. */
  39. public class BasicToolBarUI extends ToolBarUI implements SwingConstants
  40. {
  41. protected JToolBar toolBar;
  42. private boolean floating;
  43. private int floatingX;
  44. private int floatingY;
  45. private JFrame floatingFrame;
  46. private RootPaneContainer floatingToolBar;
  47. protected DragWindow dragWindow;
  48. private Container dockingSource;
  49. private int dockingSensitivity = 0;
  50. protected int focusedCompIndex = -1;
  51. protected Color dockingColor = null;
  52. protected Color floatingColor = null;
  53. protected Color dockingBorderColor = null;
  54. protected Color floatingBorderColor = null;
  55. protected MouseInputListener dockingListener;
  56. protected PropertyChangeListener propertyListener;
  57. protected ContainerListener toolBarContListener;
  58. protected FocusListener toolBarFocusListener;
  59. protected String constraintBeforeFloating = BorderLayout.NORTH;
  60. // Rollover button implementation.
  61. private static String IS_ROLLOVER = "JToolBar.isRollover";
  62. private static Border rolloverBorder;
  63. private static Border nonRolloverBorder;
  64. private static Border nonRolloverToggleBorder;
  65. private boolean rolloverBorders = false;
  66. private HashMap borderTable = new HashMap();
  67. private Hashtable rolloverTable = new Hashtable();
  68. /**
  69. * As of Java 2 platform v1.3 this previously undocumented field is no
  70. * longer used.
  71. * Key bindings are now defined by the LookAndFeel, please refer to
  72. * the key bindings specification for further details.
  73. *
  74. * @deprecated As of Java 2 platform v1.3.
  75. */
  76. protected KeyStroke upKey;
  77. /**
  78. * As of Java 2 platform v1.3 this previously undocumented field is no
  79. * longer used.
  80. * Key bindings are now defined by the LookAndFeel, please refer to
  81. * the key bindings specification for further details.
  82. *
  83. * @deprecated As of Java 2 platform v1.3.
  84. */
  85. protected KeyStroke downKey;
  86. /**
  87. * As of Java 2 platform v1.3 this previously undocumented field is no
  88. * longer used.
  89. * Key bindings are now defined by the LookAndFeel, please refer to
  90. * the key bindings specification for further details.
  91. *
  92. * @deprecated As of Java 2 platform v1.3.
  93. */
  94. protected KeyStroke leftKey;
  95. /**
  96. * As of Java 2 platform v1.3 this previously undocumented field is no
  97. * longer used.
  98. * Key bindings are now defined by the LookAndFeel, please refer to
  99. * the key bindings specification for further details.
  100. *
  101. * @deprecated As of Java 2 platform v1.3.
  102. */
  103. protected KeyStroke rightKey;
  104. private static String FOCUSED_COMP_INDEX = "JToolBar.focusedCompIndex";
  105. public static ComponentUI createUI( JComponent c )
  106. {
  107. return new BasicToolBarUI();
  108. }
  109. public void installUI( JComponent c )
  110. {
  111. toolBar = (JToolBar) c;
  112. // Set defaults
  113. installDefaults();
  114. installComponents();
  115. installListeners();
  116. installKeyboardActions();
  117. // Initialize instance vars
  118. dockingSensitivity = 0;
  119. floating = false;
  120. floatingX = floatingY = 0;
  121. floatingToolBar = null;
  122. setOrientation( toolBar.getOrientation() );
  123. c.setOpaque(true);
  124. if ( c.getClientProperty( FOCUSED_COMP_INDEX ) != null )
  125. {
  126. focusedCompIndex = ( (Integer) ( c.getClientProperty( FOCUSED_COMP_INDEX ) ) ).intValue();
  127. }
  128. }
  129. public void uninstallUI( JComponent c )
  130. {
  131. // Clear defaults
  132. uninstallDefaults();
  133. uninstallComponents();
  134. uninstallListeners();
  135. uninstallKeyboardActions();
  136. // Clear instance vars
  137. if (isFloating() == true)
  138. setFloating(false, null);
  139. floatingToolBar = null;
  140. dragWindow = null;
  141. dockingSource = null;
  142. c.putClientProperty( FOCUSED_COMP_INDEX, new Integer( focusedCompIndex ) );
  143. }
  144. protected void installDefaults( )
  145. {
  146. LookAndFeel.installBorder(toolBar,"ToolBar.border");
  147. LookAndFeel.installColorsAndFont(toolBar,
  148. "ToolBar.background",
  149. "ToolBar.foreground",
  150. "ToolBar.font");
  151. // Toolbar specific defaults
  152. if ( dockingColor == null || dockingColor instanceof UIResource )
  153. dockingColor = UIManager.getColor("ToolBar.dockingBackground");
  154. if ( floatingColor == null || floatingColor instanceof UIResource )
  155. floatingColor = UIManager.getColor("ToolBar.floatingBackground");
  156. if ( dockingBorderColor == null ||
  157. dockingBorderColor instanceof UIResource )
  158. dockingBorderColor = UIManager.getColor("ToolBar.dockingForeground");
  159. if ( floatingBorderColor == null ||
  160. floatingBorderColor instanceof UIResource )
  161. floatingBorderColor = UIManager.getColor("ToolBar.floatingForeground");
  162. // ToolBar rollover button borders
  163. Object rolloverProp = toolBar.getClientProperty( IS_ROLLOVER );
  164. if ( rolloverProp != null ) {
  165. rolloverBorders = ((Boolean)rolloverProp).booleanValue();
  166. }
  167. if (rolloverBorder == null) {
  168. rolloverBorder = createRolloverBorder();
  169. }
  170. if (nonRolloverBorder == null) {
  171. nonRolloverBorder = createNonRolloverBorder();
  172. }
  173. if (nonRolloverToggleBorder == null) {
  174. nonRolloverToggleBorder = createNonRolloverToggleBorder();
  175. }
  176. setRolloverBorders( isRolloverBorders() );
  177. }
  178. protected void uninstallDefaults( )
  179. {
  180. LookAndFeel.uninstallBorder(toolBar);
  181. dockingColor = null;
  182. floatingColor = null;
  183. dockingBorderColor = null;
  184. floatingBorderColor = null;
  185. installNormalBorders(toolBar);
  186. rolloverBorder = null;
  187. nonRolloverBorder = null;
  188. nonRolloverToggleBorder = null;
  189. }
  190. protected void installComponents( )
  191. {
  192. }
  193. protected void uninstallComponents( )
  194. {
  195. }
  196. protected void installListeners( )
  197. {
  198. dockingListener = createDockingListener( );
  199. if ( dockingListener != null )
  200. {
  201. toolBar.addMouseMotionListener( dockingListener );
  202. toolBar.addMouseListener( dockingListener );
  203. }
  204. propertyListener = createPropertyListener(); // added in setFloating
  205. if (propertyListener != null) {
  206. toolBar.addPropertyChangeListener(propertyListener);
  207. }
  208. toolBarContListener = createToolBarContListener();
  209. if ( toolBarContListener != null ) {
  210. toolBar.addContainerListener( toolBarContListener );
  211. }
  212. toolBarFocusListener = createToolBarFocusListener();
  213. if ( toolBarFocusListener != null )
  214. {
  215. // Put focus listener on all components in toolbar
  216. Component[] components = toolBar.getComponents();
  217. for ( int i = 0; i < components.length; ++i )
  218. {
  219. components[ i ].addFocusListener( toolBarFocusListener );
  220. }
  221. }
  222. }
  223. protected void uninstallListeners( )
  224. {
  225. if ( dockingListener != null )
  226. {
  227. toolBar.removeMouseMotionListener(dockingListener);
  228. toolBar.removeMouseListener(dockingListener);
  229. dockingListener = null;
  230. }
  231. if ( propertyListener != null )
  232. {
  233. toolBar.removePropertyChangeListener(propertyListener);
  234. propertyListener = null; // removed in setFloating
  235. }
  236. if ( toolBarContListener != null )
  237. {
  238. toolBar.removeContainerListener( toolBarContListener );
  239. toolBarContListener = null;
  240. }
  241. if ( toolBarFocusListener != null )
  242. {
  243. // Remove focus listener from all components in toolbar
  244. Component[] components = toolBar.getComponents();
  245. for ( int i = 0; i < components.length; ++i )
  246. {
  247. components[ i ].removeFocusListener( toolBarFocusListener );
  248. }
  249. toolBarFocusListener = null;
  250. }
  251. }
  252. protected void installKeyboardActions( )
  253. {
  254. InputMap km = getInputMap(JComponent.
  255. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  256. SwingUtilities.replaceUIInputMap(toolBar, JComponent.
  257. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
  258. km);
  259. ActionMap am = getActionMap();
  260. if (am != null) {
  261. SwingUtilities.replaceUIActionMap(toolBar, am);
  262. }
  263. }
  264. InputMap getInputMap(int condition) {
  265. if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
  266. return (InputMap)UIManager.get("ToolBar.ancestorInputMap");
  267. }
  268. return null;
  269. }
  270. ActionMap getActionMap() {
  271. ActionMap map = (ActionMap)UIManager.get("ToolBar.actionMap");
  272. if (map == null) {
  273. map = createActionMap();
  274. if (map != null) {
  275. UIManager.getLookAndFeelDefaults().put("ToolBar.actionMap",
  276. map);
  277. }
  278. }
  279. return map;
  280. }
  281. ActionMap createActionMap() {
  282. ActionMap map = new ActionMapUIResource();
  283. map.put("navigateRight", new RightAction());
  284. map.put("navigateLeft", new LeftAction());
  285. map.put("navigateUp", new UpAction());
  286. map.put("navigateDown", new DownAction());
  287. return map;
  288. }
  289. protected void uninstallKeyboardActions( )
  290. {
  291. SwingUtilities.replaceUIActionMap(toolBar, null);
  292. SwingUtilities.replaceUIInputMap(toolBar, JComponent.
  293. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
  294. null);
  295. }
  296. protected void navigateFocusedComp( int direction )
  297. {
  298. int nComp = toolBar.getComponentCount();
  299. int j;
  300. switch ( direction )
  301. {
  302. case EAST:
  303. case SOUTH:
  304. if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;
  305. j = focusedCompIndex + 1;
  306. while ( j != focusedCompIndex )
  307. {
  308. if ( j >= nComp ) j = 0;
  309. Component comp = toolBar.getComponentAtIndex( j++ );
  310. if ( comp != null && comp.isFocusTraversable() )
  311. {
  312. comp.requestFocus();
  313. break;
  314. }
  315. }
  316. break;
  317. case WEST:
  318. case NORTH:
  319. if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;
  320. j = focusedCompIndex - 1;
  321. while ( j != focusedCompIndex )
  322. {
  323. if ( j < 0 ) j = nComp - 1;
  324. Component comp = toolBar.getComponentAtIndex( j-- );
  325. if ( comp != null && comp.isFocusTraversable() )
  326. {
  327. comp.requestFocus();
  328. break;
  329. }
  330. }
  331. break;
  332. default:
  333. break;
  334. }
  335. }
  336. /**
  337. * Creates a rollover border for toolbar components. The
  338. * rollover border will be installed if rollover borders are
  339. * enabled.
  340. * <p>
  341. * Override this method to provide an alternate rollover border.
  342. *
  343. * @since 1.4
  344. */
  345. protected Border createRolloverBorder() {
  346. UIDefaults table = UIManager.getLookAndFeelDefaults();
  347. return new BorderUIResource.CompoundBorderUIResource(new BasicBorders.RolloverButtonBorder(
  348. table.getColor("controlShadow"),
  349. table.getColor("controlDkShadow"),
  350. table.getColor("controlHighlight"),
  351. table.getColor("controlLtHighlight")),
  352. new BasicBorders.RolloverMarginBorder());
  353. }
  354. /**
  355. * Creates the non rollover border for toolbar components. This
  356. * border will be installed as the border for components added
  357. * to the toolbar if rollover borders are not enabled.
  358. * <p>
  359. * Override this method to provide an alternate rollover border.
  360. *
  361. * @since 1.4
  362. */
  363. protected Border createNonRolloverBorder() {
  364. UIDefaults table = UIManager.getLookAndFeelDefaults();
  365. return new BorderUIResource.CompoundBorderUIResource(new BasicBorders.ButtonBorder(
  366. table.getColor("Button.shadow"),
  367. table.getColor("Button.darkShadow"),
  368. table.getColor("Button.light"),
  369. table.getColor("Button.highlight")),
  370. new BasicBorders.RolloverMarginBorder());
  371. }
  372. /**
  373. * Creates a non rollover border for Toggle buttons in the toolbar.
  374. */
  375. private Border createNonRolloverToggleBorder() {
  376. UIDefaults table = UIManager.getLookAndFeelDefaults();
  377. return new BorderUIResource.CompoundBorderUIResource(new BasicBorders.RadioButtonBorder(
  378. table.getColor("ToggleButton.shadow"),
  379. table.getColor("ToggleButton.darkShadow"),
  380. table.getColor("ToggleButton.light"),
  381. table.getColor("ToggleButton.highlight")),
  382. new BasicBorders.RolloverMarginBorder());
  383. }
  384. /**
  385. * No longer used, use BasicToolBarUI.createFloatingWindow(JToolBar)
  386. * @see #createFloatingWindow
  387. */
  388. protected JFrame createFloatingFrame(JToolBar toolbar) {
  389. Window window = SwingUtilities.getWindowAncestor(toolbar);
  390. JFrame frame = new JFrame(toolbar.getName(),
  391. (window != null) ? window.getGraphicsConfiguration() : null) {
  392. // Override createRootPane() to automatically resize
  393. // the frame when contents change
  394. protected JRootPane createRootPane() {
  395. JRootPane rootPane = new JRootPane() {
  396. private boolean packing = false;
  397. public void validate() {
  398. super.validate();
  399. if (!packing) {
  400. packing = true;
  401. pack();
  402. packing = false;
  403. }
  404. }
  405. };
  406. rootPane.setOpaque(true);
  407. return rootPane;
  408. }
  409. };
  410. frame.setResizable(false);
  411. WindowListener wl = createFrameListener();
  412. frame.addWindowListener(wl);
  413. return frame;
  414. }
  415. /**
  416. * Creates a window which contains the toolbar after it has been
  417. * dragged out from its container
  418. * @return a <code>RootPaneContainer</code> object, containing the toolbar.
  419. */
  420. protected RootPaneContainer createFloatingWindow(JToolBar toolbar) {
  421. class ToolBarDialog extends JDialog {
  422. public ToolBarDialog(Frame owner, String title, boolean modal) {
  423. super(owner, title, modal);
  424. }
  425. public ToolBarDialog(Dialog owner, String title, boolean modal) {
  426. super(owner, title, modal);
  427. }
  428. // Override createRootPane() to automatically resize
  429. // the frame when contents change
  430. protected JRootPane createRootPane() {
  431. JRootPane rootPane = new JRootPane() {
  432. private boolean packing = false;
  433. public void validate() {
  434. super.validate();
  435. if (!packing) {
  436. packing = true;
  437. pack();
  438. packing = false;
  439. }
  440. }
  441. };
  442. rootPane.setOpaque(true);
  443. return rootPane;
  444. }
  445. }
  446. JDialog dialog;
  447. Window window = SwingUtilities.getWindowAncestor(toolbar);
  448. if (window instanceof Frame) {
  449. dialog = new ToolBarDialog((Frame)window, toolbar.getName(), false);
  450. } else if (window instanceof Dialog) {
  451. dialog = new ToolBarDialog((Dialog)window, toolbar.getName(), false);
  452. } else {
  453. dialog = new ToolBarDialog((Frame)null, toolbar.getName(), false);
  454. }
  455. dialog.setTitle(toolbar.getName());
  456. dialog.setResizable(false);
  457. WindowListener wl = createFrameListener();
  458. dialog.addWindowListener(wl);
  459. return dialog;
  460. }
  461. protected DragWindow createDragWindow(JToolBar toolbar) {
  462. Window frame = null;
  463. if(toolBar != null) {
  464. Container p;
  465. for(p = toolBar.getParent() ; p != null && !(p instanceof Window) ;
  466. p = p.getParent());
  467. if(p != null && p instanceof Window)
  468. frame = (Window) p;
  469. }
  470. if(floatingToolBar == null) {
  471. floatingToolBar = createFloatingWindow(toolBar);
  472. }
  473. if (floatingToolBar instanceof Window) frame = (Window) floatingToolBar;
  474. DragWindow dragWindow = new DragWindow(frame);
  475. return dragWindow;
  476. }
  477. /**
  478. * Returns a flag to determine whether rollover button borders
  479. * are enabled.
  480. *
  481. * @return true if rollover borders are enabled; false otherwise
  482. * @see #setRolloverBorders
  483. * @since 1.4
  484. */
  485. public boolean isRolloverBorders() {
  486. return rolloverBorders;
  487. }
  488. /**
  489. * Sets the flag for enabling rollover borders on the toolbar and it will
  490. * also install the apropriate border depending on the state of the flag.
  491. *
  492. * @param rollover if true, rollover borders are installed.
  493. * Otherwise non-rollover borders are installed
  494. * @see #isRolloverBorders
  495. * @since 1.4
  496. */
  497. public void setRolloverBorders( boolean rollover ) {
  498. rolloverBorders = rollover;
  499. if ( rolloverBorders ) {
  500. installRolloverBorders( toolBar );
  501. } else {
  502. installNonRolloverBorders( toolBar );
  503. }
  504. }
  505. /**
  506. * Installs rollover borders on all the child components of the JComponent.
  507. * <p>
  508. * This is a convenience method to call <code>setBorderToRollover</code>
  509. * for each child component.
  510. *
  511. * @param c container which holds the child components (usally a JToolBar)
  512. * @see #setBorderToRollover
  513. * @since 1.4
  514. */
  515. protected void installRolloverBorders ( JComponent c ) {
  516. // Put rollover borders on buttons
  517. Component[] components = c.getComponents();
  518. for ( int i = 0; i < components.length; ++i ) {
  519. if ( components[ i ] instanceof JComponent ) {
  520. ( (JComponent)components[ i ] ).updateUI();
  521. setBorderToRollover( components[ i ] );
  522. }
  523. }
  524. }
  525. /**
  526. * Installs non-rollover borders on all the child components of the JComponent.
  527. * A non-rollover border is the border that is installed on the child component
  528. * while it is in the toolbar.
  529. * <p>
  530. * This is a convenience method to call <code>setBorderToNonRollover</code>
  531. * for each child component.
  532. *
  533. * @param c container which holds the child components (usally a JToolBar)
  534. * @see #setBorderToNonRollover
  535. * @since 1.4
  536. */
  537. protected void installNonRolloverBorders ( JComponent c ) {
  538. // Put non-rollover borders on buttons. These borders reduce the margin.
  539. Component[] components = c.getComponents();
  540. for ( int i = 0; i < components.length; ++i ) {
  541. if ( components[ i ] instanceof JComponent ) {
  542. ( (JComponent)components[ i ] ).updateUI();
  543. setBorderToNonRollover( components[ i ] );
  544. }
  545. }
  546. }
  547. /**
  548. * Installs normal borders on all the child components of the JComponent.
  549. * A normal border is the original border that was installed on the child
  550. * component before it was added to the toolbar.
  551. * <p>
  552. * This is a convenience method to call <code>setBorderNormal</code>
  553. * for each child component.
  554. *
  555. * @param c container which holds the child components (usally a JToolBar)
  556. * @see #setBorderToNonRollover
  557. * @since 1.4
  558. */
  559. protected void installNormalBorders ( JComponent c ) {
  560. // Put back the normal borders on buttons
  561. Component[] components = c.getComponents();
  562. for ( int i = 0; i < components.length; ++i ) {
  563. setBorderToNormal( components[ i ] );
  564. }
  565. }
  566. /**
  567. * Sets the border of the component to have a rollover border which
  568. * was created by <code>createRolloverBorder</code>.
  569. *
  570. * @param c component which will have a rollover border installed
  571. * @see #createRolloverBorder
  572. * @since 1.4
  573. */
  574. protected void setBorderToRollover(Component c) {
  575. if (c instanceof AbstractButton) {
  576. AbstractButton b = (AbstractButton)c;
  577. Border border = (Border)borderTable.get(b);
  578. if (border == null || border instanceof UIResource) {
  579. borderTable.put(b, b.getBorder());
  580. }
  581. // Only set the border if its the default border
  582. if (b.getBorder() instanceof UIResource) {
  583. b.setBorder(rolloverBorder);
  584. }
  585. rolloverTable.put(b, b.isRolloverEnabled()?
  586. Boolean.TRUE: Boolean.FALSE);
  587. b.setRolloverEnabled(true);
  588. }
  589. }
  590. /**
  591. * Sets the border of the component to have a non-rollover border which
  592. * was created by <code>createNonRolloverBorder</code>.
  593. *
  594. * @param c component which will have a non-rollover border installed
  595. * @see #createNonRolloverBorder
  596. * @since 1.4
  597. */
  598. protected void setBorderToNonRollover(Component c) {
  599. if (c instanceof AbstractButton) {
  600. AbstractButton b = (AbstractButton)c;
  601. Border border = (Border)borderTable.get(b);
  602. if (border == null || border instanceof UIResource) {
  603. borderTable.put(b, b.getBorder());
  604. }
  605. // Only set the border if its the default border
  606. if (b.getBorder() instanceof UIResource) {
  607. if (b instanceof JToggleButton) {
  608. ((JToggleButton)b).setBorder(nonRolloverToggleBorder);
  609. } else {
  610. b.setBorder(nonRolloverBorder);
  611. }
  612. }
  613. rolloverTable.put(b, b.isRolloverEnabled()?
  614. Boolean.TRUE: Boolean.FALSE);
  615. b.setRolloverEnabled(false);
  616. }
  617. }
  618. /**
  619. * Sets the border of the component to have a normal border.
  620. * A normal border is the original border that was installed on the child
  621. * component before it was added to the toolbar.
  622. *
  623. * @param c component which will have a normal border re-installed
  624. * @see #createNonRolloverBorder
  625. * @since 1.4
  626. */
  627. protected void setBorderToNormal(Component c) {
  628. if (c instanceof AbstractButton) {
  629. AbstractButton b = (AbstractButton)c;
  630. Border border = (Border)borderTable.remove(b);
  631. b.setBorder(border);
  632. Boolean value = (Boolean)rolloverTable.remove(b);
  633. if (value != null) {
  634. b.setRolloverEnabled(value.booleanValue());
  635. }
  636. }
  637. }
  638. public Dimension getMinimumSize(JComponent c) {
  639. return getPreferredSize(c);
  640. }
  641. public Dimension getPreferredSize(JComponent c) {
  642. return null;
  643. }
  644. public Dimension getMaximumSize(JComponent c) {
  645. return getPreferredSize(c);
  646. }
  647. public void setFloatingLocation(int x, int y) {
  648. floatingX = x;
  649. floatingY = y;
  650. }
  651. public boolean isFloating() {
  652. return floating;
  653. }
  654. public void setFloating(boolean b, Point p) {
  655. if (toolBar.isFloatable() == true) {
  656. if (dragWindow != null)
  657. dragWindow.setVisible(false);
  658. this.floating = b;
  659. if (b == true)
  660. {
  661. if (dockingSource == null)
  662. {
  663. dockingSource = toolBar.getParent();
  664. dockingSource.remove(toolBar);
  665. }
  666. Point l = new Point();
  667. toolBar.getLocation(l);
  668. constraintBeforeFloating = calculateConstraint(dockingSource, l);
  669. if ( propertyListener != null )
  670. UIManager.addPropertyChangeListener( propertyListener );
  671. if (floatingToolBar == null)
  672. floatingToolBar = createFloatingWindow(toolBar);
  673. floatingToolBar.getContentPane().add(toolBar,BorderLayout.CENTER);
  674. setOrientation( JToolBar.HORIZONTAL );
  675. if (floatingToolBar instanceof Window) ((Window)floatingToolBar).pack();
  676. if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setLocation(floatingX, floatingY);
  677. if (floatingToolBar instanceof Window) ((Window)floatingToolBar).show();
  678. } else {
  679. if (floatingToolBar == null)
  680. floatingToolBar = createFloatingWindow(toolBar);
  681. if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false);
  682. floatingToolBar.getContentPane().remove(toolBar);
  683. String constraint = getDockingConstraint(dockingSource,
  684. p);
  685. int orientation = mapConstraintToOrientation(constraint);
  686. setOrientation(orientation);
  687. if (dockingSource== null)
  688. dockingSource = toolBar.getParent();
  689. if ( propertyListener != null )
  690. UIManager.removePropertyChangeListener( propertyListener );
  691. dockingSource.add(constraint, toolBar);
  692. }
  693. dockingSource.invalidate();
  694. Container dockingSourceParent = dockingSource.getParent();
  695. if (dockingSourceParent != null)
  696. dockingSourceParent.validate();
  697. dockingSource.repaint();
  698. }
  699. }
  700. private int mapConstraintToOrientation(String constraint)
  701. {
  702. int orientation = toolBar.getOrientation();
  703. if ( constraint != null )
  704. {
  705. if ( constraint.equals(BorderLayout.EAST) || constraint.equals(BorderLayout.WEST) )
  706. orientation = JToolBar.VERTICAL;
  707. else if ( constraint.equals(BorderLayout.NORTH) || constraint.equals(BorderLayout.SOUTH) )
  708. orientation = JToolBar.HORIZONTAL;
  709. }
  710. return orientation;
  711. }
  712. public void setOrientation(int orientation)
  713. {
  714. toolBar.setOrientation( orientation );
  715. if (dragWindow !=null)
  716. dragWindow.setOrientation(orientation);
  717. }
  718. /**
  719. * Gets the color displayed when over a docking area
  720. */
  721. public Color getDockingColor() {
  722. return dockingColor;
  723. }
  724. /**
  725. * Sets the color displayed when over a docking area
  726. */
  727. public void setDockingColor(Color c) {
  728. this.dockingColor = c;
  729. }
  730. /**
  731. * Gets the color displayed when over a floating area
  732. */
  733. public Color getFloatingColor() {
  734. return floatingColor;
  735. }
  736. /**
  737. * Sets the color displayed when over a floating area
  738. */
  739. public void setFloatingColor(Color c) {
  740. this.floatingColor = c;
  741. }
  742. public boolean canDock(Component c, Point p) {
  743. boolean b = false;
  744. if (c.contains(p)) {
  745. dockingSensitivity = (toolBar.getOrientation() == JToolBar.HORIZONTAL) ? toolBar.getSize().height : toolBar.getSize().width;
  746. // North
  747. if (p.y < dockingSensitivity)
  748. b = true;
  749. // South
  750. if (p.y > c.getSize().height-dockingSensitivity)
  751. b = true;
  752. // West (Base distance on height for now!)
  753. if (p.x < dockingSensitivity)
  754. b = true;
  755. // East (Base distance on height for now!)
  756. if (p.x > c.getSize().width-dockingSensitivity)
  757. b = true;
  758. }
  759. return b;
  760. }
  761. private String calculateConstraint(Component c, Point p) {
  762. if (p == null) return constraintBeforeFloating;
  763. String s = BorderLayout.NORTH;
  764. if (c.contains(p)) {
  765. dockingSensitivity = (toolBar.getOrientation() == JToolBar.HORIZONTAL) ? toolBar.getSize().height : toolBar.getSize().width;
  766. if (p.y >= dockingSource.getSize().height-dockingSensitivity)
  767. s = BorderLayout.SOUTH;
  768. // West (Base distance on height for now!)
  769. else if (p.x < dockingSensitivity && (toolBar.getOrientation() == JToolBar.VERTICAL))
  770. s = BorderLayout.WEST;
  771. // East (Base distance on height for now!)
  772. else if (p.x >= dockingSource.getSize().width-dockingSensitivity && (toolBar.getOrientation() == JToolBar.VERTICAL))
  773. s = BorderLayout.EAST;
  774. // North (Base distance on height for now!)
  775. else if (p.y < dockingSensitivity)
  776. s = BorderLayout.NORTH;
  777. }
  778. return s;
  779. }
  780. private String getDockingConstraint(Component c, Point p) {
  781. if (p == null) return constraintBeforeFloating;
  782. String s = BorderLayout.NORTH;
  783. if (c.contains(p)) {
  784. dockingSensitivity = (toolBar.getOrientation() == JToolBar.HORIZONTAL) ? toolBar.getSize().height : toolBar.getSize().width;
  785. if (p.y >= dockingSource.getSize().height-dockingSensitivity)
  786. s = BorderLayout.SOUTH;
  787. // West (Base distance on height for now!)
  788. if (p.x < dockingSensitivity)
  789. s = BorderLayout.WEST;
  790. // East (Base distance on height for now!)
  791. if (p.x >= dockingSource.getSize().width-dockingSensitivity)
  792. s = BorderLayout.EAST;
  793. // North (Base distance on height for now!)
  794. if (p.y < dockingSensitivity)
  795. s = BorderLayout.NORTH;
  796. }
  797. return s;
  798. }
  799. protected void dragTo(Point position, Point origin)
  800. {
  801. if (toolBar.isFloatable() == true)
  802. {
  803. try
  804. {
  805. if (dragWindow == null)
  806. dragWindow = createDragWindow(toolBar);
  807. Point offset = dragWindow.getOffset();
  808. if (offset == null) {
  809. Dimension size = toolBar.getPreferredSize();
  810. offset = new Point(size.width2, size.height2);
  811. dragWindow.setOffset(offset);
  812. }
  813. Point global = new Point(origin.x+ position.x,
  814. origin.y+position.y);
  815. Point dragPoint = new Point(global.x- offset.x,
  816. global.y- offset.y);
  817. if (dockingSource == null)
  818. dockingSource = toolBar.getParent();
  819. Point p = new Point(origin);
  820. SwingUtilities.convertPointFromScreen(p,toolBar.getParent());
  821. constraintBeforeFloating = calculateConstraint(dockingSource, p);
  822. Point dockingPosition = dockingSource.getLocationOnScreen();
  823. Point comparisonPoint = new Point(global.x-dockingPosition.x,
  824. global.y-dockingPosition.y);
  825. if (canDock(dockingSource, comparisonPoint)) {
  826. dragWindow.setBackground(getDockingColor());
  827. String constraint = getDockingConstraint(dockingSource,
  828. comparisonPoint);
  829. int orientation = mapConstraintToOrientation(constraint);
  830. dragWindow.setOrientation(orientation);
  831. dragWindow.setBorderColor(dockingBorderColor);
  832. } else {
  833. dragWindow.setBackground(getFloatingColor());
  834. dragWindow.setOrientation( JToolBar.HORIZONTAL );
  835. dragWindow.setBorderColor(floatingBorderColor);
  836. }
  837. dragWindow.setLocation(dragPoint.x, dragPoint.y);
  838. if (dragWindow.isVisible() == false) {
  839. Dimension size = toolBar.getPreferredSize();
  840. dragWindow.setSize(size.width, size.height);
  841. dragWindow.show();
  842. }
  843. }
  844. catch ( IllegalComponentStateException e )
  845. {
  846. }
  847. }
  848. }
  849. protected void floatAt(Point position, Point origin)
  850. {
  851. if(toolBar.isFloatable() == true)
  852. {
  853. try
  854. {
  855. Point offset = dragWindow.getOffset();
  856. if (offset == null) {
  857. offset = position;
  858. dragWindow.setOffset(offset);
  859. }
  860. Point global = new Point(origin.x+ position.x,
  861. origin.y+position.y);
  862. setFloatingLocation(global.x-offset.x,
  863. global.y-offset.y);
  864. if (dockingSource != null) {
  865. Point dockingPosition = dockingSource.getLocationOnScreen();
  866. Point comparisonPoint = new Point(global.x-dockingPosition.x,
  867. global.y-dockingPosition.y);
  868. if (canDock(dockingSource, comparisonPoint)) {
  869. setFloating(false, comparisonPoint);
  870. } else {
  871. setFloating(true, null);
  872. }
  873. } else {
  874. setFloating(true, null);
  875. }
  876. dragWindow.setOffset(null);
  877. }
  878. catch ( IllegalComponentStateException e )
  879. {
  880. }
  881. }
  882. }
  883. protected ContainerListener createToolBarContListener( )
  884. {
  885. return new ToolBarContListener( );
  886. }
  887. protected FocusListener createToolBarFocusListener( )
  888. {
  889. return new ToolBarFocusListener( );
  890. }
  891. protected PropertyChangeListener createPropertyListener()
  892. {
  893. return new PropertyListener();
  894. }
  895. protected MouseInputListener createDockingListener( ) {
  896. return new DockingListener(toolBar);
  897. }
  898. protected WindowListener createFrameListener() {
  899. return new FrameListener();
  900. }
  901. // The private inner classes below should be changed to protected the
  902. // next time API changes are allowed.
  903. private static abstract class KeyAction extends AbstractAction {
  904. public boolean isEnabled() {
  905. return true;
  906. }
  907. };
  908. private static class RightAction extends KeyAction {
  909. public void actionPerformed(ActionEvent e) {
  910. JToolBar toolBar = (JToolBar)e.getSource();
  911. BasicToolBarUI ui = (BasicToolBarUI)toolBar.getUI();
  912. ui.navigateFocusedComp(EAST);
  913. }
  914. };
  915. private static class LeftAction extends KeyAction {
  916. public void actionPerformed(ActionEvent e) {
  917. JToolBar toolBar = (JToolBar)e.getSource();
  918. BasicToolBarUI ui = (BasicToolBarUI)toolBar.getUI();
  919. ui.navigateFocusedComp(WEST);
  920. }
  921. };
  922. private static class UpAction extends KeyAction {
  923. public void actionPerformed(ActionEvent e) {
  924. JToolBar toolBar = (JToolBar)e.getSource();
  925. BasicToolBarUI ui = (BasicToolBarUI)toolBar.getUI();
  926. ui.navigateFocusedComp(NORTH);
  927. }
  928. };
  929. private static class DownAction extends KeyAction {
  930. public void actionPerformed(ActionEvent e) {
  931. JToolBar toolBar = (JToolBar)e.getSource();
  932. BasicToolBarUI ui = (BasicToolBarUI)toolBar.getUI();
  933. ui.navigateFocusedComp(SOUTH);
  934. }
  935. };
  936. protected class FrameListener extends WindowAdapter {
  937. public void windowClosing(WindowEvent w) {
  938. if (toolBar.isFloatable() == true) {
  939. if (dragWindow != null)
  940. dragWindow.setVisible(false);
  941. floating = false;
  942. if (floatingToolBar == null)
  943. floatingToolBar = createFloatingWindow(toolBar);
  944. if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false);
  945. floatingToolBar.getContentPane().remove(toolBar);
  946. String constraint = constraintBeforeFloating;
  947. int orientation = mapConstraintToOrientation(constraint);
  948. setOrientation(orientation);
  949. if (dockingSource == null)
  950. dockingSource = toolBar.getParent();
  951. if (propertyListener != null)
  952. UIManager.removePropertyChangeListener(propertyListener);
  953. dockingSource.add(constraint, toolBar);
  954. dockingSource.invalidate();
  955. Container dockingSourceParent = dockingSource.getParent();
  956. if (dockingSourceParent != null)
  957. dockingSourceParent.validate();
  958. dockingSource.repaint();
  959. setFloating(false,null);
  960. }
  961. }
  962. }
  963. protected class ToolBarContListener implements ContainerListener
  964. {
  965. public void componentAdded( ContainerEvent e ) {
  966. Component c = e.getChild();
  967. if ( toolBarFocusListener != null ) {
  968. c.addFocusListener( toolBarFocusListener );
  969. }
  970. if (isRolloverBorders()) {
  971. setBorderToRollover(c);
  972. } else {
  973. setBorderToNonRollover(c);
  974. }
  975. }
  976. public void componentRemoved( ContainerEvent e ) {
  977. Component c = e.getChild();
  978. if ( toolBarFocusListener != null ) {
  979. c.removeFocusListener( toolBarFocusListener );
  980. }
  981. // Revert the button border
  982. setBorderToNormal(c);
  983. }
  984. } // end class ToolBarContListener
  985. protected class ToolBarFocusListener implements FocusListener
  986. {
  987. public void focusGained( FocusEvent e )
  988. {
  989. Component c = e.getComponent();
  990. focusedCompIndex = toolBar.getComponentIndex( c );
  991. }
  992. public void focusLost( FocusEvent e )
  993. {
  994. }
  995. } // end class ToolBarFocusListener
  996. protected class PropertyListener implements PropertyChangeListener
  997. {
  998. public void propertyChange( PropertyChangeEvent e ) {
  999. String propertyName = e.getPropertyName();
  1000. if ( propertyName.equals("lookAndFeel") ) {
  1001. toolBar.updateUI();
  1002. } else if (propertyName.equals("orientation")) {
  1003. // Search for JSeparator components and change it's orientation
  1004. // to match the toolbar and flip it's orientation.
  1005. Component[] components = toolBar.getComponents();
  1006. int orientation = ((Integer)e.getNewValue()).intValue();
  1007. JToolBar.Separator separator;
  1008. for( int i = 0; i < components.length; ++i ) {
  1009. if (components[i] instanceof JToolBar.Separator) {
  1010. separator = (JToolBar.Separator)components[i];
  1011. if ((orientation == JToolBar.HORIZONTAL)) {
  1012. separator.setOrientation(JSeparator.VERTICAL);
  1013. } else {
  1014. separator.setOrientation(JSeparator.HORIZONTAL);
  1015. }
  1016. Dimension size = separator.getSeparatorSize();
  1017. if (size != null && size.width != size.height) {
  1018. // Flip the orientation.
  1019. Dimension newSize = new Dimension(size.height, size.width);
  1020. separator.setSeparatorSize(newSize);
  1021. }
  1022. }
  1023. }
  1024. } else if (propertyName.equals( IS_ROLLOVER )) {
  1025. setRolloverBorders(((Boolean)e.getNewValue()).booleanValue());
  1026. }
  1027. }
  1028. }
  1029. /**
  1030. * This inner class is marked "public" due to a compiler bug.
  1031. * This class should be treated as a "protected" inner class.
  1032. * Instantiate it only within subclasses of BasicToolBarUI.
  1033. */
  1034. public class DockingListener implements MouseInputListener {
  1035. protected JToolBar toolBar;
  1036. protected boolean isDragging = false;
  1037. protected Point origin = null;
  1038. public DockingListener(JToolBar t) {
  1039. this.toolBar = t;
  1040. }
  1041. public void mouseClicked(MouseEvent e) {}
  1042. public void mousePressed(MouseEvent e) {
  1043. if (!toolBar.isEnabled()) {
  1044. return;
  1045. }
  1046. isDragging = false;
  1047. }
  1048. public void mouseReleased(MouseEvent e) {
  1049. if (!toolBar.isEnabled()) {
  1050. return;
  1051. }
  1052. if (isDragging == true) {
  1053. Point position = e.getPoint();
  1054. if (origin == null)
  1055. origin = e.getComponent().getLocationOnScreen();
  1056. floatAt(position, origin);
  1057. }
  1058. origin = null;
  1059. isDragging = false;
  1060. }
  1061. public void mouseEntered(MouseEvent e) { }
  1062. public void mouseExited(MouseEvent e) { }
  1063. public void mouseDragged(MouseEvent e) {
  1064. if (!toolBar.isEnabled()) {
  1065. return;
  1066. }
  1067. isDragging = true;
  1068. Point position = e.getPoint();
  1069. if (origin == null)
  1070. origin = e.getComponent().getLocationOnScreen();
  1071. dragTo(position, origin);
  1072. }
  1073. public void mouseMoved(MouseEvent e) {
  1074. }
  1075. }
  1076. protected class DragWindow extends Window
  1077. {
  1078. Color borderColor = Color.gray;
  1079. int orientation = toolBar.getOrientation();
  1080. Point offset; // offset of the mouse cursor inside the DragWindow
  1081. DragWindow(Window w) {
  1082. super(w);
  1083. }
  1084. public void setOrientation(int o) {
  1085. if(isShowing()) {
  1086. if (o == this.orientation)
  1087. return;
  1088. this.orientation = o;
  1089. Dimension size = getSize();
  1090. setSize(new Dimension(size.height, size.width));
  1091. if (offset!=null) {
  1092. if( BasicGraphicsUtils.isLeftToRight(toolBar) ) {
  1093. setOffset(new Point(offset.y, offset.x));
  1094. } else if( o == JToolBar.HORIZONTAL ) {
  1095. setOffset(new Point( size.height-offset.y, offset.x));
  1096. } else {
  1097. setOffset(new Point(offset.y, size.width-offset.x));
  1098. }
  1099. }
  1100. repaint();
  1101. }
  1102. }
  1103. public Point getOffset() {
  1104. return offset;
  1105. }
  1106. public void setOffset(Point p) {
  1107. this.offset = p;
  1108. }
  1109. public void setBorderColor(Color c) {
  1110. if (this.borderColor == c)
  1111. return;
  1112. this.borderColor = c;
  1113. repaint();
  1114. }
  1115. public Color getBorderColor() {
  1116. return this.borderColor;
  1117. }
  1118. public void paint(Graphics g) {
  1119. Color temp = g.getColor();
  1120. g.setColor(getBackground());
  1121. Dimension size = getSize();
  1122. g.fillRect(0,0,size.width, size.height);
  1123. g.setColor(getBorderColor());
  1124. g.drawRect(0,0,size.width-1, size.height-1);
  1125. g.setColor(temp);
  1126. super.paint(g);
  1127. }
  1128. public Insets getInsets() {
  1129. return new Insets(1,1,1,1);
  1130. }
  1131. }
  1132. }