1. /*
  2. * @(#)ScrollPane.java 1.89 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 java.awt;
  8. import java.awt.peer.LightweightPeer;
  9. import java.awt.peer.ScrollPanePeer;
  10. import java.awt.event.*;
  11. import javax.accessibility.*;
  12. import sun.awt.ScrollPaneWheelScroller;
  13. import java.io.Serializable;
  14. import java.io.ObjectInputStream;
  15. import java.io.ObjectOutputStream;
  16. import java.io.IOException;
  17. /**
  18. * A container class which implements automatic horizontal and/or
  19. * vertical scrolling for a single child component. The display
  20. * policy for the scrollbars can be set to:
  21. * <OL>
  22. * <LI>as needed: scrollbars created and shown only when needed by scrollpane
  23. * <LI>always: scrollbars created and always shown by the scrollpane
  24. * <LI>never: scrollbars never created or shown by the scrollpane
  25. * </OL>
  26. * <P>
  27. * The state of the horizontal and vertical scrollbars is represented
  28. * by two <code>ScrollPaneAdjustable</code> objects (one for each
  29. * dimension) which implement the <code>Adjustable</code> interface.
  30. * The API provides methods to access those objects such that the
  31. * attributes on the Adjustable object (such as unitIncrement, value,
  32. * etc.) can be manipulated.
  33. * <P>
  34. * Certain adjustable properties (minimum, maximum, blockIncrement,
  35. * and visibleAmount) are set internally by the scrollpane in accordance
  36. * with the geometry of the scrollpane and its child and these should
  37. * not be set by programs using the scrollpane.
  38. * <P>
  39. * If the scrollbar display policy is defined as "never", then the
  40. * scrollpane can still be programmatically scrolled using the
  41. * setScrollPosition() method and the scrollpane will move and clip
  42. * the child's contents appropriately. This policy is useful if the
  43. * program needs to create and manage its own adjustable controls.
  44. * <P>
  45. * The placement of the scrollbars is controlled by platform-specific
  46. * properties set by the user outside of the program.
  47. * <P>
  48. * The initial size of this container is set to 100x100, but can
  49. * be reset using setSize().
  50. * <P>
  51. * Scrolling with the wheel on a wheel-equipped mouse is enabled by default.
  52. * This can be disabled using setWheelScrollingEnabled(). Wheel scrolling can
  53. * be customized by setting the block and unit increment of the horizontal and
  54. * vertical Adjustables.
  55. * <P>
  56. * Insets are used to define any space used by scrollbars and any
  57. * borders created by the scroll pane. getInsets() can be used
  58. * to get the current value for the insets. If the value of
  59. * scrollbarsAlwaysVisible is false, then the value of the insets
  60. * will change dynamically depending on whether the scrollbars are
  61. * currently visible or not.
  62. *
  63. * @version 1.89 01/23/03
  64. * @author Tom Ball
  65. * @author Amy Fowler
  66. * @author Tim Prinzing
  67. */
  68. public class ScrollPane extends Container implements Accessible {
  69. /**
  70. * Initialize JNI field and method IDs
  71. */
  72. private static native void initIDs();
  73. static {
  74. /* ensure that the necessary native libraries are loaded */
  75. Toolkit.loadLibraries();
  76. if (!GraphicsEnvironment.isHeadless()) {
  77. initIDs();
  78. }
  79. }
  80. /**
  81. * Specifies that horizontal/vertical scrollbar should be shown
  82. * only when the size of the child exceeds the size of the scrollpane
  83. * in the horizontal/vertical dimension.
  84. */
  85. public static final int SCROLLBARS_AS_NEEDED = 0;
  86. /**
  87. * Specifies that horizontal/vertical scrollbars should always be
  88. * shown regardless of the respective sizes of the scrollpane and child.
  89. */
  90. public static final int SCROLLBARS_ALWAYS = 1;
  91. /**
  92. * Specifies that horizontal/vertical scrollbars should never be shown
  93. * regardless of the respective sizes of the scrollpane and child.
  94. */
  95. public static final int SCROLLBARS_NEVER = 2;
  96. /**
  97. * There are 3 ways in which a scroll bar can be displayed.
  98. * This integer will represent one of these 3 displays -
  99. * (SCROLLBARS_ALWAYS, SCROLLBARS_AS_NEEDED, SCROLLBARS_NEVER)
  100. *
  101. * @serial
  102. * @see #getScrollbarDisplayPolicy
  103. */
  104. private int scrollbarDisplayPolicy;
  105. /**
  106. * An adjustable vertical scrollbar.
  107. * It is important to note that you must <em>NOT</em> call 3
  108. * <code>Adjustable</code> methods, namely:
  109. * <code>setMinimum()</code>, <code>setMaximum()</code>,
  110. * <code>setVisibleAmount()</code>.
  111. *
  112. * @serial
  113. * @see #getVAdjustable
  114. */
  115. private ScrollPaneAdjustable vAdjustable;
  116. /**
  117. * An adjustable horizontal scrollbar.
  118. * It is important to note that you must <em>NOT</em> call 3
  119. * <code>Adjustable</code> methods, namely:
  120. * <code>setMinimum()</code>, <code>setMaximum()</code>,
  121. * <code>setVisibleAmount()</code>.
  122. *
  123. * @serial
  124. * @see #getHAdjustable
  125. */
  126. private ScrollPaneAdjustable hAdjustable;
  127. private static final String base = "scrollpane";
  128. private static int nameCounter = 0;
  129. private static final boolean defaultWheelScroll = true;
  130. /**
  131. * Indicates whether or not scrolling should take place when a
  132. * MouseWheelEvent is received.
  133. *
  134. * @serial
  135. * @since 1.4
  136. */
  137. private boolean wheelScrollingEnabled = defaultWheelScroll;
  138. /*
  139. * JDK 1.1 serialVersionUID
  140. */
  141. private static final long serialVersionUID = 7956609840827222915L;
  142. /**
  143. * Create a new scrollpane container with a scrollbar display
  144. * policy of "as needed".
  145. * @throws HeadlessException if GraphicsEnvironment.isHeadless()
  146. * returns true
  147. * @see java.awt.GraphicsEnvironment#isHeadless
  148. */
  149. public ScrollPane() throws HeadlessException {
  150. this(SCROLLBARS_AS_NEEDED);
  151. }
  152. /**
  153. * Create a new scrollpane container.
  154. * @param scrollbarDisplayPolicy policy for when scrollbars should be shown
  155. * @throws IllegalArgumentException if the specified scrollbar
  156. * display policy is invalid
  157. * @throws HeadlessException if GraphicsEnvironment.isHeadless()
  158. * returns true
  159. * @see java.awt.GraphicsEnvironment#isHeadless
  160. */
  161. public ScrollPane(int scrollbarDisplayPolicy) throws HeadlessException {
  162. GraphicsEnvironment.checkHeadless();
  163. this.layoutMgr = null;
  164. this.width = 100;
  165. this.height = 100;
  166. switch (scrollbarDisplayPolicy) {
  167. case SCROLLBARS_NEVER:
  168. case SCROLLBARS_AS_NEEDED:
  169. case SCROLLBARS_ALWAYS:
  170. this.scrollbarDisplayPolicy = scrollbarDisplayPolicy;
  171. break;
  172. default:
  173. throw new IllegalArgumentException("illegal scrollbar display policy");
  174. }
  175. vAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
  176. Adjustable.VERTICAL);
  177. hAdjustable = new ScrollPaneAdjustable(this, new PeerFixer(this),
  178. Adjustable.HORIZONTAL);
  179. setWheelScrollingEnabled(defaultWheelScroll);
  180. }
  181. /**
  182. * Construct a name for this component. Called by getName() when the
  183. * name is null.
  184. */
  185. String constructComponentName() {
  186. synchronized (getClass()) {
  187. return base + nameCounter++;
  188. }
  189. }
  190. /**
  191. * Adds the specified component to this scroll pane container.
  192. * If the scroll pane has an existing child component, that
  193. * component is removed and the new one is added.
  194. * @param comp the component to be added
  195. * @param constraints not applicable
  196. * @param index position of child component (must be <= 0)
  197. */
  198. protected final void addImpl(Component comp, Object constraints, int index) {
  199. synchronized (getTreeLock()) {
  200. if (getComponentCount() > 0) {
  201. remove(0);
  202. }
  203. if (index > 0) {
  204. throw new IllegalArgumentException("position greater than 0");
  205. }
  206. super.addImpl(comp, constraints, index);
  207. }
  208. }
  209. /**
  210. * Returns the display policy for the scrollbars.
  211. * @return the display policy for the scrollbars
  212. */
  213. public int getScrollbarDisplayPolicy() {
  214. return scrollbarDisplayPolicy;
  215. }
  216. /**
  217. * Returns the current size of the scroll pane's view port.
  218. * @return the size of the view port in pixels
  219. */
  220. public Dimension getViewportSize() {
  221. Insets i = getInsets();
  222. return new Dimension(width - i.right - i.left,
  223. height - i.top - i.bottom);
  224. }
  225. /**
  226. * Returns the height that would be occupied by a horizontal
  227. * scrollbar, which is independent of whether it is currently
  228. * displayed by the scroll pane or not.
  229. * @return the height of a horizontal scrollbar in pixels
  230. */
  231. public int getHScrollbarHeight() {
  232. int h = 0;
  233. if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
  234. ScrollPanePeer peer = (ScrollPanePeer)this.peer;
  235. if (peer != null) {
  236. h = peer.getHScrollbarHeight();
  237. }
  238. }
  239. return h;
  240. }
  241. /**
  242. * Returns the width that would be occupied by a vertical
  243. * scrollbar, which is independent of whether it is currently
  244. * displayed by the scroll pane or not.
  245. * @return the width of a vertical scrollbar in pixels
  246. */
  247. public int getVScrollbarWidth() {
  248. int w = 0;
  249. if (scrollbarDisplayPolicy != SCROLLBARS_NEVER) {
  250. ScrollPanePeer peer = (ScrollPanePeer)this.peer;
  251. if (peer != null) {
  252. w = peer.getVScrollbarWidth();
  253. }
  254. }
  255. return w;
  256. }
  257. /**
  258. * Returns the <code>ScrollPaneAdjustable</code> object which
  259. * represents the state of the vertical scrollbar.
  260. * The declared return type of this method is
  261. * <code>Adjustable</code> to maintain backward compatibility.
  262. * @see java.awt.ScrollPaneAdjustable
  263. */
  264. public Adjustable getVAdjustable() {
  265. return vAdjustable;
  266. }
  267. /**
  268. * Returns the <code>ScrollPaneAdjustable</code> object which
  269. * represents the state of the horizontal scrollbar.
  270. * The declared return type of this method is
  271. * <code>Adjustable</code> to maintain backward compatibility.
  272. * @see java.awt.ScrollPaneAdjustable
  273. */
  274. public Adjustable getHAdjustable() {
  275. return hAdjustable;
  276. }
  277. /**
  278. * Scrolls to the specified position within the child component.
  279. * A call to this method is only valid if the scroll pane contains
  280. * a child. Specifying a position outside of the legal scrolling bounds
  281. * of the child will scroll to the closest legal position.
  282. * Legal bounds are defined to be the rectangle:
  283. * x = 0, y = 0, width = (child width - view port width),
  284. * height = (child height - view port height).
  285. * This is a convenience method which interfaces with the Adjustable
  286. * objects which represent the state of the scrollbars.
  287. * @param x the x position to scroll to
  288. * @param y the y position to scroll to
  289. * @throws NullPointerException if the scrollpane does not contain
  290. * a child
  291. */
  292. public void setScrollPosition(int x, int y) {
  293. synchronized (getTreeLock()) {
  294. if (ncomponents <= 0) {
  295. throw new NullPointerException("child is null");
  296. }
  297. hAdjustable.setValue(x);
  298. vAdjustable.setValue(y);
  299. }
  300. }
  301. /**
  302. * Scrolls to the specified position within the child component.
  303. * A call to this method is only valid if the scroll pane contains
  304. * a child and the specified position is within legal scrolling bounds
  305. * of the child. Specifying a position outside of the legal scrolling
  306. * bounds of the child will scroll to the closest legal position.
  307. * Legal bounds are defined to be the rectangle:
  308. * x = 0, y = 0, width = (child width - view port width),
  309. * height = (child height - view port height).
  310. * This is a convenience method which interfaces with the Adjustable
  311. * objects which represent the state of the scrollbars.
  312. * @param p the Point representing the position to scroll to
  313. */
  314. public void setScrollPosition(Point p) {
  315. setScrollPosition(p.x, p.y);
  316. }
  317. /**
  318. * Returns the current x,y position within the child which is displayed
  319. * at the 0,0 location of the scrolled panel's view port.
  320. * This is a convenience method which interfaces with the adjustable
  321. * objects which represent the state of the scrollbars.
  322. * @return the coordinate position for the current scroll position
  323. * @throws NullPointerException if the scrollpane does not contain
  324. * a child
  325. */
  326. public Point getScrollPosition() {
  327. if (ncomponents <= 0) {
  328. throw new NullPointerException("child is null");
  329. }
  330. return new Point(hAdjustable.getValue(), vAdjustable.getValue());
  331. }
  332. /**
  333. * Sets the layout manager for this container. This method is
  334. * overridden to prevent the layout mgr from being set.
  335. * @param mgr the specified layout manager
  336. */
  337. public final void setLayout(LayoutManager mgr) {
  338. throw new AWTError("ScrollPane controls layout");
  339. }
  340. /**
  341. * Lays out this container by resizing its child to its preferred size.
  342. * If the new preferred size of the child causes the current scroll
  343. * position to be invalid, the scroll position is set to the closest
  344. * valid position.
  345. *
  346. * @see Component#validate
  347. */
  348. public void doLayout() {
  349. layout();
  350. }
  351. /**
  352. * Determine the size to allocate the child component.
  353. * If the viewport area is bigger than the childs
  354. * preferred size then the child is allocated enough
  355. * to fill the viewport, otherwise the child is given
  356. * it's preferred size.
  357. */
  358. Dimension calculateChildSize() {
  359. //
  360. // calculate the view size, accounting for border but not scrollbars
  361. // - don't use right/bottom insets since they vary depending
  362. // on whether or not scrollbars were displayed on last resize
  363. //
  364. Dimension size = getSize();
  365. Insets insets = getInsets();
  366. int viewWidth = size.width - insets.left*2;
  367. int viewHeight = size.height - insets.top*2;
  368. //
  369. // determine whether or not horz or vert scrollbars will be displayed
  370. //
  371. boolean vbarOn;
  372. boolean hbarOn;
  373. Component child = getComponent(0);
  374. Dimension childSize = new Dimension(child.getPreferredSize());
  375. if (scrollbarDisplayPolicy == SCROLLBARS_AS_NEEDED) {
  376. vbarOn = childSize.height > viewHeight;
  377. hbarOn = childSize.width > viewWidth;
  378. } else if (scrollbarDisplayPolicy == SCROLLBARS_ALWAYS) {
  379. vbarOn = hbarOn = true;
  380. } else { // SCROLLBARS_NEVER
  381. vbarOn = hbarOn = false;
  382. }
  383. //
  384. // adjust predicted view size to account for scrollbars
  385. //
  386. int vbarWidth = getVScrollbarWidth();
  387. int hbarHeight = getHScrollbarHeight();
  388. if (vbarOn) {
  389. viewWidth -= vbarWidth;
  390. }
  391. if(hbarOn) {
  392. viewHeight -= hbarHeight;
  393. }
  394. //
  395. // if child is smaller than view, size it up
  396. //
  397. if (childSize.width < viewWidth) {
  398. childSize.width = viewWidth;
  399. }
  400. if (childSize.height < viewHeight) {
  401. childSize.height = viewHeight;
  402. }
  403. return childSize;
  404. }
  405. /**
  406. * @deprecated As of JDK version 1.1,
  407. * replaced by <code>doLayout()</code>.
  408. */
  409. public void layout() {
  410. if (ncomponents > 0) {
  411. Component c = getComponent(0);
  412. Point p = getScrollPosition();
  413. Dimension cs = calculateChildSize();
  414. Dimension vs = getViewportSize();
  415. Insets i = getInsets();
  416. c.reshape(i.left - p.x, i.top - p.y, cs.width, cs.height);
  417. ScrollPanePeer peer = (ScrollPanePeer)this.peer;
  418. if (peer != null) {
  419. peer.childResized(cs.width, cs.height);
  420. }
  421. // update adjustables... the viewport size may have changed
  422. // with the scrollbars coming or going so the viewport size
  423. // is updated before the adjustables.
  424. vs = getViewportSize();
  425. hAdjustable.setSpan(0, cs.width, vs.width);
  426. vAdjustable.setSpan(0, cs.height, vs.height);
  427. }
  428. }
  429. /**
  430. * Prints the component in this scroll pane.
  431. * @param g the specified Graphics window
  432. * @see Component#print
  433. * @see Component#printAll
  434. */
  435. public void printComponents(Graphics g) {
  436. if (ncomponents > 0) {
  437. Component c = component[0];
  438. Point p = c.getLocation();
  439. Dimension vs = getViewportSize();
  440. Insets i = getInsets();
  441. Graphics cg = g.create();
  442. try {
  443. cg.clipRect(i.left, i.top, vs.width, vs.height);
  444. cg.translate(p.x, p.y);
  445. c.printAll(cg);
  446. } finally {
  447. cg.dispose();
  448. }
  449. }
  450. }
  451. /**
  452. * Creates the scroll pane's peer.
  453. */
  454. public void addNotify() {
  455. synchronized (getTreeLock()) {
  456. int vAdjustableValue = 0;
  457. int hAdjustableValue = 0;
  458. // Bug 4124460. Save the current adjustable values,
  459. // so they can be restored after addnotify. Set the
  460. // adjustables to 0, to prevent crashes for possible
  461. // negative values.
  462. if (getComponentCount() > 0) {
  463. vAdjustableValue = vAdjustable.getValue();
  464. hAdjustableValue = hAdjustable.getValue();
  465. vAdjustable.setValue(0);
  466. hAdjustable.setValue(0);
  467. }
  468. if (peer == null)
  469. peer = getToolkit().createScrollPane(this);
  470. super.addNotify();
  471. // Bug 4124460. Restore the adjustable values.
  472. if (getComponentCount() > 0) {
  473. vAdjustable.setValue(vAdjustableValue);
  474. hAdjustable.setValue(hAdjustableValue);
  475. }
  476. if (getComponentCount() > 0) {
  477. Component comp = getComponent(0);
  478. if (comp.peer instanceof LightweightPeer) {
  479. // The scrollpane won't work with a windowless child... it assumes
  480. // it is moving a child window around so the windowless child is
  481. // wrapped with a window.
  482. remove(0);
  483. Panel child = new Panel();
  484. child.setLayout(new BorderLayout());
  485. child.add(comp);
  486. add(child);
  487. }
  488. }
  489. }
  490. }
  491. /**
  492. * Returns a string representing the state of this
  493. * <code>ScrollPane</code>. This
  494. * method is intended to be used only for debugging purposes, and the
  495. * content and format of the returned string may vary between
  496. * implementations. The returned string may be empty but may not be
  497. * <code>null</code>.
  498. *
  499. * @return the parameter string of this scroll pane
  500. */
  501. public String paramString() {
  502. String sdpStr;
  503. switch (scrollbarDisplayPolicy) {
  504. case SCROLLBARS_AS_NEEDED:
  505. sdpStr = "as-needed";
  506. break;
  507. case SCROLLBARS_ALWAYS:
  508. sdpStr = "always";
  509. break;
  510. case SCROLLBARS_NEVER:
  511. sdpStr = "never";
  512. break;
  513. default:
  514. sdpStr = "invalid display policy";
  515. }
  516. Point p = ncomponents > 0? getScrollPosition() : new Point(0,0);
  517. Insets i = getInsets();
  518. return super.paramString()+",ScrollPosition=("+p.x+","+p.y+")"+
  519. ",Insets=("+i.top+","+i.left+","+i.bottom+","+i.right+")"+
  520. ",ScrollbarDisplayPolicy="+sdpStr+
  521. ",wheelScrollingEnabled="+isWheelScrollingEnabled();
  522. }
  523. void autoProcessMouseWheel(MouseWheelEvent e) {
  524. processMouseWheelEvent(e);
  525. }
  526. /**
  527. * Process mouse wheel events that are delivered to this
  528. * <code>ScrollPane</code> by scrolling an appropriate amount.
  529. * <p>Note that if the event parameter is <code>null</code>
  530. * the behavior is unspecified and may result in an
  531. * exception.
  532. *
  533. * @param e the mouse wheel event
  534. * @since 1.4
  535. */
  536. protected void processMouseWheelEvent(MouseWheelEvent e) {
  537. if (isWheelScrollingEnabled()) {
  538. ScrollPaneWheelScroller.handleWheelScrolling(this, e);
  539. e.consume();
  540. }
  541. super.processMouseWheelEvent(e);
  542. }
  543. /**
  544. * If wheel scrolling is enabled, we return true for MouseWheelEvents
  545. * @since 1.4
  546. */
  547. protected boolean eventTypeEnabled(int type) {
  548. if (type == MouseEvent.MOUSE_WHEEL && isWheelScrollingEnabled()) {
  549. return true;
  550. }
  551. else {
  552. return super.eventTypeEnabled(type);
  553. }
  554. }
  555. /**
  556. * Enables/disables scrolling in response to movement of the mouse wheel.
  557. * Wheel scrolling is enabled by default.
  558. *
  559. * @param handleWheel <code>true</code> if scrolling should be done
  560. * automatically for a MouseWheelEvent,
  561. * <code>false</code> otherwise.
  562. * @see #isWheelScrollingEnabled
  563. * @see java.awt.event.MouseWheelEvent
  564. * @see java.awt.event.MouseWheelListener
  565. * @since 1.4
  566. */
  567. public void setWheelScrollingEnabled(boolean handleWheel) {
  568. wheelScrollingEnabled = handleWheel;
  569. }
  570. /**
  571. * Indicates whether or not scrolling will take place in response to
  572. * the mouse wheel. Wheel scrolling is enabled by default.
  573. *
  574. * @see #setWheelScrollingEnabled(boolean)
  575. * @since 1.4
  576. */
  577. public boolean isWheelScrollingEnabled() {
  578. return wheelScrollingEnabled;
  579. }
  580. /**
  581. * Writes default serializable fields to stream.
  582. */
  583. private void writeObject(ObjectOutputStream s) throws IOException {
  584. // 4352819: We only need this degenerate writeObject to make
  585. // it safe for future versions of this class to write optional
  586. // data to the stream.
  587. s.defaultWriteObject();
  588. }
  589. /**
  590. * Reads default serializable fields to stream.
  591. * @exception HeadlessException if
  592. * <code>GraphicsEnvironment.isHeadless()</code> returns
  593. * <code>true</code>
  594. * @see java.awt.GraphicsEnvironment#isHeadless
  595. */
  596. private void readObject(ObjectInputStream s)
  597. throws ClassNotFoundException, IOException, HeadlessException
  598. {
  599. GraphicsEnvironment.checkHeadless();
  600. // 4352819: Gotcha! Cannot use s.defaultReadObject here and
  601. // then continue with reading optional data. Use GetField instead.
  602. ObjectInputStream.GetField f = s.readFields();
  603. // Old fields
  604. scrollbarDisplayPolicy = f.get("scrollbarDisplayPolicy",
  605. SCROLLBARS_AS_NEEDED);
  606. hAdjustable = (ScrollPaneAdjustable)f.get("hAdjustable", null);
  607. vAdjustable = (ScrollPaneAdjustable)f.get("vAdjustable", null);
  608. // Since 1.4
  609. wheelScrollingEnabled = f.get("wheelScrollingEnabled",
  610. defaultWheelScroll);
  611. // // Note to future maintainers
  612. // if (f.defaulted("wheelScrollingEnabled")) {
  613. // // We are reading pre-1.4 stream that doesn't have
  614. // // optional data, not even the TC_ENDBLOCKDATA marker.
  615. // // Reading anything after this point is unsafe as we will
  616. // // read unrelated objects further down the stream (4352819).
  617. // }
  618. // else {
  619. // // Reading data from 1.4 or later, it's ok to try to read
  620. // // optional data as OptionalDataException with eof == true
  621. // // will be correctly reported
  622. // }
  623. }
  624. class PeerFixer implements AdjustmentListener, java.io.Serializable {
  625. PeerFixer(ScrollPane scroller) {
  626. this.scroller = scroller;
  627. }
  628. /**
  629. * Invoked when the value of the adjustable has changed.
  630. */
  631. public void adjustmentValueChanged(AdjustmentEvent e) {
  632. Adjustable adj = e.getAdjustable();
  633. int value = e.getValue();
  634. ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
  635. if (peer != null) {
  636. peer.setValue(adj, value);
  637. }
  638. Component c = scroller.getComponent(0);
  639. switch(adj.getOrientation()) {
  640. case Adjustable.VERTICAL:
  641. c.move(c.getLocation().x, -(value));
  642. break;
  643. case Adjustable.HORIZONTAL:
  644. c.move(-(value), c.getLocation().y);
  645. break;
  646. default:
  647. throw new IllegalArgumentException("Illegal adjustable orientation");
  648. }
  649. }
  650. private ScrollPane scroller;
  651. }
  652. /////////////////
  653. // Accessibility support
  654. ////////////////
  655. /**
  656. * Gets the AccessibleContext associated with this ScrollPane.
  657. * For scroll panes, the AccessibleContext takes the form of an
  658. * AccessibleAWTScrollPane.
  659. * A new AccessibleAWTScrollPane instance is created if necessary.
  660. *
  661. * @return an AccessibleAWTScrollPane that serves as the
  662. * AccessibleContext of this ScrollPane
  663. */
  664. public AccessibleContext getAccessibleContext() {
  665. if (accessibleContext == null) {
  666. accessibleContext = new AccessibleAWTScrollPane();
  667. }
  668. return accessibleContext;
  669. }
  670. /**
  671. * This class implements accessibility support for the
  672. * <code>ScrollPane</code> class. It provides an implementation of the
  673. * Java Accessibility API appropriate to scroll pane user-interface
  674. * elements.
  675. */
  676. protected class AccessibleAWTScrollPane extends AccessibleAWTContainer {
  677. /**
  678. * Get the role of this object.
  679. *
  680. * @return an instance of AccessibleRole describing the role of the
  681. * object
  682. * @see AccessibleRole
  683. */
  684. public AccessibleRole getAccessibleRole() {
  685. return AccessibleRole.SCROLL_PANE;
  686. }
  687. } // class AccessibleAWTScrollPane
  688. }
  689. /*
  690. * In JDK 1.1.1, the pkg private class java.awt.PeerFixer was moved to
  691. * become an inner class of ScrollPane, which broke serialization
  692. * for ScrollPane objects using JDK 1.1.
  693. * Instead of moving it back out here, which would break all JDK 1.1.x
  694. * releases, we keep PeerFixer in both places. Because of the scoping rules,
  695. * the PeerFixer that is used in ScrollPane will be the one that is the
  696. * inner class. This pkg private PeerFixer class below will only be used
  697. * if the Java 2 platform is used to deserialize ScrollPane objects that were serialized
  698. * using JDK1.1
  699. */
  700. class PeerFixer implements AdjustmentListener, java.io.Serializable {
  701. PeerFixer(ScrollPane scroller) {
  702. this.scroller = scroller;
  703. }
  704. /**
  705. * Invoked when the value of the adjustable has changed.
  706. */
  707. public void adjustmentValueChanged(AdjustmentEvent e) {
  708. Adjustable adj = e.getAdjustable();
  709. int value = e.getValue();
  710. ScrollPanePeer peer = (ScrollPanePeer) scroller.peer;
  711. if (peer != null) {
  712. peer.setValue(adj, value);
  713. }
  714. Component c = scroller.getComponent(0);
  715. switch(adj.getOrientation()) {
  716. case Adjustable.VERTICAL:
  717. c.move(c.getLocation().x, -(value));
  718. break;
  719. case Adjustable.HORIZONTAL:
  720. c.move(-(value), c.getLocation().y);
  721. break;
  722. default:
  723. throw new IllegalArgumentException("Illegal adjustable orientation");
  724. }
  725. }
  726. private ScrollPane scroller;
  727. }