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