1. /*
  2. * @(#)JToolBar.java 1.105 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;
  8. import java.awt.Color;
  9. import java.awt.Component;
  10. import java.awt.ComponentOrientation;
  11. import java.awt.Container;
  12. import java.awt.Dimension;
  13. import java.awt.Graphics;
  14. import java.awt.Insets;
  15. import java.awt.LayoutManager;
  16. import java.awt.LayoutManager2;
  17. import java.awt.event.*;
  18. import java.beans.*;
  19. import javax.swing.border.Border;
  20. import javax.swing.plaf.*;
  21. import javax.accessibility.*;
  22. import java.io.Serializable;
  23. import java.io.ObjectOutputStream;
  24. import java.io.ObjectInputStream;
  25. import java.io.IOException;
  26. import java.util.Hashtable;
  27. /**
  28. * <code>JToolBar</code> provides a component that is useful for
  29. * displaying commonly used <code>Action</code>s or controls.
  30. * For examples and information on using tool bars see
  31. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/toolbar.html">How to Use Tool Bars</a>,
  32. * a section in <em>The Java Tutorial</em>.
  33. *
  34. * <p>
  35. * With most look and feels,
  36. * the user can drag out a tool bar into a separate window
  37. * (unless the <code>floatable</code> property is set to <code>false</code>).
  38. * For drag-out to work correctly, it is recommended that you add
  39. * <code>JToolBar</code> instances to one of the four "sides" of a
  40. * container whose layout manager is a <code>BorderLayout</code>,
  41. * and do not add children to any of the other four "sides".
  42. * <p>
  43. * For the keyboard keys used by this component in the standard Look and
  44. * Feel (L&F) renditions, see the
  45. * <a href="doc-files/Key-Index.html#JToolBar"><code>JToolBar</code> key assignments</a>.
  46. * <p>
  47. * <strong>Warning:</strong>
  48. * Serialized objects of this class will not be compatible with
  49. * future Swing releases. The current serialization support is
  50. * appropriate for short term storage or RMI between applications running
  51. * the same version of Swing. As of 1.4, support for long term storage
  52. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  53. * has been added to the <code>java.beans</code> package.
  54. * Please see {@link java.beans.XMLEncoder}.
  55. *
  56. * @beaninfo
  57. * attribute: isContainer true
  58. * description: A component which displays commonly used controls or Actions.
  59. *
  60. * @version 1.105 01/23/03
  61. * @author Georges Saab
  62. * @author Jeff Shapiro
  63. * @see Action
  64. */
  65. public class JToolBar extends JComponent implements SwingConstants, Accessible
  66. {
  67. /**
  68. * @see #getUIClassID
  69. * @see #readObject
  70. */
  71. private static final String uiClassID = "ToolBarUI";
  72. private boolean paintBorder = true;
  73. private Insets margin = null;
  74. private boolean floatable = true;
  75. private int orientation = HORIZONTAL;
  76. /**
  77. * Creates a new tool bar; orientation defaults to <code>HORIZONTAL</code>.
  78. */
  79. public JToolBar()
  80. {
  81. this( HORIZONTAL );
  82. }
  83. /**
  84. * Creates a new tool bar with the specified <code>orientation</code>.
  85. * The <code>orientation</code> must be either <code>HORIZONTAL</code>
  86. * or <code>VERTICAL</code>.
  87. *
  88. * @param orientation the orientation desired
  89. */
  90. public JToolBar( int orientation )
  91. {
  92. this(null, orientation);
  93. }
  94. /**
  95. * Creates a new tool bar with the specified <code>name</code>. The
  96. * name is used as the title of the undocked tool bar. The default
  97. * orientation is <code>HORIZONTAL</code>.
  98. *
  99. * @param name the name of the tool bar
  100. * @since 1.3
  101. */
  102. public JToolBar( String name ) {
  103. this(name, HORIZONTAL);
  104. }
  105. /**
  106. * Creates a new tool bar with a specified <code>name</code> and
  107. * <code>orientation</code>.
  108. * All other constructors call this constructor.
  109. * If <code>orientation</code> is an invalid value, an exception will
  110. * be thrown.
  111. *
  112. * @param name the name of the tool bar
  113. * @param orientation the initial orientation -- it must be
  114. * either <code>HORIZONTAL</code> or <code>VERTICAL</code>
  115. * @exception IllegalArgumentException if orientation is neither
  116. * <code>HORIZONTAL</code> nor <code>VERTICAL</code>
  117. * @since 1.3
  118. */
  119. public JToolBar( String name , int orientation) {
  120. setName(name);
  121. checkOrientation( orientation );
  122. this.orientation = orientation;
  123. DefaultToolBarLayout layout = new DefaultToolBarLayout( orientation );
  124. setLayout( layout );
  125. addPropertyChangeListener( layout );
  126. updateUI();
  127. }
  128. /**
  129. * Returns the tool bar's current UI.
  130. * @see #setUI
  131. */
  132. public ToolBarUI getUI() {
  133. return (ToolBarUI)ui;
  134. }
  135. /**
  136. * Sets the L&F object that renders this component.
  137. *
  138. * @param ui the <code>ToolBarUI</code> L&F object
  139. * @see UIDefaults#getUI
  140. * @beaninfo
  141. * bound: true
  142. * hidden: true
  143. * attribute: visualUpdate true
  144. * description: The UI object that implements the Component's LookAndFeel.
  145. */
  146. public void setUI(ToolBarUI ui) {
  147. super.setUI(ui);
  148. }
  149. /**
  150. * Notification from the <code>UIFactory</code> that the L&F has changed.
  151. * Called to replace the UI with the latest version from the
  152. * <code>UIFactory</code>.
  153. *
  154. * @see JComponent#updateUI
  155. */
  156. public void updateUI() {
  157. setUI((ToolBarUI)UIManager.getUI(this));
  158. // GTKLookAndFeel installs a different LayoutManager, and sets it
  159. // to null after changing the look and feel, so, install the default
  160. // if the LayoutManager is null.
  161. if (getLayout() == null) {
  162. setLayout(new DefaultToolBarLayout(getOrientation()));
  163. }
  164. invalidate();
  165. }
  166. /**
  167. * Returns the name of the L&F class that renders this component.
  168. *
  169. * @return the string "ToolBarUI"
  170. * @see JComponent#getUIClassID
  171. * @see UIDefaults#getUI
  172. */
  173. public String getUIClassID() {
  174. return uiClassID;
  175. }
  176. /**
  177. * Returns the index of the specified component.
  178. * (Note: Separators occupy index positions.)
  179. *
  180. * @param c the <code>Component</code> to find
  181. * @return an integer indicating the component's position,
  182. * where 0 is first
  183. */
  184. public int getComponentIndex(Component c) {
  185. int ncomponents = this.getComponentCount();
  186. Component[] component = this.getComponents();
  187. for (int i = 0 ; i < ncomponents ; i++) {
  188. Component comp = component[i];
  189. if (comp == c)
  190. return i;
  191. }
  192. return -1;
  193. }
  194. /**
  195. * Returns the component at the specified index.
  196. *
  197. * @param i the component's position, where 0 is first
  198. * @return the <code>Component</code> at that position,
  199. * or <code>null</code> for an invalid index
  200. *
  201. */
  202. public Component getComponentAtIndex(int i) {
  203. int ncomponents = this.getComponentCount();
  204. if ( i >= 0 && i < ncomponents) {
  205. Component[] component = this.getComponents();
  206. return component[i];
  207. }
  208. return null;
  209. }
  210. /**
  211. * Sets the margin between the tool bar's border and
  212. * its buttons. Setting to <code>null</code> causes the tool bar to
  213. * use the default margins. The tool bar's default <code>Border</code>
  214. * object uses this value to create the proper margin.
  215. * However, if a non-default border is set on the tool bar,
  216. * it is that <code>Border</code> object's responsibility to create the
  217. * appropriate margin space (otherwise this property will
  218. * effectively be ignored).
  219. *
  220. * @param m an <code>Insets</code> object that defines the space
  221. * between the border and the buttons
  222. * @see Insets
  223. * @beaninfo
  224. * description: The margin between the tool bar's border and contents
  225. * bound: true
  226. * expert: true
  227. */
  228. public void setMargin(Insets m)
  229. {
  230. Insets old = margin;
  231. margin = m;
  232. firePropertyChange("margin", old, m);
  233. revalidate();
  234. repaint();
  235. }
  236. /**
  237. * Returns the margin between the tool bar's border and
  238. * its buttons.
  239. *
  240. * @return an <code>Insets</code> object containing the margin values
  241. * @see Insets
  242. */
  243. public Insets getMargin()
  244. {
  245. if(margin == null) {
  246. return new Insets(0,0,0,0);
  247. } else {
  248. return margin;
  249. }
  250. }
  251. /**
  252. * Gets the <code>borderPainted</code> property.
  253. *
  254. * @return the value of the <code>borderPainted</code> property
  255. * @see #setBorderPainted
  256. */
  257. public boolean isBorderPainted()
  258. {
  259. return paintBorder;
  260. }
  261. /**
  262. * Sets the <code>borderPainted</code> property, which is
  263. * <code>true</code> if the border should be painted.
  264. * The default value for this property is <code>true</code>.
  265. * Some look and feels might not implement painted borders;
  266. * they will ignore this property.
  267. *
  268. * @param b if true, the border is painted
  269. * @see #isBorderPainted
  270. * @beaninfo
  271. * description: Does the tool bar paint its borders?
  272. * bound: true
  273. * expert: true
  274. */
  275. public void setBorderPainted(boolean b)
  276. {
  277. if ( paintBorder != b )
  278. {
  279. boolean old = paintBorder;
  280. paintBorder = b;
  281. firePropertyChange("borderPainted", old, b);
  282. revalidate();
  283. repaint();
  284. }
  285. }
  286. /**
  287. * Paints the tool bar's border if the <code>borderPainted</code> property
  288. * is <code>true</code>.
  289. *
  290. * @param g the <code>Graphics</code> context in which the painting
  291. * is done
  292. * @see JComponent#paint
  293. * @see JComponent#setBorder
  294. */
  295. protected void paintBorder(Graphics g)
  296. {
  297. if (isBorderPainted())
  298. {
  299. super.paintBorder(g);
  300. }
  301. }
  302. /**
  303. * Gets the <code>floatable</code> property.
  304. *
  305. * @return the value of the <code>floatable</code> property
  306. *
  307. * @see #setFloatable
  308. */
  309. public boolean isFloatable()
  310. {
  311. return floatable;
  312. }
  313. /**
  314. * Sets the <code>floatable</code> property,
  315. * which must be <code>true</code> for the user to move the tool bar.
  316. * Typically, a floatable tool bar can be
  317. * dragged into a different position within the same container
  318. * or out into its own window.
  319. * The default value of this property is <code>true</code>.
  320. * Some look and feels might not implement floatable tool bars;
  321. * they will ignore this property.
  322. *
  323. * @param b if <code>true</code>, the tool bar can be moved;
  324. * <code>false</code> otherwise
  325. * @see #isFloatable
  326. * @beaninfo
  327. * description: Can the tool bar be made to float by the user?
  328. * bound: true
  329. * preferred: true
  330. */
  331. public void setFloatable( boolean b )
  332. {
  333. if ( floatable != b )
  334. {
  335. boolean old = floatable;
  336. floatable = b;
  337. firePropertyChange("floatable", old, b);
  338. revalidate();
  339. repaint();
  340. }
  341. }
  342. /**
  343. * Returns the current orientation of the tool bar. The value is either
  344. * <code>HORIZONTAL</code> or <code>VERTICAL</code>.
  345. *
  346. * @return an integer representing the current orientation -- either
  347. * <code>HORIZONTAL</code> or <code>VERTICAL</code>
  348. * @see #setOrientation
  349. */
  350. public int getOrientation()
  351. {
  352. return this.orientation;
  353. }
  354. /**
  355. * Sets the orientation of the tool bar. The orientation must have
  356. * either the value <code>HORIZONTAL</code> or <code>VERTICAL</code>.
  357. * If <code>orientation</code> is
  358. * an invalid value, an exception will be thrown.
  359. *
  360. * @param o the new orientation -- either <code>HORIZONTAL</code> or
  361. * </code>VERTICAL</code>
  362. * @exception IllegalArgumentException if orientation is neither
  363. * <code>HORIZONTAL</code> nor <code>VERTICAL</code>
  364. * @see #getOrientation
  365. * @beaninfo
  366. * description: The current orientation of the tool bar
  367. * bound: true
  368. * preferred: true
  369. */
  370. public void setOrientation( int o )
  371. {
  372. checkOrientation( o );
  373. if ( orientation != o )
  374. {
  375. int old = orientation;
  376. orientation = o;
  377. firePropertyChange("orientation", old, o);
  378. revalidate();
  379. repaint();
  380. }
  381. }
  382. /**
  383. * Sets the rollover state of this toolbar. If the rollover state is true
  384. * then the border of the toolbar buttons will be drawn only when the
  385. * mouse pointer hovers over them. The default value of this property
  386. * is false.
  387. * <p>
  388. * The implementation of a look and feel may choose to ignore this
  389. * property.
  390. *
  391. * @param rollover true for rollover toolbar buttons; otherwise false
  392. * @since 1.4
  393. * @beaninfo
  394. * bound: true
  395. * preferred: true
  396. * attribute: visualUpdate true
  397. * description: Will draw rollover button borders in the toolbar.
  398. */
  399. public void setRollover(boolean rollover) {
  400. putClientProperty("JToolBar.isRollover",
  401. rollover ? Boolean.TRUE : Boolean.FALSE);
  402. }
  403. /**
  404. * Returns the rollover state.
  405. *
  406. * @return true if rollover toolbar buttons are to be drawn; otherwise false
  407. * @see #setRollover(boolean)
  408. * @since 1.4
  409. */
  410. public boolean isRollover() {
  411. Boolean rollover = (Boolean)getClientProperty("JToolBar.isRollover");
  412. if (rollover != null) {
  413. return rollover.booleanValue();
  414. }
  415. return false;
  416. }
  417. private void checkOrientation( int orientation )
  418. {
  419. switch ( orientation )
  420. {
  421. case VERTICAL:
  422. case HORIZONTAL:
  423. break;
  424. default:
  425. throw new IllegalArgumentException( "orientation must be one of: VERTICAL, HORIZONTAL" );
  426. }
  427. }
  428. /**
  429. * Appends a separator of default size to the end of the tool bar.
  430. * The default size is determined by the current look and feel.
  431. */
  432. public void addSeparator()
  433. {
  434. addSeparator(null);
  435. }
  436. /**
  437. * Appends a separator of a specified size to the end
  438. * of the tool bar.
  439. *
  440. * @param size the <code>Dimension</code> of the separator
  441. */
  442. public void addSeparator( Dimension size )
  443. {
  444. JToolBar.Separator s = new JToolBar.Separator( size );
  445. if (getOrientation() == VERTICAL) {
  446. s.setOrientation(JSeparator.HORIZONTAL);
  447. } else {
  448. s.setOrientation(JSeparator.VERTICAL);
  449. }
  450. add(s);
  451. }
  452. /**
  453. * Adds a new <code>JButton</code> which dispatches the action.
  454. *
  455. * <p>
  456. * As of 1.3, this is no longer the preferred method for adding
  457. * <code>Action</code>s to a container. Instead it is recommended
  458. * to configure a control with an action using
  459. * using <code>setAction</code>, and then add that control directly
  460. * to the <code>Container</code>.
  461. *
  462. * @param a the <code>Action</code> object to add as a new menu item
  463. * @return the new button which dispatches the action
  464. */
  465. public JButton add(Action a) {
  466. JButton b = createActionComponent(a);
  467. b.setAction(a);
  468. add(b);
  469. return b;
  470. }
  471. /**
  472. * Factory method which creates the <code>JButton</code> for
  473. * <code>Action</code>s added to the <code>JToolBar</code>.
  474. * The default name is empty if a <code>null</code> action is passed.
  475. *
  476. * <p>
  477. * As of 1.3, this is no longer the preferred method for adding
  478. * <code>Action</code>s to a <code>Container</code>.
  479. * Instead it is recommended to configure a control with an action
  480. * using <code>setAction</code>, and then add that control directly
  481. * to the <code>Container</code>.
  482. *
  483. * @param a the <code>Action</code> for the button to be added
  484. * @return the newly created button
  485. * @see Action
  486. */
  487. protected JButton createActionComponent(Action a) {
  488. String text = a!=null? (String)a.getValue(Action.NAME) : null;
  489. Icon icon = a!=null? (Icon)a.getValue(Action.SMALL_ICON) : null;
  490. boolean enabled = a!=null? a.isEnabled() : true;
  491. String tooltip = a!=null?
  492. (String)a.getValue(Action.SHORT_DESCRIPTION) : null;
  493. JButton b = new JButton(text, icon) {
  494. protected PropertyChangeListener createActionPropertyChangeListener(Action a) {
  495. PropertyChangeListener pcl = createActionChangeListener(this);
  496. if (pcl==null) {
  497. pcl = super.createActionPropertyChangeListener(a);
  498. }
  499. return pcl;
  500. }
  501. };
  502. if (icon !=null) {
  503. b.putClientProperty("hideActionText", Boolean.TRUE);
  504. }
  505. b.setHorizontalTextPosition(JButton.CENTER);
  506. b.setVerticalTextPosition(JButton.BOTTOM);
  507. b.setEnabled(enabled);
  508. b.setToolTipText(tooltip);
  509. return b;
  510. }
  511. /**
  512. * Returns a properly configured <code>PropertyChangeListener</code>
  513. * which updates the control as changes to the <code>Action</code> occur,
  514. * or <code>null</code> if the default
  515. * property change listener for the control is desired.
  516. *
  517. * <p>
  518. * As of 1.3, this is no longer the preferred method for adding
  519. * <code>Action</code>s to a <code>Container</code>.
  520. * Instead it is recommended to configure a control with an action
  521. * using <code>setAction</code>, and then add that control directly
  522. * to the <code>Container</code>.
  523. * @return <code>null</code>
  524. */
  525. protected PropertyChangeListener createActionChangeListener(JButton b) {
  526. return null;
  527. }
  528. /**
  529. * If a <code>JButton</code> is being added, it is initially
  530. * set to be disabled.
  531. *
  532. * @param comp the component to be enhanced
  533. * @param constraints the constraints to be enforced on the component
  534. * @param index the index of the component
  535. *
  536. */
  537. protected void addImpl(Component comp, Object constraints, int index) {
  538. super.addImpl(comp, constraints, index);
  539. if (comp instanceof JButton) {
  540. ((JButton)comp).setDefaultCapable(false);
  541. }
  542. }
  543. /**
  544. * A toolbar-specific separator. An object with dimension but
  545. * no contents used to divide buttons on a tool bar into groups.
  546. */
  547. static public class Separator extends JSeparator
  548. {
  549. private Dimension separatorSize;
  550. /**
  551. * Creates a new toolbar separator with the default size
  552. * as defined by the current look and feel.
  553. */
  554. public Separator()
  555. {
  556. this( null ); // let the UI define the default size
  557. }
  558. /**
  559. * Creates a new toolbar separator with the specified size.
  560. *
  561. * @param size the <code>Dimension</code> of the separator
  562. */
  563. public Separator( Dimension size )
  564. {
  565. super( JSeparator.HORIZONTAL );
  566. setSeparatorSize(size);
  567. }
  568. /**
  569. * Returns the name of the L&F class that renders this component.
  570. *
  571. * @return the string "ToolBarSeparatorUI"
  572. * @see JComponent#getUIClassID
  573. * @see UIDefaults#getUI
  574. */
  575. public String getUIClassID()
  576. {
  577. return "ToolBarSeparatorUI";
  578. }
  579. /**
  580. * Sets the size of the separator.
  581. *
  582. * @param size the new <code>Dimension</code> of the separator
  583. */
  584. public void setSeparatorSize( Dimension size )
  585. {
  586. if (size != null) {
  587. separatorSize = size;
  588. } else {
  589. super.updateUI();
  590. }
  591. this.invalidate();
  592. }
  593. /**
  594. * Returns the size of the separator
  595. *
  596. * @return the <code>Dimension</code> object containing the separator's
  597. * size (This is a reference, NOT a copy!)
  598. */
  599. public Dimension getSeparatorSize()
  600. {
  601. return separatorSize;
  602. }
  603. /**
  604. * Returns the minimum size for the separator.
  605. *
  606. * @return the <code>Dimension</code> object containing the separator's
  607. * minimum size
  608. */
  609. public Dimension getMinimumSize()
  610. {
  611. if (separatorSize != null) {
  612. return separatorSize.getSize();
  613. } else {
  614. return super.getMinimumSize();
  615. }
  616. }
  617. /**
  618. * Returns the maximum size for the separator.
  619. *
  620. * @return the <code>Dimension</code> object containing the separator's
  621. * maximum size
  622. */
  623. public Dimension getMaximumSize()
  624. {
  625. if (separatorSize != null) {
  626. return separatorSize.getSize();
  627. } else {
  628. return super.getMaximumSize();
  629. }
  630. }
  631. /**
  632. * Returns the preferred size for the separator.
  633. *
  634. * @return the <code>Dimension</code> object containing the separator's
  635. * preferred size
  636. */
  637. public Dimension getPreferredSize()
  638. {
  639. if (separatorSize != null) {
  640. return separatorSize.getSize();
  641. } else {
  642. return super.getPreferredSize();
  643. }
  644. }
  645. }
  646. /**
  647. * See <code>readObject</code> and <code>writeObject</code> in
  648. * <code>JComponent</code> for more
  649. * information about serialization in Swing.
  650. */
  651. private void writeObject(ObjectOutputStream s) throws IOException {
  652. s.defaultWriteObject();
  653. if (getUIClassID().equals(uiClassID)) {
  654. byte count = JComponent.getWriteObjCounter(this);
  655. JComponent.setWriteObjCounter(this, --count);
  656. if (count == 0 && ui != null) {
  657. ui.installUI(this);
  658. }
  659. }
  660. }
  661. /**
  662. * Returns a string representation of this <code>JToolBar</code>.
  663. * This method
  664. * is intended to be used only for debugging purposes, and the
  665. * content and format of the returned string may vary between
  666. * implementations. The returned string may be empty but may not
  667. * be <code>null</code>.
  668. *
  669. * @return a string representation of this <code>JToolBar</code>.
  670. */
  671. protected String paramString() {
  672. String paintBorderString = (paintBorder ?
  673. "true" : "false");
  674. String marginString = (margin != null ?
  675. margin.toString() : "");
  676. String floatableString = (floatable ?
  677. "true" : "false");
  678. String orientationString = (orientation == HORIZONTAL ?
  679. "HORIZONTAL" : "VERTICAL");
  680. return super.paramString() +
  681. ",floatable=" + floatableString +
  682. ",margin=" + marginString +
  683. ",orientation=" + orientationString +
  684. ",paintBorder=" + paintBorderString;
  685. }
  686. private class DefaultToolBarLayout
  687. implements LayoutManager2, Serializable, PropertyChangeListener, UIResource {
  688. LayoutManager lm;
  689. DefaultToolBarLayout(int orientation) {
  690. if (orientation == JToolBar.VERTICAL) {
  691. lm = new BoxLayout(JToolBar.this, BoxLayout.PAGE_AXIS);
  692. } else {
  693. lm = new BoxLayout(JToolBar.this, BoxLayout.LINE_AXIS);
  694. }
  695. }
  696. public void addLayoutComponent(String name, Component comp) {
  697. }
  698. public void addLayoutComponent(Component comp, Object constraints) {
  699. }
  700. public void removeLayoutComponent(Component comp) {
  701. }
  702. public Dimension preferredLayoutSize(Container target) {
  703. return lm.preferredLayoutSize(target);
  704. }
  705. public Dimension minimumLayoutSize(Container target) {
  706. return lm.minimumLayoutSize(target);
  707. }
  708. public Dimension maximumLayoutSize(Container target) {
  709. if (lm instanceof LayoutManager2) {
  710. return ((LayoutManager2)lm).maximumLayoutSize(target);
  711. } else {
  712. // Code copied from java.awt.Component.getMaximumSize()
  713. // to avoid infinite recursion.
  714. // See also java.awt.Container.getMaximumSize()
  715. return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
  716. }
  717. }
  718. public void layoutContainer(Container target) {
  719. lm.layoutContainer(target);
  720. }
  721. public float getLayoutAlignmentX(Container target) {
  722. if (lm instanceof LayoutManager2) {
  723. return ((LayoutManager2)lm).getLayoutAlignmentX(target);
  724. } else {
  725. // Code copied from java.awt.Component.getAlignmentX()
  726. // to avoid infinite recursion.
  727. // See also java.awt.Container.getAlignmentX()
  728. return CENTER_ALIGNMENT;
  729. }
  730. }
  731. public float getLayoutAlignmentY(Container target) {
  732. if (lm instanceof LayoutManager2) {
  733. return ((LayoutManager2)lm).getLayoutAlignmentY(target);
  734. } else {
  735. // Code copied from java.awt.Component.getAlignmentY()
  736. // to avoid infinite recursion.
  737. // See also java.awt.Container.getAlignmentY()
  738. return CENTER_ALIGNMENT;
  739. }
  740. }
  741. public void invalidateLayout(Container target) {
  742. if (lm instanceof LayoutManager2) {
  743. ((LayoutManager2)lm).invalidateLayout(target);
  744. }
  745. }
  746. public void propertyChange(PropertyChangeEvent e) {
  747. String name = e.getPropertyName();
  748. if( name.equals("orientation") ) {
  749. int o = ((Integer)e.getNewValue()).intValue();
  750. if (o == JToolBar.VERTICAL)
  751. lm = new BoxLayout(JToolBar.this, BoxLayout.PAGE_AXIS);
  752. else {
  753. lm = new BoxLayout(JToolBar.this, BoxLayout.LINE_AXIS);
  754. }
  755. }
  756. }
  757. }
  758. public void setLayout(LayoutManager mgr) {
  759. LayoutManager oldMgr = getLayout();
  760. if (oldMgr instanceof PropertyChangeListener) {
  761. removePropertyChangeListener((PropertyChangeListener)oldMgr);
  762. }
  763. super.setLayout(mgr);
  764. }
  765. /////////////////
  766. // Accessibility support
  767. ////////////////
  768. /**
  769. * Gets the AccessibleContext associated with this JToolBar.
  770. * For tool bars, the AccessibleContext takes the form of an
  771. * AccessibleJToolBar.
  772. * A new AccessibleJToolBar instance is created if necessary.
  773. *
  774. * @return an AccessibleJToolBar that serves as the
  775. * AccessibleContext of this JToolBar
  776. */
  777. public AccessibleContext getAccessibleContext() {
  778. if (accessibleContext == null) {
  779. accessibleContext = new AccessibleJToolBar();
  780. }
  781. return accessibleContext;
  782. }
  783. /**
  784. * This class implements accessibility support for the
  785. * <code>JToolBar</code> class. It provides an implementation of the
  786. * Java Accessibility API appropriate to toolbar user-interface elements.
  787. */
  788. protected class AccessibleJToolBar extends AccessibleJComponent {
  789. /**
  790. * Get the state of this object.
  791. *
  792. * @return an instance of AccessibleStateSet containing the current
  793. * state set of the object
  794. * @see AccessibleState
  795. */
  796. public AccessibleStateSet getAccessibleStateSet() {
  797. AccessibleStateSet states = super.getAccessibleStateSet();
  798. // FIXME: [[[WDW - need to add orientation from BoxLayout]]]
  799. // FIXME: [[[WDW - need to do SELECTABLE if SelectionModel is added]]]
  800. return states;
  801. }
  802. /**
  803. * Get the role of this object.
  804. *
  805. * @return an instance of AccessibleRole describing the role of the object
  806. */
  807. public AccessibleRole getAccessibleRole() {
  808. return AccessibleRole.TOOL_BAR;
  809. }
  810. } // inner class AccessibleJToolBar
  811. }