1. /*
  2. * @(#)JScrollPane.java 1.91 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 javax.swing.plaf.*;
  9. import javax.swing.border.*;
  10. import javax.swing.event.*;
  11. import javax.accessibility.*;
  12. import java.awt.Component;
  13. import java.awt.ComponentOrientation;
  14. import java.awt.Graphics;
  15. import java.awt.Rectangle;
  16. import java.awt.Insets;
  17. import java.awt.Color;
  18. import java.awt.LayoutManager;
  19. import java.awt.Point;
  20. import java.io.ObjectOutputStream;
  21. import java.io.ObjectInputStream;
  22. import java.io.IOException;
  23. /**
  24. * Provides a scrollable view of a lightweight component.
  25. * A <code>JScrollPane</code> manages a viewport, optional
  26. * vertical and horizontal scroll bars, and optional row and
  27. * column heading viewports.
  28. * You can find task-oriented documentation of <code>JScrollPane</code> in
  29. * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/scrollpane.html">How to Use Scroll Panes</a>,
  30. * a section in <em>The Java Tutorial</em>. Note that
  31. * <code>JScrollPane</code> does not support heavyweight components.
  32. * <p>
  33. * <TABLE ALIGN="RIGHT" BORDER="0" SUMMARY="layout">
  34. * <TR>
  35. * <TD ALIGN="CENTER">
  36. * <P ALIGN="CENTER"><IMG SRC="doc-files/JScrollPane-1.gif"
  37. * alt="The following text describes this image."
  38. * WIDTH="256" HEIGHT="248" ALIGN="BOTTOM" BORDER="0">
  39. * </TD>
  40. * </TR>
  41. * </TABLE>
  42. * The <code>JViewport</code> provides a window,
  43. * or "viewport" onto a data
  44. * source -- for example, a text file. That data source is the
  45. * "scrollable client" (aka data model) displayed by the
  46. * <code>JViewport</code> view.
  47. * A <code>JScrollPane</code> basically consists of <code>JScrollBar</code>s,
  48. * a <code>JViewport</code>, and the wiring between them,
  49. * as shown in the diagram at right.
  50. * <p>
  51. * In addition to the scroll bars and viewport,
  52. * a <code>JScrollPane</code> can have a
  53. * column header and a row header. Each of these is a
  54. * <code>JViewport</code> object that
  55. * you specify with <code>setRowHeaderView</code>,
  56. * and <code>setColumnHeaderView</code>.
  57. * The column header viewport automatically scrolls left and right, tracking
  58. * the left-right scrolling of the main viewport.
  59. * (It never scrolls vertically, however.)
  60. * The row header acts in a similar fashion.
  61. * <p>
  62. * By default, the corners are empty.
  63. * You can put a component into a corner using
  64. * <code>setCorner</code>,
  65. * in case you there is some function or decoration you
  66. * would like to add to the scroll pane. The size of corner components is
  67. * entirely determined by the size of the headers and scroll bars that
  68. * surround them.
  69. * <p>
  70. * To add a border around the main viewport,
  71. * you can use <code>setViewportBorder</code>.
  72. * (Of course, you can also add a border around the whole scroll pane using
  73. * <code>setBorder</code>.)
  74. * <p>
  75. * For the keyboard keys used by this component in the standard Look and
  76. * Feel (L&F) renditions, see the
  77. * <a href="doc-files/Key-Index.html#JScrollPane">JScrollPane</a>
  78. * key assignments.
  79. * <p>
  80. * A common operation to want to do is to set the background color that will
  81. * be used if the main viewport view is smaller than the viewport, or is
  82. * not opaque. This can be accomplished by setting the background color
  83. * of the viewport, via <code>scrollPane.getViewport().setBackground()</code>.
  84. * The reason for setting the color of the viewport and not the scrollpane
  85. * is that by default <code>JViewport</code> is opaque
  86. * which, among other things, means it will completely fill
  87. * in its background using its background color. Therefore when
  88. * <code>JScrollPane</code> draws its background the viewport will
  89. * usually draw over it.
  90. * <p>
  91. * By default <code>JScrollPane</code> uses <code>ScrollPaneLayout</code>
  92. * to handle the layout of its child Components. <code>ScrollPaneLayout</code>
  93. * determines the size to make the viewport view in one of two ways:
  94. * <ol>
  95. * <li>If the view implements <code>Scrollable</code>
  96. * a combination of <code>getPreferredScrollableViewportSize</code>,
  97. * <code>getScrollableTracksViewportWidth</code> and
  98. * <code>getScrollableTracksViewportHeight</code>is used, otherwise
  99. * <li><code>getPreferredSize</code> is used.
  100. * </ol>
  101. * <p>
  102. * <strong>Warning:</strong>
  103. * Serialized objects of this class will not be compatible with
  104. * future Swing releases. The current serialization support is
  105. * appropriate for short term storage or RMI between applications running
  106. * the same version of Swing. As of 1.4, support for long term storage
  107. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  108. * has been added to the <code>java.beans</code> package.
  109. * Please see {@link java.beans.XMLEncoder}.
  110. *
  111. * @see JScrollBar
  112. * @see JViewport
  113. * @see ScrollPaneLayout
  114. * @see Scrollable
  115. * @see Component#getPreferredSize
  116. * @see #setViewportView
  117. * @see #setRowHeaderView
  118. * @see #setColumnHeaderView
  119. * @see #setCorner
  120. * @see #setViewportBorder
  121. *
  122. * @beaninfo
  123. * attribute: isContainer true
  124. * attribute: containerDelegate getViewport
  125. * description: A specialized container that manages a viewport, optional scrollbars and headers
  126. *
  127. * @version 1.79 09/01/00
  128. * @author Hans Muller
  129. */
  130. public class JScrollPane extends JComponent implements ScrollPaneConstants, Accessible
  131. {
  132. private Border viewportBorder;
  133. /**
  134. * @see #getUIClassID
  135. * @see #readObject
  136. */
  137. private static final String uiClassID = "ScrollPaneUI";
  138. /**
  139. * The display policy for the vertical scrollbar.
  140. * The default is <code>JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED</code>.
  141. * @see #setVerticalScrollBarPolicy
  142. */
  143. protected int verticalScrollBarPolicy = VERTICAL_SCROLLBAR_AS_NEEDED;
  144. /**
  145. * The display policy for the horizontal scrollbar.
  146. * The default is <code>JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED</code>.
  147. * @see #setHorizontalScrollBarPolicy
  148. */
  149. protected int horizontalScrollBarPolicy = HORIZONTAL_SCROLLBAR_AS_NEEDED;
  150. /**
  151. * The scrollpane's viewport child. Default is an empty
  152. * <code>JViewport</code>.
  153. * @see #setViewport
  154. */
  155. protected JViewport viewport;
  156. /**
  157. * The scrollpane's vertical scrollbar child.
  158. * Default is a <code>JScrollBar</code>.
  159. * @see #setVerticalScrollBar
  160. */
  161. protected JScrollBar verticalScrollBar;
  162. /**
  163. * The scrollpane's horizontal scrollbar child.
  164. * Default is a <code>JScrollBar</code>.
  165. * @see #setHorizontalScrollBar
  166. */
  167. protected JScrollBar horizontalScrollBar;
  168. /**
  169. * The row header child. Default is <code>null</code>.
  170. * @see #setRowHeader
  171. */
  172. protected JViewport rowHeader;
  173. /**
  174. * The column header child. Default is <code>null</code>.
  175. * @see #setColumnHeader
  176. */
  177. protected JViewport columnHeader;
  178. /**
  179. * The component to display in the lower left corner.
  180. * Default is <code>null</code>.
  181. * @see #setCorner
  182. */
  183. protected Component lowerLeft;
  184. /**
  185. * The component to display in the lower right corner.
  186. * Default is <code>null</code>.
  187. * @see #setCorner
  188. */
  189. protected Component lowerRight;
  190. /**
  191. * The component to display in the upper left corner.
  192. * Default is <code>null</code>.
  193. * @see #setCorner
  194. */
  195. protected Component upperLeft;
  196. /**
  197. * The component to display in the upper right corner.
  198. * Default is <code>null</code>.
  199. * @see #setCorner
  200. */
  201. protected Component upperRight;
  202. /*
  203. * State flag for mouse wheel scrolling
  204. */
  205. private boolean wheelScrollState = true;
  206. /**
  207. * Creates a <code>JScrollPane</code> that displays the view
  208. * component in a viewport
  209. * whose view position can be controlled with a pair of scrollbars.
  210. * The scrollbar policies specify when the scrollbars are displayed,
  211. * For example, if <code>vsbPolicy</code> is
  212. * <code>VERTICAL_SCROLLBAR_AS_NEEDED</code>
  213. * then the vertical scrollbar only appears if the view doesn't fit
  214. * vertically. The available policy settings are listed at
  215. * {@link #setVerticalScrollBarPolicy} and
  216. * {@link #setHorizontalScrollBarPolicy}.
  217. *
  218. * @see #setViewportView
  219. *
  220. * @param view the component to display in the scrollpanes viewport
  221. * @param vsbPolicy an integer that specifies the vertical
  222. * scrollbar policy
  223. * @param hsbPolicy an integer that specifies the horizontal
  224. * scrollbar policy
  225. */
  226. public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
  227. {
  228. setLayout(new ScrollPaneLayout.UIResource());
  229. setVerticalScrollBarPolicy(vsbPolicy);
  230. setHorizontalScrollBarPolicy(hsbPolicy);
  231. setViewport(createViewport());
  232. setVerticalScrollBar(createVerticalScrollBar());
  233. setHorizontalScrollBar(createHorizontalScrollBar());
  234. if (view != null) {
  235. setViewportView(view);
  236. }
  237. setOpaque(true);
  238. updateUI();
  239. if (!this.getComponentOrientation().isLeftToRight()) {
  240. viewport.setViewPosition(new Point(Integer.MAX_VALUE, 0));
  241. }
  242. }
  243. /**
  244. * Creates a <code>JScrollPane</code> that displays the
  245. * contents of the specified
  246. * component, where both horizontal and vertical scrollbars appear
  247. * whenever the component's contents are larger than the view.
  248. *
  249. * @see #setViewportView
  250. * @param view the component to display in the scrollpane's viewport
  251. */
  252. public JScrollPane(Component view) {
  253. this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
  254. }
  255. /**
  256. * Creates an empty (no viewport view) <code>JScrollPane</code>
  257. * with specified
  258. * scrollbar policies. The available policy settings are listed at
  259. * {@link #setVerticalScrollBarPolicy} and
  260. * {@link #setHorizontalScrollBarPolicy}.
  261. *
  262. * @see #setViewportView
  263. *
  264. * @param vsbPolicy an integer that specifies the vertical
  265. * scrollbar policy
  266. * @param hsbPolicy an integer that specifies the horizontal
  267. * scrollbar policy
  268. */
  269. public JScrollPane(int vsbPolicy, int hsbPolicy) {
  270. this(null, vsbPolicy, hsbPolicy);
  271. }
  272. /**
  273. * Creates an empty (no viewport view) <code>JScrollPane</code>
  274. * where both horizontal and vertical scrollbars appear when needed.
  275. */
  276. public JScrollPane() {
  277. this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
  278. }
  279. /**
  280. * Returns the look and feel (L&F) object that renders this component.
  281. *
  282. * @return the <code>ScrollPaneUI</code> object that renders this
  283. * component
  284. * @see #setUI
  285. * @beaninfo
  286. * bound: true
  287. * hidden: true
  288. * attribute: visualUpdate true
  289. * description: The UI object that implements the Component's LookAndFeel.
  290. */
  291. public ScrollPaneUI getUI() {
  292. return (ScrollPaneUI)ui;
  293. }
  294. /**
  295. * Sets the <code>ScrollPaneUI</code> object that provides the
  296. * look and feel (L&F) for this component.
  297. *
  298. * @param ui the <code>ScrollPaneUI</code> L&F object
  299. * @see #getUI
  300. */
  301. public void setUI(ScrollPaneUI ui) {
  302. super.setUI(ui);
  303. }
  304. /**
  305. * Replaces the current <code>ScrollPaneUI</code> object with a version
  306. * from the current default look and feel.
  307. * To be called when the default look and feel changes.
  308. *
  309. * @see JComponent#updateUI
  310. * @see UIManager#getUI
  311. */
  312. public void updateUI() {
  313. setUI((ScrollPaneUI)UIManager.getUI(this));
  314. }
  315. /**
  316. * Returns the suffix used to construct the name of the L&F class used to
  317. * render this component.
  318. *
  319. * @return the string "ScrollPaneUI"
  320. * @see JComponent#getUIClassID
  321. * @see UIDefaults#getUI
  322. *
  323. * @beaninfo
  324. * hidden: true
  325. */
  326. public String getUIClassID() {
  327. return uiClassID;
  328. }
  329. /**
  330. * Sets the layout manager for this <code>JScrollPane</code>.
  331. * This method overrides <code>setLayout</code> in
  332. * <code>java.awt.Container</code> to ensure that only
  333. * <code>LayoutManager</code>s which
  334. * are subclasses of <code>ScrollPaneLayout</code> can be used in a
  335. * <code>JScrollPane</code>. If <code>layout</code> is non-null, this
  336. * will invoke <code>syncWithScrollPane</code> on it.
  337. *
  338. * @param layout the specified layout manager
  339. * @exception ClassCastException if layout is not a
  340. * <code>ScrollPaneLayout</code>
  341. * @see java.awt.Container#getLayout
  342. * @see java.awt.Container#setLayout
  343. *
  344. * @beaninfo
  345. * hidden: true
  346. */
  347. public void setLayout(LayoutManager layout) {
  348. if (layout instanceof ScrollPaneLayout) {
  349. super.setLayout(layout);
  350. ((ScrollPaneLayout)layout).syncWithScrollPane(this);
  351. }
  352. else if (layout == null) {
  353. super.setLayout(layout);
  354. }
  355. else {
  356. String s = "layout of JScrollPane must be a ScrollPaneLayout";
  357. throw new ClassCastException(s);
  358. }
  359. }
  360. /**
  361. * Calls <code>revalidate</code> on any descendant of this
  362. * <code>JScrollPane</code>. For example,
  363. * the viewport's view, will cause a request to be queued that
  364. * will validate the <code>JScrollPane</code> and all its descendants.
  365. *
  366. * @return true
  367. * @see JComponent#revalidate
  368. *
  369. * @beaninfo
  370. * hidden: true
  371. */
  372. public boolean isValidateRoot() {
  373. return true;
  374. }
  375. /**
  376. * Returns the vertical scroll bar policy value.
  377. * @return the <code>verticalScrollBarPolicy</code> property
  378. * @see #setVerticalScrollBarPolicy
  379. */
  380. public int getVerticalScrollBarPolicy() {
  381. return verticalScrollBarPolicy;
  382. }
  383. /**
  384. * Determines when the vertical scrollbar appears in the scrollpane.
  385. * Legal values are:
  386. * <ul>
  387. * <li>JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
  388. * <li>JScrollPane.VERTICAL_SCROLLBAR_NEVER
  389. * <li>JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
  390. * </ul>
  391. *
  392. * @param policy one of the three values listed above
  393. * @exception IllegalArgumentException if <code>policy</code>
  394. * is not one of the legal values shown above
  395. * @see #getVerticalScrollBarPolicy
  396. *
  397. * @beaninfo
  398. * preferred: true
  399. * bound: true
  400. * description: The scrollpane vertical scrollbar policy
  401. * enum: VERTICAL_SCROLLBAR_AS_NEEDED JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
  402. * VERTICAL_SCROLLBAR_NEVER JScrollPane.VERTICAL_SCROLLBAR_NEVER
  403. * VERTICAL_SCROLLBAR_ALWAYS JScrollPane.VERTICAL_SCROLLBAR_ALWAYS
  404. */
  405. public void setVerticalScrollBarPolicy(int policy) {
  406. switch (policy) {
  407. case VERTICAL_SCROLLBAR_AS_NEEDED:
  408. case VERTICAL_SCROLLBAR_NEVER:
  409. case VERTICAL_SCROLLBAR_ALWAYS:
  410. break;
  411. default:
  412. throw new IllegalArgumentException("invalid verticalScrollBarPolicy");
  413. }
  414. int old = verticalScrollBarPolicy;
  415. verticalScrollBarPolicy = policy;
  416. firePropertyChange("verticalScrollBarPolicy", old, policy);
  417. revalidate();
  418. repaint();
  419. }
  420. /**
  421. * Returns the horizontal scroll bar policy value.
  422. * @return the <code>horizontalScrollBarPolicy</code> property
  423. * @see #setHorizontalScrollBarPolicy
  424. */
  425. public int getHorizontalScrollBarPolicy() {
  426. return horizontalScrollBarPolicy;
  427. }
  428. /**
  429. * Determines when the horizontal scrollbar appears in the scrollpane.
  430. * The options are:<ul>
  431. * <li>JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
  432. * <li>JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
  433. * <li>JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
  434. * </ul>
  435. *
  436. * @param policy one of the three values listed above
  437. * @exception IllegalArgumentException if <code>policy</code>
  438. * is not one of the legal values shown above
  439. * @see #getHorizontalScrollBarPolicy
  440. *
  441. * @beaninfo
  442. * preferred: true
  443. * bound: true
  444. * description: The scrollpane scrollbar policy
  445. * enum: HORIZONTAL_SCROLLBAR_AS_NEEDED JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED
  446. * HORIZONTAL_SCROLLBAR_NEVER JScrollPane.HORIZONTAL_SCROLLBAR_NEVER
  447. * HORIZONTAL_SCROLLBAR_ALWAYS JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS
  448. */
  449. public void setHorizontalScrollBarPolicy(int policy) {
  450. switch (policy) {
  451. case HORIZONTAL_SCROLLBAR_AS_NEEDED:
  452. case HORIZONTAL_SCROLLBAR_NEVER:
  453. case HORIZONTAL_SCROLLBAR_ALWAYS:
  454. break;
  455. default:
  456. throw new IllegalArgumentException("invalid horizontalScrollBarPolicy");
  457. }
  458. int old = horizontalScrollBarPolicy;
  459. horizontalScrollBarPolicy = policy;
  460. firePropertyChange("horizontalScrollBarPolicy", old, policy);
  461. revalidate();
  462. repaint();
  463. }
  464. /**
  465. * Returns the <code>Border</code> object that surrounds the viewport.
  466. *
  467. * @return the <code>viewportBorder</code> property
  468. * @see #setViewportBorder
  469. */
  470. public Border getViewportBorder() {
  471. return viewportBorder;
  472. }
  473. /**
  474. * Adds a border around the viewport. Note that the border isn't
  475. * set on the viewport directly, <code>JViewport</code> doesn't support
  476. * the <code>JComponent</code> border property.
  477. * Similarly setting the <code>JScrollPane</code>s
  478. * viewport doesn't affect the <code>viewportBorder</code> property.
  479. * <p>
  480. * The default value of this property is computed by the look
  481. * and feel implementation.
  482. *
  483. * @param viewportBorder the border to be added
  484. * @see #getViewportBorder
  485. * @see #setViewport
  486. *
  487. * @beaninfo
  488. * preferred: true
  489. * bound: true
  490. * description: The border around the viewport.
  491. */
  492. public void setViewportBorder(Border viewportBorder) {
  493. Border oldValue = this.viewportBorder;
  494. this.viewportBorder = viewportBorder;
  495. firePropertyChange("viewportBorder", oldValue, viewportBorder);
  496. }
  497. /**
  498. * Returns the bounds of the viewport's border.
  499. *
  500. * @return a <code>Rectangle</code> object specifying the viewport border
  501. */
  502. public Rectangle getViewportBorderBounds()
  503. {
  504. Rectangle borderR = new Rectangle(getSize());
  505. Insets insets = getInsets();
  506. borderR.x = insets.left;
  507. borderR.y = insets.top;
  508. borderR.width -= insets.left + insets.right;
  509. borderR.height -= insets.top + insets.bottom;
  510. boolean leftToRight = SwingUtilities.isLeftToRight(this);
  511. /* If there's a visible column header remove the space it
  512. * needs from the top of borderR.
  513. */
  514. JViewport colHead = getColumnHeader();
  515. if ((colHead != null) && (colHead.isVisible())) {
  516. int colHeadHeight = colHead.getHeight();
  517. borderR.y += colHeadHeight;
  518. borderR.height -= colHeadHeight;
  519. }
  520. /* If there's a visible row header remove the space it needs
  521. * from the left of borderR.
  522. */
  523. JViewport rowHead = getRowHeader();
  524. if ((rowHead != null) && (rowHead.isVisible())) {
  525. int rowHeadWidth = rowHead.getWidth();
  526. if ( leftToRight ) {
  527. borderR.x += rowHeadWidth;
  528. }
  529. borderR.width -= rowHeadWidth;
  530. }
  531. /* If there's a visible vertical scrollbar remove the space it needs
  532. * from the width of borderR.
  533. */
  534. JScrollBar vsb = getVerticalScrollBar();
  535. if ((vsb != null) && (vsb.isVisible())) {
  536. int vsbWidth = vsb.getWidth();
  537. if ( !leftToRight ) {
  538. borderR.x += vsbWidth;
  539. }
  540. borderR.width -= vsbWidth;
  541. }
  542. /* If there's a visible horizontal scrollbar remove the space it needs
  543. * from the height of borderR.
  544. */
  545. JScrollBar hsb = getHorizontalScrollBar();
  546. if ((hsb != null) && (hsb.isVisible())) {
  547. borderR.height -= hsb.getHeight();
  548. }
  549. return borderR;
  550. }
  551. /**
  552. * By default <code>JScrollPane</code> creates scrollbars
  553. * that are instances
  554. * of this class. <code>Scrollbar</code> overrides the
  555. * <code>getUnitIncrement</code> and <code>getBlockIncrement</code>
  556. * methods so that, if the viewport's view is a <code>Scrollable</code>,
  557. * the view is asked to compute these values. Unless
  558. * the unit/block increment have been explicitly set.
  559. * <p>
  560. * <strong>Warning:</strong>
  561. * Serialized objects of this class will not be compatible with
  562. * future Swing releases. The current serialization support is
  563. * appropriate for short term storage or RMI between applications running
  564. * the same version of Swing. As of 1.4, support for long term storage
  565. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  566. * has been added to the <code>java.beans</code> package.
  567. * Please see {@link java.beans.XMLEncoder}.
  568. *
  569. * @see Scrollable
  570. * @see JScrollPane#createVerticalScrollBar
  571. * @see JScrollPane#createHorizontalScrollBar
  572. */
  573. protected class ScrollBar extends JScrollBar implements UIResource
  574. {
  575. /**
  576. * Set to true when the unit increment has been explicitly set.
  577. * If this is false the viewport's view is obtained and if it
  578. * is an instance of <code>Scrollable</code> the unit increment
  579. * from it is used.
  580. */
  581. private boolean unitIncrementSet;
  582. /**
  583. * Set to true when the block increment has been explicitly set.
  584. * If this is false the viewport's view is obtained and if it
  585. * is an instance of <code>Scrollable</code> the block increment
  586. * from it is used.
  587. */
  588. private boolean blockIncrementSet;
  589. /**
  590. * Creates a scrollbar with the specified orientation,
  591. * where the options are:<ul>
  592. * <li>JScrollPane.VERTICAL
  593. * <li>JScrollPane.HORIZONTAL
  594. * </ul>
  595. *
  596. * @param orientation an integer specifying one of the legal
  597. * orientation values shown above
  598. */
  599. public ScrollBar(int orientation) {
  600. super(orientation);
  601. }
  602. /**
  603. * Messages super to set the value, and resets the
  604. * <code>unitIncrementSet</code> instance variable to true.
  605. *
  606. * @param unitIncrement the new unit increment value, in pixels
  607. */
  608. public void setUnitIncrement(int unitIncrement) {
  609. unitIncrementSet = true;
  610. super.setUnitIncrement(unitIncrement);
  611. }
  612. /**
  613. * Computes the unit increment for scrolling if the viewport's
  614. * view is a <code>Scrollable</code> object.
  615. * Otherwise return <code>super.getUnitIncrement</code>.
  616. *
  617. * @param direction less than zero to scroll up/left,
  618. * greater than zero for down/right
  619. * @return an integer, in pixels, containing the unit increment
  620. * @see Scrollable#getScrollableUnitIncrement
  621. */
  622. public int getUnitIncrement(int direction) {
  623. JViewport vp = getViewport();
  624. if (!unitIncrementSet && (vp != null) &&
  625. (vp.getView() instanceof Scrollable)) {
  626. Scrollable view = (Scrollable)(vp.getView());
  627. Rectangle vr = vp.getViewRect();
  628. return view.getScrollableUnitIncrement(vr, getOrientation(), direction);
  629. }
  630. else {
  631. return super.getUnitIncrement(direction);
  632. }
  633. }
  634. /**
  635. * Messages super to set the value, and resets the
  636. * <code>blockIncrementSet</code> instance variable to true.
  637. *
  638. * @param blockIncrement the new block increment value, in pixels
  639. */
  640. public void setBlockIncrement(int blockIncrement) {
  641. blockIncrementSet = true;
  642. super.setBlockIncrement(blockIncrement);
  643. }
  644. /**
  645. * Computes the block increment for scrolling if the viewport's
  646. * view is a <code>Scrollable</code> object. Otherwise
  647. * the <code>blockIncrement</code> equals the viewport's width
  648. * or height. If there's no viewport return
  649. * <code>super.getBlockIncrement</code>.
  650. *
  651. * @param direction less than zero to scroll up/left,
  652. * greater than zero for down/right
  653. * @return an integer, in pixels, containing the block increment
  654. * @see Scrollable#getScrollableBlockIncrement
  655. */
  656. public int getBlockIncrement(int direction) {
  657. JViewport vp = getViewport();
  658. if (blockIncrementSet || vp == null) {
  659. return super.getBlockIncrement(direction);
  660. }
  661. else if (vp.getView() instanceof Scrollable) {
  662. Scrollable view = (Scrollable)(vp.getView());
  663. Rectangle vr = vp.getViewRect();
  664. return view.getScrollableBlockIncrement(vr, getOrientation(), direction);
  665. }
  666. else if (getOrientation() == VERTICAL) {
  667. return vp.getExtentSize().height;
  668. }
  669. else {
  670. return vp.getExtentSize().width;
  671. }
  672. }
  673. }
  674. /**
  675. * Returns a <code>JScrollPane.ScrollBar</code> by default.
  676. * Subclasses may override this method to force <code>ScrollPaneUI</code>
  677. * implementations to use a <code>JScrollBar</code> subclass.
  678. * Used by <code>ScrollPaneUI</code> implementations to
  679. * create the horizontal scrollbar.
  680. *
  681. * @return a <code>JScrollBar</code> with a horizontal orientation
  682. * @see JScrollBar
  683. */
  684. public JScrollBar createHorizontalScrollBar() {
  685. return new ScrollBar(JScrollBar.HORIZONTAL);
  686. }
  687. /**
  688. * Returns the horizontal scroll bar that controls the viewport's
  689. * horizontal view position.
  690. *
  691. * @return the <code>horizontalScrollBar</code> property
  692. * @see #setHorizontalScrollBar
  693. */
  694. public JScrollBar getHorizontalScrollBar() {
  695. return horizontalScrollBar;
  696. }
  697. /**
  698. * Adds the scrollbar that controls the viewport's horizontal view
  699. * position to the scrollpane.
  700. * This is usually unnecessary, as <code>JScrollPane</code> creates
  701. * horizontal and vertical scrollbars by default.
  702. *
  703. * @param horizontalScrollBar the horizontal scrollbar to be added
  704. * @see #createHorizontalScrollBar
  705. * @see #getHorizontalScrollBar
  706. *
  707. * @beaninfo
  708. * expert: true
  709. * bound: true
  710. * description: The horizontal scrollbar.
  711. */
  712. public void setHorizontalScrollBar(JScrollBar horizontalScrollBar) {
  713. JScrollBar old = getHorizontalScrollBar();
  714. this.horizontalScrollBar = horizontalScrollBar;
  715. add(horizontalScrollBar, HORIZONTAL_SCROLLBAR);
  716. firePropertyChange("horizontalScrollBar", old, horizontalScrollBar);
  717. revalidate();
  718. repaint();
  719. }
  720. /**
  721. * Returns a <code>JScrollPane.ScrollBar</code> by default. Subclasses
  722. * may override this method to force <code>ScrollPaneUI</code>
  723. * implementations to use a <code>JScrollBar</code> subclass.
  724. * Used by <code>ScrollPaneUI</code> implementations to create the
  725. * vertical scrollbar.
  726. *
  727. * @return a <code>JScrollBar</code> with a vertical orientation
  728. * @see JScrollBar
  729. */
  730. public JScrollBar createVerticalScrollBar() {
  731. return new ScrollBar(JScrollBar.VERTICAL);
  732. }
  733. /**
  734. * Returns the vertical scroll bar that controls the viewports
  735. * vertical view position.
  736. *
  737. * @return the <code>verticalScrollBar</code> property
  738. * @see #setVerticalScrollBar
  739. */
  740. public JScrollBar getVerticalScrollBar() {
  741. return verticalScrollBar;
  742. }
  743. /**
  744. * Adds the scrollbar that controls the viewports vertical view position
  745. * to the scrollpane. This is usually unnecessary,
  746. * as <code>JScrollPane</code> creates vertical and
  747. * horizontal scrollbars by default.
  748. *
  749. * @param verticalScrollBar the new vertical scrollbar to be added
  750. * @see #createVerticalScrollBar
  751. * @see #getVerticalScrollBar
  752. *
  753. * @beaninfo
  754. * expert: true
  755. * bound: true
  756. * description: The vertical scrollbar.
  757. */
  758. public void setVerticalScrollBar(JScrollBar verticalScrollBar) {
  759. JScrollBar old = getVerticalScrollBar();
  760. this.verticalScrollBar = verticalScrollBar;
  761. add(verticalScrollBar, VERTICAL_SCROLLBAR);
  762. firePropertyChange("verticalScrollBar", old, verticalScrollBar);
  763. revalidate();
  764. repaint();
  765. }
  766. /**
  767. * Returns a new <code>JViewport</code> by default.
  768. * Used to create the
  769. * viewport (as needed) in <code>setViewportView</code>,
  770. * <code>setRowHeaderView</code>, and <code>setColumnHeaderView</code>.
  771. * Subclasses may override this method to return a subclass of
  772. * <code>JViewport</code>.
  773. *
  774. * @return a new <code>JViewport</code>
  775. */
  776. protected JViewport createViewport() {
  777. return new JViewport();
  778. }
  779. /**
  780. * Returns the current <code>JViewport</code>.
  781. *
  782. * @see #setViewport
  783. * @return the <code>viewport</code> property
  784. */
  785. public JViewport getViewport() {
  786. return viewport;
  787. }
  788. /**
  789. * Removes the old viewport (if there is one); forces the
  790. * viewPosition of the new viewport to be in the +x,+y quadrant;
  791. * syncs up the row and column headers (if there are any) with the
  792. * new viewport; and finally syncs the scrollbars and
  793. * headers with the new viewport.
  794. * <p>
  795. * Most applications will find it more convenient to use
  796. * <code>setViewportView</code>
  797. * to add a viewport and a view to the scrollpane.
  798. *
  799. * @param viewport the new viewport to be used; if viewport is
  800. * <code>null</code>, the old viewport is still removed
  801. * and the new viewport is set to <code>null</code>
  802. * @see #createViewport
  803. * @see #getViewport
  804. * @see #setViewportView
  805. *
  806. * @beaninfo
  807. * expert: true
  808. * bound: true
  809. * attribute: visualUpdate true
  810. * description: The viewport child for this scrollpane
  811. *
  812. */
  813. public void setViewport(JViewport viewport) {
  814. JViewport old = getViewport();
  815. this.viewport = viewport;
  816. if (viewport != null) {
  817. add(viewport, VIEWPORT);
  818. }
  819. else if (old != null) {
  820. remove(old);
  821. }
  822. firePropertyChange("viewport", old, viewport);
  823. if (accessibleContext != null) {
  824. ((AccessibleJScrollPane)accessibleContext).resetViewPort();
  825. }
  826. revalidate();
  827. repaint();
  828. }
  829. /**
  830. * Creates a viewport if necessary and then sets its view. Applications
  831. * that don't provide the view directly to the <code>JScrollPane</code>
  832. * constructor
  833. * should use this method to specify the scrollable child that's going
  834. * to be displayed in the scrollpane. For example:
  835. * <pre>
  836. * JScrollPane scrollpane = new JScrollPane();
  837. * scrollpane.setViewportView(myBigComponentToScroll);
  838. * </pre>
  839. * Applications should not add children directly to the scrollpane.
  840. *
  841. * @param view the component to add to the viewport
  842. * @see #setViewport
  843. * @see JViewport#setView
  844. */
  845. public void setViewportView(Component view) {
  846. if (getViewport() == null) {
  847. setViewport(createViewport());
  848. }
  849. getViewport().setView(view);
  850. }
  851. /**
  852. * Returns the row header.
  853. * @return the <code>rowHeader</code> property
  854. * @see #setRowHeader
  855. */
  856. public JViewport getRowHeader() {
  857. return rowHeader;
  858. }
  859. /**
  860. * Removes the old rowHeader, if it exists. If the new rowHeader
  861. * isn't <code>null</code>, syncs the y coordinate of its
  862. * viewPosition with
  863. * the viewport (if there is one) and then adds it to the scrollpane.
  864. * <p>
  865. * Most applications will find it more convenient to use
  866. * <code>setRowHeaderView</code>
  867. * to add a row header component and its viewport to the scrollpane.
  868. *
  869. * @param rowHeader the new row header to be used; if <code>null</code>
  870. * the old row header is still removed and the new rowHeader
  871. * is set to <code>null</code>
  872. * @see #getRowHeader
  873. * @see #setRowHeaderView
  874. *
  875. * @beaninfo
  876. * bound: true
  877. * expert: true
  878. * description: The row header child for this scrollpane
  879. */
  880. public void setRowHeader(JViewport rowHeader) {
  881. JViewport old = getRowHeader();
  882. this.rowHeader = rowHeader;
  883. if (rowHeader != null) {
  884. add(rowHeader, ROW_HEADER);
  885. }
  886. else if (old != null) {
  887. remove(old);
  888. }
  889. firePropertyChange("rowHeader", old, rowHeader);
  890. revalidate();
  891. repaint();
  892. }
  893. /**
  894. * Creates a row-header viewport if necessary, sets
  895. * its view and then adds the row-header viewport
  896. * to the scrollpane. For example:
  897. * <pre>
  898. * JScrollPane scrollpane = new JScrollPane();
  899. * scrollpane.setViewportView(myBigComponentToScroll);
  900. * scrollpane.setRowHeaderView(myBigComponentsRowHeader);
  901. * </pre>
  902. *
  903. * @see #setRowHeader
  904. * @see JViewport#setView
  905. * @param view the component to display as the row header
  906. */
  907. public void setRowHeaderView(Component view) {
  908. if (getRowHeader() == null) {
  909. setRowHeader(createViewport());
  910. }
  911. getRowHeader().setView(view);
  912. }
  913. /**
  914. * Returns the column header.
  915. * @return the <code>columnHeader</code> property
  916. * @see #setColumnHeader
  917. */
  918. public JViewport getColumnHeader() {
  919. return columnHeader;
  920. }
  921. /**
  922. * Removes the old columnHeader, if it exists. If the new columnHeader
  923. * isn't <code>null</code>, sync the x coordinate of the its viewPosition
  924. * with the viewport (if there is one) and then add it to the scrollpane.
  925. * <p>
  926. * Most applications will find it more convenient to use
  927. * <code>setRowHeaderView</code>
  928. * to add a row header component and its viewport to the scrollpane.
  929. *
  930. * @see #getColumnHeader
  931. * @see #setColumnHeaderView
  932. *
  933. * @beaninfo
  934. * bound: true
  935. * description: The column header child for this scrollpane
  936. * attribute: visualUpdate true
  937. */
  938. public void setColumnHeader(JViewport columnHeader) {
  939. JViewport old = getColumnHeader();
  940. this.columnHeader = columnHeader;
  941. if (columnHeader != null) {
  942. add(columnHeader, COLUMN_HEADER);
  943. }
  944. else if (old != null) {
  945. remove(old);
  946. }
  947. firePropertyChange("columnHeader", old, columnHeader);
  948. revalidate();
  949. repaint();
  950. }
  951. /**
  952. * Creates a column-header viewport if necessary, sets
  953. * its view, and then adds the column-header viewport
  954. * to the scrollpane. For example:
  955. * <pre>
  956. * JScrollPane scrollpane = new JScrollPane();
  957. * scrollpane.setViewportView(myBigComponentToScroll);
  958. * scrollpane.setColumnHeaderView(myBigComponentsColumnHeader);
  959. * </pre>
  960. *
  961. * @see #setColumnHeader
  962. * @see JViewport#setView
  963. *
  964. * @param view the component to display as the column header
  965. */
  966. public void setColumnHeaderView(Component view) {
  967. if (getColumnHeader() == null) {
  968. setColumnHeader(createViewport());
  969. }
  970. getColumnHeader().setView(view);
  971. }
  972. /**
  973. * Returns the component at the specified corner. The
  974. * <code>key</code> value specifying the corner is one of:
  975. * <ul>
  976. * <li>JScrollPane.LOWER_LEFT_CORNER
  977. * <li>JScrollPane.LOWER_RIGHT_CORNER
  978. * <li>JScrollPane.UPPER_LEFT_CORNER
  979. * <li>JScrollPane.UPPER_RIGHT_CORNER
  980. * <li>JScrollPane.LOWER_LEADING_CORNER
  981. * <li>JScrollPane.LOWER_TRAILING_CORNER
  982. * <li>JScrollPane.UPPER_LEADING_CORNER
  983. * <li>JScrollPane.UPPER_TRAILING_CORNER
  984. * </ul>
  985. *
  986. * @param key one of the values as shown above
  987. * @return one of the components listed below or <code>null</code>
  988. * if <code>key</code> is invalid:
  989. * <ul>
  990. * <li>lowerLeft
  991. * <li>lowerRight
  992. * <li>upperLeft
  993. * <li>upperRight
  994. * </ul>
  995. * @see #setCorner
  996. */
  997. public Component getCorner(String key) {
  998. if (key.equals(LOWER_LEFT_CORNER)) {
  999. return lowerLeft;
  1000. }
  1001. else if (key.equals(LOWER_RIGHT_CORNER)) {
  1002. return lowerRight;
  1003. }
  1004. else if (key.equals(UPPER_LEFT_CORNER)) {
  1005. return upperLeft;
  1006. }
  1007. else if (key.equals(UPPER_RIGHT_CORNER)) {
  1008. return upperRight;
  1009. }
  1010. else {
  1011. return null;
  1012. }
  1013. }
  1014. /**
  1015. * Adds a child that will appear in one of the scroll panes
  1016. * corners, if there's room. For example with both scrollbars
  1017. * showing (on the right and bottom edges of the scrollpane)
  1018. * the lower left corner component will be shown in the space
  1019. * between ends of the two scrollbars. Legal values for
  1020. * the <b>key</b> are:
  1021. * <ul>
  1022. * <li>JScrollPane.LOWER_LEFT_CORNER
  1023. * <li>JScrollPane.LOWER_RIGHT_CORNER
  1024. * <li>JScrollPane.UPPER_LEFT_CORNER
  1025. * <li>JScrollPane.UPPER_RIGHT_CORNER
  1026. * <li>JScrollPane.LOWER_LEADING_CORNER
  1027. * <li>JScrollPane.LOWER_TRAILING_CORNER
  1028. * <li>JScrollPane.UPPER_LEADING_CORNER
  1029. * <li>JScrollPane.UPPER_TRAILING_CORNER
  1030. * </ul>
  1031. * <p>
  1032. * Although "corner" doesn't match any beans property
  1033. * signature, <code>PropertyChange</code> events are generated with the
  1034. * property name set to the corner key.
  1035. *
  1036. * @param key identifies which corner the component will appear in
  1037. * @param corner one of the following components:
  1038. * <ul>
  1039. * <li>lowerLeft
  1040. * <li>lowerRight
  1041. * <li>upperLeft
  1042. * <li>upperRight
  1043. * </ul>
  1044. * @exception IllegalArgumentException if corner key is invalid
  1045. */
  1046. public void setCorner(String key, Component corner)
  1047. {
  1048. Component old;
  1049. if (key.equals(LOWER_LEFT_CORNER)) {
  1050. old = lowerLeft;
  1051. lowerLeft = corner;
  1052. }
  1053. else if (key.equals(LOWER_RIGHT_CORNER)) {
  1054. old = lowerRight;
  1055. lowerRight = corner;
  1056. }
  1057. else if (key.equals(UPPER_LEFT_CORNER)) {
  1058. old = upperLeft;
  1059. upperLeft = corner;
  1060. }
  1061. else if (key.equals(UPPER_RIGHT_CORNER)) {
  1062. old = upperRight;
  1063. upperRight = corner;
  1064. }
  1065. else {
  1066. throw new IllegalArgumentException("invalid corner key");
  1067. }
  1068. if (old != null) {
  1069. remove(old);
  1070. }
  1071. if (corner != null) {
  1072. add(corner, key);
  1073. }
  1074. firePropertyChange(key, old, corner);
  1075. revalidate();
  1076. repaint();
  1077. }
  1078. /**
  1079. * Sets the orientation for the vertical and horizontal
  1080. * scrollbars as determined by the
  1081. * <code>ComponentOrientation</code> argument.
  1082. *
  1083. * @param co one of the following values:
  1084. * <ul>
  1085. * <li>java.awt.ComponentOrientation.LEFT_TO_RIGHT
  1086. * <li>java.awt.ComponentOrientation.RIGHT_TO_LEFT
  1087. * <li>java.awt.ComponentOrientation.UNKNOWN
  1088. * </ul>
  1089. * @see java.awt.ComponentOrientation
  1090. */
  1091. public void setComponentOrientation( ComponentOrientation co ) {
  1092. super.setComponentOrientation( co );
  1093. if( verticalScrollBar != null )
  1094. verticalScrollBar.setComponentOrientation( co );
  1095. if( horizontalScrollBar != null )
  1096. horizontalScrollBar.setComponentOrientation( co );
  1097. }
  1098. /**
  1099. * Indicates whether or not scrolling will take place in response to the
  1100. * mouse wheel. Wheel scrolling is enabled by default.
  1101. *
  1102. * @see #setWheelScrollingEnabled
  1103. * @since 1.4
  1104. * @beaninfo
  1105. * bound: true
  1106. * description: Flag for enabling/disabling mouse wheel scrolling
  1107. */
  1108. public boolean isWheelScrollingEnabled() {return wheelScrollState;}
  1109. /**
  1110. * Enables/disables scrolling in response to movement of the mouse wheel.
  1111. * Wheel scrolling is enabled by default.
  1112. *
  1113. * @param handleWheel <code>true</code> if scrolling should be done
  1114. * automatically for a MouseWheelEvent,
  1115. * <code>false</code> otherwise.
  1116. * @see #isWheelScrollingEnabled
  1117. * @see java.awt.event.MouseWheelEvent
  1118. * @see java.awt.event.MouseWheelListener
  1119. * @since 1.4
  1120. * @beaninfo
  1121. * bound: true
  1122. * description: Flag for enabling/disabling mouse wheel scrolling
  1123. */
  1124. public void setWheelScrollingEnabled(boolean handleWheel) {
  1125. boolean old = wheelScrollState;
  1126. wheelScrollState = handleWheel;
  1127. firePropertyChange("wheelScrollingEnabled", old, handleWheel);
  1128. }
  1129. /**
  1130. * See <code>readObject</code> and <code>writeObject</code> in
  1131. * <code>JComponent</code> for more
  1132. * information about serialization in Swing.
  1133. */
  1134. private void writeObject(ObjectOutputStream s) throws IOException {
  1135. s.defaultWriteObject();
  1136. if (getUIClassID().equals(uiClassID)) {
  1137. byte count = JComponent.getWriteObjCounter(this);
  1138. JComponent.setWriteObjCounter(this, --count);
  1139. if (count == 0 && ui != null) {
  1140. ui.installUI(this);
  1141. }
  1142. }
  1143. }
  1144. /**
  1145. * Returns a string representation of this <code>JScrollPane</code>.
  1146. * This method
  1147. * is intended to be used only for debugging purposes, and the
  1148. * content and format of the returned string may vary between
  1149. * implementations. The returned string may be empty but may not
  1150. * be <code>null</code>.
  1151. *
  1152. * @return a string representation of this <code>JScrollPane</code>.
  1153. */
  1154. protected String paramString() {
  1155. String viewportBorderString = (viewportBorder != null ?
  1156. viewportBorder.toString() : "");
  1157. String viewportString = (viewport != null ?
  1158. viewport.toString() : "");
  1159. String verticalScrollBarPolicyString;
  1160. if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_AS_NEEDED) {
  1161. verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_AS_NEEDED";
  1162. } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_NEVER) {
  1163. verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_NEVER";
  1164. } else if (verticalScrollBarPolicy == VERTICAL_SCROLLBAR_ALWAYS) {
  1165. verticalScrollBarPolicyString = "VERTICAL_SCROLLBAR_ALWAYS";
  1166. } else verticalScrollBarPolicyString = "";
  1167. String horizontalScrollBarPolicyString;
  1168. if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_AS_NEEDED) {
  1169. horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_AS_NEEDED";
  1170. } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_NEVER) {
  1171. horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_NEVER";
  1172. } else if (horizontalScrollBarPolicy == HORIZONTAL_SCROLLBAR_ALWAYS) {
  1173. horizontalScrollBarPolicyString = "HORIZONTAL_SCROLLBAR_ALWAYS";
  1174. } else horizontalScrollBarPolicyString = "";
  1175. String horizontalScrollBarString = (horizontalScrollBar != null ?
  1176. horizontalScrollBar.toString()
  1177. : "");
  1178. String verticalScrollBarString = (verticalScrollBar != null ?
  1179. verticalScrollBar.toString() : "");
  1180. String columnHeaderString = (columnHeader != null ?
  1181. columnHeader.toString() : "");
  1182. String rowHeaderString = (rowHeader != null ?
  1183. rowHeader.toString() : "");
  1184. String lowerLeftString = (lowerLeft != null ?
  1185. lowerLeft.toString() : "");
  1186. String lowerRightString = (lowerRight != null ?
  1187. lowerRight.toString() : "");
  1188. String upperLeftString = (upperLeft != null ?
  1189. upperLeft.toString() : "");
  1190. String upperRightString = (upperRight != null ?
  1191. upperRight.toString() : "");
  1192. return super.paramString() +
  1193. ",columnHeader=" + columnHeaderString +
  1194. ",horizontalScrollBar=" + horizontalScrollBarString +
  1195. ",horizontalScrollBarPolicy=" + horizontalScrollBarPolicyString +
  1196. ",lowerLeft=" + lowerLeftString +
  1197. ",lowerRight=" + lowerRightString +
  1198. ",rowHeader=" + rowHeaderString +
  1199. ",upperLeft=" + upperLeftString +
  1200. ",upperRight=" + upperRightString +
  1201. ",verticalScrollBar=" + verticalScrollBarString +
  1202. ",verticalScrollBarPolicy=" + verticalScrollBarPolicyString +
  1203. ",viewport=" + viewportString +
  1204. ",viewportBorder=" + viewportBorderString;
  1205. }
  1206. /////////////////
  1207. // Accessibility support
  1208. ////////////////
  1209. /**
  1210. * Gets the AccessibleContext associated with this JScrollPane.
  1211. * For scroll panes, the AccessibleContext takes the form of an
  1212. * AccessibleJScrollPane.
  1213. * A new AccessibleJScrollPane instance is created if necessary.
  1214. *
  1215. * @return an AccessibleJScrollPane that serves as the
  1216. * AccessibleContext of this JScrollPane
  1217. */
  1218. public AccessibleContext getAccessibleContext() {
  1219. if (accessibleContext == null) {
  1220. accessibleContext = new AccessibleJScrollPane();
  1221. }
  1222. return accessibleContext;
  1223. }
  1224. /**
  1225. * This class implements accessibility support for the
  1226. * <code>JScrollPane</code> class. It provides an implementation of the
  1227. * Java Accessibility API appropriate to scroll pane user-interface
  1228. * elements.
  1229. * <p>
  1230. * <strong>Warning:</strong>
  1231. * Serialized objects of this class will not be compatible with
  1232. * future Swing releases. The current serialization support is
  1233. * appropriate for short term storage or RMI between applications running
  1234. * the same version of Swing. As of 1.4, support for long term storage
  1235. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  1236. * has been added to the <code>java.beans</code> package.
  1237. * Please see {@link java.beans.XMLEncoder}.
  1238. */
  1239. protected class AccessibleJScrollPane extends AccessibleJComponent
  1240. implements ChangeListener {
  1241. protected JViewport viewPort = null;
  1242. public void resetViewPort() {
  1243. viewPort.removeChangeListener(this);
  1244. viewPort = JScrollPane.this.getViewport();
  1245. viewPort.addChangeListener(this);
  1246. }
  1247. /**
  1248. * Constructor to set up listener on viewport.
  1249. */
  1250. public AccessibleJScrollPane() {
  1251. super();
  1252. if (viewPort == null) {
  1253. viewPort = JScrollPane.this.getViewport();
  1254. }
  1255. viewPort.addChangeListener(this);
  1256. }
  1257. /**
  1258. * Get the role of this object.
  1259. *
  1260. * @return an instance of AccessibleRole describing the role of the
  1261. * object
  1262. * @see AccessibleRole
  1263. */
  1264. public AccessibleRole getAccessibleRole() {
  1265. return AccessibleRole.SCROLL_PANE;
  1266. }
  1267. /**
  1268. * Supports the change listener interface and fires property change
  1269. */
  1270. public void stateChanged(ChangeEvent e) {
  1271. AccessibleContext ac = ((Accessible)JScrollPane.this).getAccessibleContext();
  1272. if (ac != null) {
  1273. ac.firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, Boolean.valueOf(false), Boolean.valueOf(true));
  1274. }
  1275. }
  1276. }
  1277. }