/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.awt;
import java.awt.peer.
LightweightPeer;
import java.awt.peer.
ScrollPanePeer;
import java.awt.event.*;
import javax.accessibility.*;
import sun.awt.
ScrollPaneWheelScroller;
import sun.awt.
SunToolkit;
import java.beans.
ConstructorProperties;
import java.beans.
Transient;
import java.io.
ObjectInputStream;
import java.io.
ObjectOutputStream;
import java.io.
IOException;
/**
* A container class which implements automatic horizontal and/or
* vertical scrolling for a single child component. The display
* policy for the scrollbars can be set to:
* <OL>
* <LI>as needed: scrollbars created and shown only when needed by scrollpane
* <LI>always: scrollbars created and always shown by the scrollpane
* <LI>never: scrollbars never created or shown by the scrollpane
* </OL>
* <P>
* The state of the horizontal and vertical scrollbars is represented
* by two <code>ScrollPaneAdjustable</code> objects (one for each
* dimension) which implement the <code>Adjustable</code> interface.
* The API provides methods to access those objects such that the
* attributes on the Adjustable object (such as unitIncrement, value,
* etc.) can be manipulated.
* <P>
* Certain adjustable properties (minimum, maximum, blockIncrement,
* and visibleAmount) are set internally by the scrollpane in accordance
* with the geometry of the scrollpane and its child and these should
* not be set by programs using the scrollpane.
* <P>
* If the scrollbar display policy is defined as "never", then the
* scrollpane can still be programmatically scrolled using the
* setScrollPosition() method and the scrollpane will move and clip
* the child's contents appropriately. This policy is useful if the
* program needs to create and manage its own adjustable controls.
* <P>
* The placement of the scrollbars is controlled by platform-specific
* properties set by the user outside of the program.
* <P>
* The initial size of this container is set to 100x100, but can
* be reset using setSize().
* <P>
* Scrolling with the wheel on a wheel-equipped mouse is enabled by default.
* This can be disabled using <code>setWheelScrollingEnabled</code>.
* Wheel scrolling can be customized by setting the block and
* unit increment of the horizontal and vertical Adjustables.
* For information on how mouse wheel events are dispatched, see
* the class description for {@link MouseWheelEvent}.
* <P>
* Insets are used to define any space used by scrollbars and any
* borders created by the scroll pane. getInsets() can be used
* to get the current value for the insets. If the value of
* scrollbarsAlwaysVisible is false, then the value of the insets
* will change dynamically depending on whether the scrollbars are
* currently visible or not.
*
* @author Tom Ball
* @author Amy Fowler
* @author Tim Prinzing
*/
public class
ScrollPane extends
Container implements
Accessible {
/**
* Initialize JNI field and method IDs
*/
private static native void
initIDs();
static {
/* ensure that the necessary native libraries are loaded */
Toolkit.
loadLibraries();
if (!
GraphicsEnvironment.
isHeadless()) {
initIDs();
}
}
/**
* Specifies that horizontal/vertical scrollbar should be shown
* only when the size of the child exceeds the size of the scrollpane
* in the horizontal/vertical dimension.
*/
public static final int
SCROLLBARS_AS_NEEDED = 0;
/**
* Specifies that horizontal/vertical scrollbars should always be
* shown regardless of the respective sizes of the scrollpane and child.
*/
public static final int
SCROLLBARS_ALWAYS = 1;
/**
* Specifies that horizontal/vertical scrollbars should never be shown
* regardless of the respective sizes of the scrollpane and child.
*/
public static final int
SCROLLBARS_NEVER = 2;
/**
* There are 3 ways in which a scroll bar can be displayed.
* This integer will represent one of these 3 displays -
* (SCROLLBARS_ALWAYS, SCROLLBARS_AS_NEEDED, SCROLLBARS_NEVER)
*
* @serial
* @see #getScrollbarDisplayPolicy
*/
private int
scrollbarDisplayPolicy;
/**
* An adjustable vertical scrollbar.
* It is important to note that you must <em>NOT</em> call 3
* <code>Adjustable</code> methods, namely:
* <code>setMinimum()</code>, <code>setMaximum()</code>,
* <code>setVisibleAmount()</code>.
*
* @serial
* @see #getVAdjustable
*/
private
ScrollPaneAdjustable vAdjustable;
/**
* An adjustable horizontal scrollbar.
* It is important to note that you must <em>NOT</em> call 3
* <code>Adjustable</code> methods, namely:
* <code>setMinimum()</code>, <code>setMaximum()</code>,
* <code>setVisibleAmount()</code>.
*
* @serial
* @see #getHAdjustable
*/
private
ScrollPaneAdjustable hAdjustable;
private static final
String base = "scrollpane";
private static int
nameCounter = 0;
private static final boolean
defaultWheelScroll = true;
/**
* Indicates whether or not scrolling should take place when a
* MouseWheelEvent is received.
*
* @serial
* @since 1.4
*/
private boolean
wheelScrollingEnabled =
defaultWheelScroll;
/*
* JDK 1.1 serialVersionUID
*/
private static final long
serialVersionUID = 7956609840827222915L;
/**
* Create a new scrollpane container with a scrollbar display
* policy of "as needed".
* @throws HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public
ScrollPane() throws
HeadlessException {
this(
SCROLLBARS_AS_NEEDED);
}
/**
* Create a new scrollpane container.
* @param scrollbarDisplayPolicy policy for when scrollbars should be shown
* @throws IllegalArgumentException if the specified scrollbar
* display policy is invalid
* @throws HeadlessException if GraphicsEnvironment.isHeadless()
* returns true
* @see java.awt.GraphicsEnvironment#isHeadless
*/
@
ConstructorProperties({"scrollbarDisplayPolicy"})
public
ScrollPane(int
scrollbarDisplayPolicy) throws
HeadlessException {
GraphicsEnvironment.
checkHeadless();
this.
layoutMgr = null;
this.
width = 100;
this.
height = 100;
switch (
scrollbarDisplayPolicy) {
case
SCROLLBARS_NEVER:
case
SCROLLBARS_AS_NEEDED:
case
SCROLLBARS_ALWAYS:
this.
scrollbarDisplayPolicy =
scrollbarDisplayPolicy;
break;
default:
throw new
IllegalArgumentException("illegal scrollbar display policy");
}
vAdjustable = new
ScrollPaneAdjustable(this, new
PeerFixer(this),
Adjustable.
VERTICAL);
hAdjustable = new
ScrollPaneAdjustable(this, new
PeerFixer(this),
Adjustable.
HORIZONTAL);
setWheelScrollingEnabled(
defaultWheelScroll);
}
/**
* Construct a name for this component. Called by getName() when the
* name is null.
*/
String constructComponentName() {
synchronized (
ScrollPane.class) {
return
base +
nameCounter++;
}
}
// The scrollpane won't work with a windowless child... it assumes
// it is moving a child window around so the windowless child is
// wrapped with a window.
private void
addToPanel(
Component comp,
Object constraints, int
index) {
Panel child = new
Panel();
child.
setLayout(new
BorderLayout());
child.
add(
comp);
super.addImpl(
child,
constraints,
index);
validate();
}
/**
* Adds the specified component to this scroll pane container.
* If the scroll pane has an existing child component, that
* component is removed and the new one is added.
* @param comp the component to be added
* @param constraints not applicable
* @param index position of child component (must be <= 0)
*/
protected final void
addImpl(
Component comp,
Object constraints, int
index) {
synchronized (
getTreeLock()) {
if (
getComponentCount() > 0) {
remove(0);
}
if (
index > 0) {
throw new
IllegalArgumentException("position greater than 0");
}
if (!
SunToolkit.
isLightweightOrUnknown(
comp)) {
super.addImpl(
comp,
constraints,
index);
} else {
addToPanel(
comp,
constraints,
index);
}
}
}
/**
* Returns the display policy for the scrollbars.
* @return the display policy for the scrollbars
*/
public int
getScrollbarDisplayPolicy() {
return
scrollbarDisplayPolicy;
}
/**
* Returns the current size of the scroll pane's view port.
* @return the size of the view port in pixels
*/
public
Dimension getViewportSize() {
Insets i =
getInsets();
return new
Dimension(
width -
i.
right -
i.
left,
height -
i.
top -
i.
bottom);
}
/**
* Returns the height that would be occupied by a horizontal
* scrollbar, which is independent of whether it is currently
* displayed by the scroll pane or not.
* @return the height of a horizontal scrollbar in pixels
*/
public int
getHScrollbarHeight() {
int
h = 0;
if (
scrollbarDisplayPolicy !=
SCROLLBARS_NEVER) {
ScrollPanePeer peer = (
ScrollPanePeer)this.
peer;
if (
peer != null) {
h =
peer.
getHScrollbarHeight();
}
}
return
h;
}
/**
* Returns the width that would be occupied by a vertical
* scrollbar, which is independent of whether it is currently
* displayed by the scroll pane or not.
* @return the width of a vertical scrollbar in pixels
*/
public int
getVScrollbarWidth() {
int
w = 0;
if (
scrollbarDisplayPolicy !=
SCROLLBARS_NEVER) {
ScrollPanePeer peer = (
ScrollPanePeer)this.
peer;
if (
peer != null) {
w =
peer.
getVScrollbarWidth();
}
}
return
w;
}
/**
* Returns the <code>ScrollPaneAdjustable</code> object which
* represents the state of the vertical scrollbar.
* The declared return type of this method is
* <code>Adjustable</code> to maintain backward compatibility.
* @see java.awt.ScrollPaneAdjustable
*/
public
Adjustable getVAdjustable() {
return
vAdjustable;
}
/**
* Returns the <code>ScrollPaneAdjustable</code> object which
* represents the state of the horizontal scrollbar.
* The declared return type of this method is
* <code>Adjustable</code> to maintain backward compatibility.
* @see java.awt.ScrollPaneAdjustable
*/
public
Adjustable getHAdjustable() {
return
hAdjustable;
}
/**
* Scrolls to the specified position within the child component.
* A call to this method is only valid if the scroll pane contains
* a child. Specifying a position outside of the legal scrolling bounds
* of the child will scroll to the closest legal position.
* Legal bounds are defined to be the rectangle:
* x = 0, y = 0, width = (child width - view port width),
* height = (child height - view port height).
* This is a convenience method which interfaces with the Adjustable
* objects which represent the state of the scrollbars.
* @param x the x position to scroll to
* @param y the y position to scroll to
* @throws NullPointerException if the scrollpane does not contain
* a child
*/
public void
setScrollPosition(int
x, int
y) {
synchronized (
getTreeLock()) {
if (
getComponentCount()==0) {
throw new
NullPointerException("child is null");
}
hAdjustable.
setValue(
x);
vAdjustable.
setValue(
y);
}
}
/**
* Scrolls to the specified position within the child component.
* A call to this method is only valid if the scroll pane contains
* a child and the specified position is within legal scrolling bounds
* of the child. Specifying a position outside of the legal scrolling
* bounds of the child will scroll to the closest legal position.
* Legal bounds are defined to be the rectangle:
* x = 0, y = 0, width = (child width - view port width),
* height = (child height - view port height).
* This is a convenience method which interfaces with the Adjustable
* objects which represent the state of the scrollbars.
* @param p the Point representing the position to scroll to
* @throws NullPointerException if {@code p} is {@code null}
*/
public void
setScrollPosition(
Point p) {
setScrollPosition(
p.
x,
p.
y);
}
/**
* Returns the current x,y position within the child which is displayed
* at the 0,0 location of the scrolled panel's view port.
* This is a convenience method which interfaces with the adjustable
* objects which represent the state of the scrollbars.
* @return the coordinate position for the current scroll position
* @throws NullPointerException if the scrollpane does not contain
* a child
*/
@
Transient
public
Point getScrollPosition() {
synchronized (
getTreeLock()) {
if (
getComponentCount()==0) {
throw new
NullPointerException("child is null");
}
return new
Point(
hAdjustable.
getValue(),
vAdjustable.
getValue());
}
}
/**
* Sets the layout manager for this container. This method is
* overridden to prevent the layout mgr from being set.
* @param mgr the specified layout manager
*/
public final void
setLayout(
LayoutManager mgr) {
throw new
AWTError("ScrollPane controls layout");
}
/**
* Lays out this container by resizing its child to its preferred size.
* If the new preferred size of the child causes the current scroll
* position to be invalid, the scroll position is set to the closest
* valid position.
*
* @see Component#validate
*/
public void
doLayout() {
layout();
}
/**
* Determine the size to allocate the child component.
* If the viewport area is bigger than the preferred size
* of the child then the child is allocated enough
* to fill the viewport, otherwise the child is given
* it's preferred size.
*/
Dimension calculateChildSize() {
//
// calculate the view size, accounting for border but not scrollbars
// - don't use right/bottom insets since they vary depending
// on whether or not scrollbars were displayed on last resize
//
Dimension size =
getSize();
Insets insets =
getInsets();
int
viewWidth =
size.
width -
insets.
left*2;
int
viewHeight =
size.
height -
insets.
top*2;
//
// determine whether or not horz or vert scrollbars will be displayed
//
boolean
vbarOn;
boolean
hbarOn;
Component child =
getComponent(0);
Dimension childSize = new
Dimension(
child.
getPreferredSize());
if (
scrollbarDisplayPolicy ==
SCROLLBARS_AS_NEEDED) {
vbarOn =
childSize.
height >
viewHeight;
hbarOn =
childSize.
width >
viewWidth;
} else if (
scrollbarDisplayPolicy ==
SCROLLBARS_ALWAYS) {
vbarOn =
hbarOn = true;
} else { // SCROLLBARS_NEVER
vbarOn =
hbarOn = false;
}
//
// adjust predicted view size to account for scrollbars
//
int
vbarWidth =
getVScrollbarWidth();
int
hbarHeight =
getHScrollbarHeight();
if (
vbarOn) {
viewWidth -=
vbarWidth;
}
if(
hbarOn) {
viewHeight -=
hbarHeight;
}
//
// if child is smaller than view, size it up
//
if (
childSize.
width <
viewWidth) {
childSize.
width =
viewWidth;
}
if (
childSize.
height <
viewHeight) {
childSize.
height =
viewHeight;
}
return
childSize;
}
/**
* @deprecated As of JDK version 1.1,
* replaced by <code>doLayout()</code>.
*/
@
Deprecated
public void
layout() {
if (
getComponentCount()==0) {
return;
}
Component c =
getComponent(0);
Point p =
getScrollPosition();
Dimension cs =
calculateChildSize();
Dimension vs =
getViewportSize();
c.
reshape(-
p.
x, -
p.
y,
cs.
width,
cs.
height);
ScrollPanePeer peer = (
ScrollPanePeer)this.
peer;
if (
peer != null) {
peer.
childResized(
cs.
width,
cs.
height);
}
// update adjustables... the viewport size may have changed
// with the scrollbars coming or going so the viewport size
// is updated before the adjustables.
vs =
getViewportSize();
hAdjustable.
setSpan(0,
cs.
width,
vs.
width);
vAdjustable.
setSpan(0,
cs.
height,
vs.
height);
}
/**
* Prints the component in this scroll pane.
* @param g the specified Graphics window
* @see Component#print
* @see Component#printAll
*/
public void
printComponents(
Graphics g) {
if (
getComponentCount()==0) {
return;
}
Component c =
getComponent(0);
Point p =
c.
getLocation();
Dimension vs =
getViewportSize();
Insets i =
getInsets();
Graphics cg =
g.
create();
try {
cg.
clipRect(
i.
left,
i.
top,
vs.
width,
vs.
height);
cg.
translate(
p.
x,
p.
y);
c.
printAll(
cg);
} finally {
cg.
dispose();
}
}
/**
* Creates the scroll pane's peer.
*/
public void
addNotify() {
synchronized (
getTreeLock()) {
int
vAdjustableValue = 0;
int
hAdjustableValue = 0;
// Bug 4124460. Save the current adjustable values,
// so they can be restored after addnotify. Set the
// adjustables to 0, to prevent crashes for possible
// negative values.
if (
getComponentCount() > 0) {
vAdjustableValue =
vAdjustable.
getValue();
hAdjustableValue =
hAdjustable.
getValue();
vAdjustable.
setValue(0);
hAdjustable.
setValue(0);
}
if (
peer == null)
peer =
getToolkit().
createScrollPane(this);
super.addNotify();
// Bug 4124460. Restore the adjustable values.
if (
getComponentCount() > 0) {
vAdjustable.
setValue(
vAdjustableValue);
hAdjustable.
setValue(
hAdjustableValue);
}
}
}
/**
* Returns a string representing the state of this
* <code>ScrollPane</code>. This
* method is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not be
* <code>null</code>.
*
* @return the parameter string of this scroll pane
*/
public
String paramString() {
String sdpStr;
switch (
scrollbarDisplayPolicy) {
case
SCROLLBARS_AS_NEEDED:
sdpStr = "as-needed";
break;
case
SCROLLBARS_ALWAYS:
sdpStr = "always";
break;
case
SCROLLBARS_NEVER:
sdpStr = "never";
break;
default:
sdpStr = "invalid display policy";
}
Point p = (
getComponentCount()>0)?
getScrollPosition() : new
Point(0,0);
Insets i =
getInsets();
return super.paramString()+",ScrollPosition=("+
p.
x+","+
p.
y+")"+
",Insets=("+
i.
top+","+
i.
left+","+
i.
bottom+","+
i.
right+")"+
",ScrollbarDisplayPolicy="+
sdpStr+
",wheelScrollingEnabled="+
isWheelScrollingEnabled();
}
void
autoProcessMouseWheel(
MouseWheelEvent e) {
processMouseWheelEvent(
e);
}
/**
* Process mouse wheel events that are delivered to this
* <code>ScrollPane</code> by scrolling an appropriate amount.
* <p>Note that if the event parameter is <code>null</code>
* the behavior is unspecified and may result in an
* exception.
*
* @param e the mouse wheel event
* @since 1.4
*/
protected void
processMouseWheelEvent(
MouseWheelEvent e) {
if (
isWheelScrollingEnabled()) {
ScrollPaneWheelScroller.
handleWheelScrolling(this,
e);
e.
consume();
}
super.processMouseWheelEvent(
e);
}
/**
* If wheel scrolling is enabled, we return true for MouseWheelEvents
* @since 1.4
*/
protected boolean
eventTypeEnabled(int
type) {
if (
type ==
MouseEvent.
MOUSE_WHEEL &&
isWheelScrollingEnabled()) {
return true;
}
else {
return super.eventTypeEnabled(
type);
}
}
/**
* Enables/disables scrolling in response to movement of the mouse wheel.
* Wheel scrolling is enabled by default.
*
* @param handleWheel <code>true</code> if scrolling should be done
* automatically for a MouseWheelEvent,
* <code>false</code> otherwise.
* @see #isWheelScrollingEnabled
* @see java.awt.event.MouseWheelEvent
* @see java.awt.event.MouseWheelListener
* @since 1.4
*/
public void
setWheelScrollingEnabled(boolean
handleWheel) {
wheelScrollingEnabled =
handleWheel;
}
/**
* Indicates whether or not scrolling will take place in response to
* the mouse wheel. Wheel scrolling is enabled by default.
*
* @see #setWheelScrollingEnabled(boolean)
* @since 1.4
*/
public boolean
isWheelScrollingEnabled() {
return
wheelScrollingEnabled;
}
/**
* Writes default serializable fields to stream.
*/
private void
writeObject(
ObjectOutputStream s) throws
IOException {
// 4352819: We only need this degenerate writeObject to make
// it safe for future versions of this class to write optional
// data to the stream.
s.
defaultWriteObject();
}
/**
* Reads default serializable fields to stream.
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless()</code> returns
* <code>true</code>
* @see java.awt.GraphicsEnvironment#isHeadless
*/
private void
readObject(
ObjectInputStream s)
throws
ClassNotFoundException,
IOException,
HeadlessException
{
GraphicsEnvironment.
checkHeadless();
// 4352819: Gotcha! Cannot use s.defaultReadObject here and
// then continue with reading optional data. Use GetField instead.
ObjectInputStream.
GetField f =
s.
readFields();
// Old fields
scrollbarDisplayPolicy =
f.
get("scrollbarDisplayPolicy",
SCROLLBARS_AS_NEEDED);
hAdjustable = (
ScrollPaneAdjustable)
f.
get("hAdjustable", null);
vAdjustable = (
ScrollPaneAdjustable)
f.
get("vAdjustable", null);
// Since 1.4
wheelScrollingEnabled =
f.
get("wheelScrollingEnabled",
defaultWheelScroll);
// // Note to future maintainers
// if (f.defaulted("wheelScrollingEnabled")) {
// // We are reading pre-1.4 stream that doesn't have
// // optional data, not even the TC_ENDBLOCKDATA marker.
// // Reading anything after this point is unsafe as we will
// // read unrelated objects further down the stream (4352819).
// }
// else {
// // Reading data from 1.4 or later, it's ok to try to read
// // optional data as OptionalDataException with eof == true
// // will be correctly reported
// }
}
class
PeerFixer implements
AdjustmentListener, java.io.
Serializable
{
private static final long
serialVersionUID = 1043664721353696630L;
PeerFixer(
ScrollPane scroller) {
this.
scroller =
scroller;
}
/**
* Invoked when the value of the adjustable has changed.
*/
public void
adjustmentValueChanged(
AdjustmentEvent e) {
Adjustable adj =
e.
getAdjustable();
int
value =
e.
getValue();
ScrollPanePeer peer = (
ScrollPanePeer)
scroller.
peer;
if (
peer != null) {
peer.
setValue(
adj,
value);
}
Component c =
scroller.
getComponent(0);
switch(
adj.
getOrientation()) {
case
Adjustable.
VERTICAL:
c.
move(
c.
getLocation().
x, -(
value));
break;
case
Adjustable.
HORIZONTAL:
c.
move(-(
value),
c.
getLocation().
y);
break;
default:
throw new
IllegalArgumentException("Illegal adjustable orientation");
}
}
private
ScrollPane scroller;
}
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this ScrollPane.
* For scroll panes, the AccessibleContext takes the form of an
* AccessibleAWTScrollPane.
* A new AccessibleAWTScrollPane instance is created if necessary.
*
* @return an AccessibleAWTScrollPane that serves as the
* AccessibleContext of this ScrollPane
* @since 1.3
*/
public
AccessibleContext getAccessibleContext() {
if (
accessibleContext == null) {
accessibleContext = new
AccessibleAWTScrollPane();
}
return
accessibleContext;
}
/**
* This class implements accessibility support for the
* <code>ScrollPane</code> class. It provides an implementation of the
* Java Accessibility API appropriate to scroll pane user-interface
* elements.
* @since 1.3
*/
protected class
AccessibleAWTScrollPane extends
AccessibleAWTContainer
{
/*
* JDK 1.3 serialVersionUID
*/
private static final long
serialVersionUID = 6100703663886637L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
* @see AccessibleRole
*/
public
AccessibleRole getAccessibleRole() {
return
AccessibleRole.
SCROLL_PANE;
}
} // class AccessibleAWTScrollPane
}
/*
* In JDK 1.1.1, the pkg private class java.awt.PeerFixer was moved to
* become an inner class of ScrollPane, which broke serialization
* for ScrollPane objects using JDK 1.1.
* Instead of moving it back out here, which would break all JDK 1.1.x
* releases, we keep PeerFixer in both places. Because of the scoping rules,
* the PeerFixer that is used in ScrollPane will be the one that is the
* inner class. This pkg private PeerFixer class below will only be used
* if the Java 2 platform is used to deserialize ScrollPane objects that were serialized
* using JDK1.1
*/
class
PeerFixer implements
AdjustmentListener, java.io.
Serializable {
/*
* serialVersionUID
*/
private static final long
serialVersionUID = 7051237413532574756L;
PeerFixer(
ScrollPane scroller) {
this.
scroller =
scroller;
}
/**
* Invoked when the value of the adjustable has changed.
*/
public void
adjustmentValueChanged(
AdjustmentEvent e) {
Adjustable adj =
e.
getAdjustable();
int
value =
e.
getValue();
ScrollPanePeer peer = (
ScrollPanePeer)
scroller.
peer;
if (
peer != null) {
peer.
setValue(
adj,
value);
}
Component c =
scroller.
getComponent(0);
switch(
adj.
getOrientation()) {
case
Adjustable.
VERTICAL:
c.
move(
c.
getLocation().
x, -(
value));
break;
case
Adjustable.
HORIZONTAL:
c.
move(-(
value),
c.
getLocation().
y);
break;
default:
throw new
IllegalArgumentException("Illegal adjustable orientation");
}
}
private
ScrollPane scroller;
}