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