1 /* ScrollPane.java -- Scrolling window
2 Copyright (C) 1999, 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
41 import java
.awt
.event
.MouseEvent
;
42 import java
.awt
.peer
.ComponentPeer
;
43 import java
.awt
.peer
.ScrollPanePeer
;
45 import javax
.accessibility
.Accessible
;
46 import javax
.accessibility
.AccessibleContext
;
47 import javax
.accessibility
.AccessibleRole
;
50 * This widget provides a scrollable region that allows a single
51 * subcomponent to be viewed through a smaller window.
53 * @author Aaron M. Renn (arenn@urbanophile.com)
55 public class ScrollPane
extends Container
implements Accessible
63 * Constant indicating that scrollbars are created as needed in this
66 public static final int SCROLLBARS_AS_NEEDED
= 0;
69 * Constant indicating that scrollbars are always displayed in this
72 public static final int SCROLLBARS_ALWAYS
= 1;
75 * Constant indicating that scrollbars are never displayed in this window.
77 public static final int SCROLLBARS_NEVER
= 2;
79 // Serialization constant
80 private static final long serialVersionUID
= 7956609840827222915L;
82 /*************************************************************************/
89 * @serial The horizontal scrollbar for this window. The methods
90 * <code>setMinimum()</code>, <code>setMaximum</code>, and
91 * <code>setVisibleAmount</code> must not be called on this scrollbar.
93 private ScrollPaneAdjustable hAdjustable
;
96 * @serial The vertical scrollbar for this window. The methods
97 * <code>setMinimum()</code>, <code>setMaximum</code>, and
98 * <code>setVisibleAmount</code> must not be called on this scrollbar.
100 private ScrollPaneAdjustable vAdjustable
;
103 * @serial Indicates when scrollbars are displayed in this window, will
104 * be one of the constants from this class.
106 private int scrollbarDisplayPolicy
;
108 // Current scroll position
109 private Point scrollPosition
= new Point(0, 0);
111 private boolean wheelScrollingEnabled
;
113 /*************************************************************************/
120 * Initializes a new instance of <code>ScrollPane</code> with a default
121 * scrollbar policy of <code>SCROLLBARS_AS_NEEDED</code>.
123 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
128 this(SCROLLBARS_AS_NEEDED
);
131 /*************************************************************************/
134 * Initializes a new instance of <code>ScrollPane</code> with the
135 * specified scrollbar policy.
137 * @param scrollbarDisplayPolicy When to display scrollbars, which must
138 * be one of the constants defined in this class.
140 * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
143 ScrollPane(int scrollbarDisplayPolicy
)
145 if (GraphicsEnvironment
.isHeadless ())
146 throw new HeadlessException ();
148 this.scrollbarDisplayPolicy
= scrollbarDisplayPolicy
;
150 if (scrollbarDisplayPolicy
!= SCROLLBARS_ALWAYS
151 && scrollbarDisplayPolicy
!= SCROLLBARS_AS_NEEDED
152 && scrollbarDisplayPolicy
!= SCROLLBARS_NEVER
)
153 throw new IllegalArgumentException("Bad scrollbarDisplayPolicy: " +
154 scrollbarDisplayPolicy
);
156 if (scrollbarDisplayPolicy
!= SCROLLBARS_NEVER
)
158 hAdjustable
= new ScrollPaneAdjustable (this, Scrollbar
.HORIZONTAL
);
159 vAdjustable
= new ScrollPaneAdjustable (this, Scrollbar
.VERTICAL
);
162 wheelScrollingEnabled
= true;
168 /*************************************************************************/
175 * Returns the current scrollbar display policy.
177 * @return The current scrollbar display policy.
180 getScrollbarDisplayPolicy()
182 return(scrollbarDisplayPolicy
);
185 /*************************************************************************/
188 * Returns the horizontal scrollbar for this object. If the scrollbar
189 * display policy is set to <code>SCROLLBARS_NEVER</code> then this
190 * will be <code>null</code>.
192 * @return The horizontal scrollbar for this window.
200 /*************************************************************************/
203 * Returns the vertical scrollbar for this object. If the scrollbar
204 * display policy is set to <code>SCROLLBARS_NEVER</code> then this
205 * will be <code>null</code>.
207 * @return The horizontal scrollbar for this window.
215 /*************************************************************************/
218 * Returns the current viewport size. The viewport is the region of
219 * this object's window where the child is actually displayed.
221 * @return The viewport size.
223 public Dimension
getViewportSize ()
225 Dimension viewsize
= getSize ();
226 Insets insets
= getInsets ();
228 viewsize
.width
-= (insets
.left
+ insets
.right
);
229 viewsize
.height
-= (insets
.top
+ insets
.bottom
);
231 Component
[] list
= getComponents();
232 if ((list
== null) || (list
.length
<= 0))
235 Dimension dim
= list
[0].getPreferredSize();
237 if (dim
.width
<= 0 && dim
.height
<= 0)
240 int vScrollbarWidth
= getVScrollbarWidth ();
241 int hScrollbarHeight
= getHScrollbarHeight ();
243 if (scrollbarDisplayPolicy
== SCROLLBARS_ALWAYS
)
245 viewsize
.width
-= vScrollbarWidth
;
246 viewsize
.height
-= hScrollbarHeight
;
250 if (scrollbarDisplayPolicy
== SCROLLBARS_NEVER
)
253 // The scroll policy is SCROLLBARS_AS_NEEDED, so we need to see if
254 // either scrollbar is needed.
256 // Assume we don't need either scrollbar.
257 boolean mayNeedVertical
= false;
258 boolean mayNeedHorizontal
= false;
260 boolean needVertical
= false;
261 boolean needHorizontal
= false;
263 // Check if we need vertical scrollbars. If we do, then we need to
264 // subtract the width of the vertical scrollbar from the viewport's
266 if (dim
.height
> viewsize
.height
)
268 else if (dim
.height
> (viewsize
.height
- hScrollbarHeight
))
269 // This is tricky. In this case the child is tall enough that its
270 // bottom edge would be covered by a horizontal scrollbar, if one
271 // were present. This means that if there's a horizontal
272 // scrollbar then we need a vertical scrollbar.
273 mayNeedVertical
= true;
275 if (dim
.width
> viewsize
.width
)
276 needHorizontal
= true;
277 else if (dim
.width
> (viewsize
.width
- vScrollbarWidth
))
278 mayNeedHorizontal
= true;
280 if (needVertical
&& mayNeedHorizontal
)
281 needHorizontal
= true;
283 if (needHorizontal
&& mayNeedVertical
)
287 viewsize
.height
-= hScrollbarHeight
;
290 viewsize
.width
-= vScrollbarWidth
;
295 /*************************************************************************/
298 * Returns the height of a horizontal scrollbar.
300 * @return The height of a horizontal scrollbar.
303 getHScrollbarHeight()
305 ScrollPanePeer spp
= (ScrollPanePeer
)getPeer();
307 return(spp
.getHScrollbarHeight());
309 return(0); // FIXME: What to do here?
312 /*************************************************************************/
315 * Returns the width of a vertical scrollbar.
317 * @return The width of a vertical scrollbar.
322 ScrollPanePeer spp
= (ScrollPanePeer
)getPeer();
324 return(spp
.getVScrollbarWidth());
326 return(0); // FIXME: What to do here?
329 /*************************************************************************/
332 * Returns the current scroll position of the viewport.
334 * @return The current scroll position of the viewport.
342 Adjustable v
= getVAdjustable();
343 Adjustable h
= getHAdjustable();
350 return(new Point(x
, y
));
353 /*************************************************************************/
356 * Sets the scroll position to the specified value.
358 * @param scrollPosition The new scrollPosition.
360 * @exception IllegalArgumentException If the specified value is outside
361 * the legal scrolling range.
364 setScrollPosition(Point scrollPosition
) throws IllegalArgumentException
366 setScrollPosition(scrollPosition
.x
, scrollPosition
.y
);
369 /*************************************************************************/
372 * Sets the scroll position to the specified value.
374 * @param x The new X coordinate of the scroll position.
375 * @param y The new Y coordinate of the scroll position.
377 * @exception IllegalArgumentException If the specified value is outside
378 * the legal scrolling range.
381 setScrollPosition(int x
, int y
)
383 Adjustable h
= getHAdjustable();
384 Adjustable v
= getVAdjustable();
391 ScrollPanePeer spp
= (ScrollPanePeer
)getPeer();
393 spp
.setScrollPosition(x
, y
);
396 /*************************************************************************/
399 * Notifies this object that it should create its native peer.
407 setPeer((ComponentPeer
)getToolkit().createScrollPane(this));
410 Component
[] list
= getComponents();
411 if (list
!= null && list
.length
> 0 && ! (list
[0] instanceof Panel
))
413 Panel panel
= new Panel();
414 panel
.setLayout(new BorderLayout());
415 panel
.add(list
[0], BorderLayout
.CENTER
);
420 /*************************************************************************/
423 * Notifies this object that it should destroy its native peers.
428 super.removeNotify();
431 /*************************************************************************/
434 * Adds the specified child component to this container. A
435 * <code>ScrollPane</code> can have at most one child, so if a second
436 * one is added, then first one is removed.
438 * @param component The component to add to this container.
439 * @param constraints A list of layout constraints for this object.
440 * @param index The index at which to add the child, which is ignored
441 * in this implementation.
443 protected final void addImpl (Component component
, Object constraints
,
446 Component
[] list
= getComponents();
447 if ((list
!= null) && (list
.length
> 0))
450 super.addImpl(component
, constraints
, -1);
455 /*************************************************************************/
458 * Lays out this component. This consists of resizing the sole child
459 * component to its perferred size.
467 /*************************************************************************/
470 * Lays out this component. This consists of resizing the sole child
471 * component to its perferred size.
473 * @deprecated This method is deprecated in favor of
474 * <code>doLayout()</code>.
479 Component
[] list
= getComponents ();
480 if ((list
!= null) && (list
.length
> 0))
482 Dimension dim
= list
[0].getPreferredSize ();
483 Dimension vp
= getViewportSize ();
485 if (dim
.width
< vp
.width
)
486 dim
.width
= vp
.width
;
488 if (dim
.height
< vp
.height
)
489 dim
.height
= vp
.height
;
491 ScrollPanePeer peer
= (ScrollPanePeer
) getPeer ();
493 peer
.childResized (dim
.width
, dim
.height
);
495 list
[0].setSize (dim
);
497 Point p
= getScrollPosition ();
500 if (p
.y
> dim
.height
)
503 setScrollPosition (p
);
507 /*************************************************************************/
510 * This method overrides its superclass method to ensure no layout
511 * manager is set for this container. <code>ScrollPane</code>'s do
512 * not have layout managers.
514 * @param layoutManager Ignored
517 setLayout(LayoutManager layoutManager
)
522 /*************************************************************************/
525 * Prints all of the components in this container.
527 * @param graphics The desired graphics context for printing.
530 printComponents(Graphics graphics
)
532 super.printComponents(graphics
);
535 /*************************************************************************/
538 * Returns a debug string for this object.
540 * @return A debug string for this object.
545 Insets insets
= getInsets();
546 return getName() + ","
549 + getWidth() + "x" + getHeight() + ","
550 + "ScrollPosition=(" + scrollPosition
.getX() + ","
551 + scrollPosition
.getY() + "),"
552 + "Insets=(" + insets
.top
+ ","
554 + insets
.bottom
+ ","
555 + insets
.right
+ "),"
556 + "ScrollbarDisplayPolicy=" + getScrollbarDisplayPolicy() + ","
557 + "wheelScrollingEnabled=" + isWheelScrollingEnabled();
561 * Tells whether or not an event is enabled.
565 protected boolean eventTypeEnabled (int type
)
567 if (type
== MouseEvent
.MOUSE_WHEEL
)
568 return wheelScrollingEnabled
;
570 return super.eventTypeEnabled (type
);
574 * Tells whether or not wheel scrolling is enabled.
578 public boolean isWheelScrollingEnabled ()
580 return wheelScrollingEnabled
;
584 * Enables/disables wheel scrolling.
588 public void setWheelScrollingEnabled (boolean enable
)
590 wheelScrollingEnabled
= enable
;
593 protected class AccessibleAWTScrollPane
extends AccessibleAWTContainer
595 private static final long serialVersionUID
= 6100703663886637L;
597 public AccessibleRole
getAccessibleRole()
599 return AccessibleRole
.SCROLL_PANE
;
604 * Gets the AccessibleContext associated with this <code>ScrollPane</code>.
605 * The context is created, if necessary.
607 * @return the associated context
609 public AccessibleContext
getAccessibleContext()
611 /* Create the context if this is the first request */
612 if (accessibleContext
== null)
613 accessibleContext
= new AccessibleAWTScrollPane();
614 return accessibleContext
;
616 } // class ScrollPane