Merge from the pain train
[official-gcc.git] / libjava / java / awt / ScrollPane.java
blobc38feb339c57b4d288100cb9390327dd4ace931e
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)
9 any later version.
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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
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
24 combination.
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. */
39 package java.awt;
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;
49 /**
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
59 * Static Variables
62 /**
63 * Constant indicating that scrollbars are created as needed in this
64 * windows.
66 public static final int SCROLLBARS_AS_NEEDED = 0;
68 /**
69 * Constant indicating that scrollbars are always displayed in this
70 * window.
72 public static final int SCROLLBARS_ALWAYS = 1;
74 /**
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 /*************************************************************************/
85 * Instance Variables
88 /**
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;
95 /**
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 /*************************************************************************/
116 * Constructors
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.
125 public
126 ScrollPane()
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.
142 public
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;
164 // Default size.
165 setSize(100,100);
168 /*************************************************************************/
171 * Instance Variables
175 * Returns the current scrollbar display policy.
177 * @return The current scrollbar display policy.
179 public int
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.
194 public Adjustable
195 getHAdjustable()
197 return(hAdjustable);
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.
209 public Adjustable
210 getVAdjustable()
212 return(vAdjustable);
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))
233 return viewsize;
235 Dimension dim = list[0].getPreferredSize();
237 if (dim.width <= 0 && dim.height <= 0)
238 return viewsize;
240 int vScrollbarWidth = getVScrollbarWidth ();
241 int hScrollbarHeight = getHScrollbarHeight ();
243 if (scrollbarDisplayPolicy == SCROLLBARS_ALWAYS)
245 viewsize.width -= vScrollbarWidth;
246 viewsize.height -= hScrollbarHeight;
247 return viewsize;
250 if (scrollbarDisplayPolicy == SCROLLBARS_NEVER)
251 return viewsize;
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
265 // width.
266 if (dim.height > viewsize.height)
267 needVertical = true;
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)
284 needVertical = true;
286 if (needHorizontal)
287 viewsize.height -= hScrollbarHeight;
289 if (needVertical)
290 viewsize.width -= vScrollbarWidth;
292 return viewsize;
295 /*************************************************************************/
298 * Returns the height of a horizontal scrollbar.
300 * @return The height of a horizontal scrollbar.
302 public int
303 getHScrollbarHeight()
305 ScrollPanePeer spp = (ScrollPanePeer)getPeer();
306 if (spp != null)
307 return(spp.getHScrollbarHeight());
308 else
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.
319 public int
320 getVScrollbarWidth()
322 ScrollPanePeer spp = (ScrollPanePeer)getPeer();
323 if (spp != null)
324 return(spp.getVScrollbarWidth());
325 else
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.
336 public Point
337 getScrollPosition()
339 int x = 0;
340 int y = 0;
342 Adjustable v = getVAdjustable();
343 Adjustable h = getHAdjustable();
345 if (v != null)
346 y = v.getValue();
347 if (h != null)
348 x = h.getValue();
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.
363 public void
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.
380 public void
381 setScrollPosition(int x, int y)
383 Adjustable h = getHAdjustable();
384 Adjustable v = getVAdjustable();
386 if (h != null)
387 h.setValue(x);
388 if (v != null)
389 v.setValue(y);
391 ScrollPanePeer spp = (ScrollPanePeer)getPeer();
392 if (spp != null)
393 spp.setScrollPosition(x, y);
396 /*************************************************************************/
399 * Notifies this object that it should create its native peer.
401 public void
402 addNotify()
404 if (!isDisplayable ())
405 return;
407 setPeer((ComponentPeer)getToolkit().createScrollPane(this));
408 super.addNotify();
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);
416 add(panel);
420 /*************************************************************************/
423 * Notifies this object that it should destroy its native peers.
425 public void
426 removeNotify()
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,
444 int index)
446 Component[] list = getComponents();
447 if ((list != null) && (list.length > 0))
448 remove(list[0]);
450 super.addImpl(component, constraints, -1);
452 doLayout();
455 /*************************************************************************/
458 * Lays out this component. This consists of resizing the sole child
459 * component to its perferred size.
461 public void
462 doLayout()
464 layout ();
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>.
476 public void
477 layout()
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 ();
492 if (peer != null)
493 peer.childResized (dim.width, dim.height);
495 list[0].setSize (dim);
497 Point p = getScrollPosition ();
498 if (p.x > dim.width)
499 p.x = dim.width;
500 if (p.y > dim.height)
501 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
516 public final void
517 setLayout(LayoutManager layoutManager)
519 return;
522 /*************************************************************************/
525 * Prints all of the components in this container.
527 * @param graphics The desired graphics context for printing.
529 public void
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.
542 public String
543 paramString()
545 Insets insets = getInsets();
546 return getName() + ","
547 + getX() + ","
548 + getY() + ","
549 + getWidth() + "x" + getHeight() + ","
550 + "ScrollPosition=(" + scrollPosition.getX() + ","
551 + scrollPosition.getY() + "),"
552 + "Insets=(" + insets.top + ","
553 + insets.left + ","
554 + insets.bottom + ","
555 + insets.right + "),"
556 + "ScrollbarDisplayPolicy=" + getScrollbarDisplayPolicy() + ","
557 + "wheelScrollingEnabled=" + isWheelScrollingEnabled();
561 * Tells whether or not an event is enabled.
563 * @since 1.4
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.
576 * @since 1.4
578 public boolean isWheelScrollingEnabled ()
580 return wheelScrollingEnabled;
584 * Enables/disables wheel scrolling.
586 * @since 1.4
588 public void setWheelScrollingEnabled (boolean enable)
590 wheelScrollingEnabled = enable;
593 protected class AccessibleAWTScrollPane extends AccessibleAWTContainer
595 public AccessibleRole getAccessibleRole()
597 return AccessibleRole.SCROLL_PANE;
602 * Gets the AccessibleContext associated with this <code>ScrollPane</code>.
603 * The context is created, if necessary.
605 * @return the associated context
607 public AccessibleContext getAccessibleContext()
609 /* Create the context if this is the first request */
610 if (accessibleContext == null)
611 accessibleContext = new AccessibleAWTScrollPane();
612 return accessibleContext;
614 } // class ScrollPane