2 Copyright (C) 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., 59 Temple Place, Suite 330, 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.Component;
42 import java.awt.ComponentOrientation;
43 import java.awt.Dimension;
44 import java.awt.LayoutManager;
45 import java.awt.Insets;
46 import java.awt.LayoutManager;
47 import java.awt.Point;
48 import java.awt.Rectangle;
50 import javax.accessibility.Accessible;
51 import javax.swing.border.Border;
52 import javax.swing.event.ChangeEvent;
53 import javax.swing.event.ChangeListener;
54 import javax.swing.plaf.ScrollPaneUI;
55 import javax.swing.plaf.UIResource;
59 * <tr><th>Property </th><th>Stored in </th><th>Bound?</th></tr>
60 * <tr><td>columnHeader </td><td>scrollPane </td><td>yes </td></tr>
61 * <tr><td>columnHeaderView </td><td>columnHeader </td><td>no </td></tr>
62 * <tr><td>componentOrientation </td><td>scrollPane </td><td>yes </td></tr>
63 * <tr><td>horizontalScrollBar </td><td>scrollPane </td><td>yes </td></tr>
64 * <tr><td>horizontalScrollBarPolicy </td><td>scrollPane </td><td>yes </td></tr>
65 * <tr><td>layout </td><td>scrollPane </td><td>yes </td></tr>
66 * <tr><td>rowHeader </td><td>scrollPane </td><td>yes </td></tr>
67 * <tr><td>rowHeaderView </td><td>rowHeader </td><td>no </td></tr>
68 * <tr><td>validateRoot </td><td>scrollPane </td><td>no </td></tr>
69 * <tr><td>verticalScrollBar </td><td>scrollPane </td><td>yes </td></tr>
70 * <tr><td>verticalScrollBarPolicy </td><td>scrollPane </td><td>yes </td></tr>
71 * <tr><td>viewport </td><td>scrollPane </td><td>yes </td></tr>
72 * <tr><td>viewportBorder </td><td>scrollPane </td><td>yes </td></tr>
73 * <tr><td>viewportBorderBounds </td><td>scrollPane </td><td>no </td></tr>
74 * <tr><td>viewportView </td><td>viewport </td><td>no </td></tr>
75 * <tr><td>wheelScrollingEnabled </td><td>scrollPane </td><td>yes </td></tr>
78 public class JScrollPane
80 implements Accessible, ScrollPaneConstants
82 JViewport columnHeader;
90 JScrollBar horizontalScrollBar;
91 int horizontalScrollBarPolicy;
92 JScrollBar verticalScrollBar;
93 int verticalScrollBarPolicy;
96 Border viewportBorder;
97 boolean wheelScrollingEnabled;
98 ChangeListener scrollListener;
100 public static final String COLUMN_HEADER_CHANGED_PROPERTY = "columnHeader";
101 public static final String COMPONENT_ORIENTATION_CHANGED_PROPERTY = "componentOrientation";
102 public static final String HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY = "horizontalScrollBar";
103 public static final String HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "horizontalScrollBarPolicy";
104 public static final String LAYOUT_CHANGED_PROPERTY = "layout";
105 public static final String ROW_HEADER_CHANGED_PROPERTY = "rowHeader";
106 public static final String VERTICAL_SCROLLBAR_CHANGED_PROPERTY = "verticalScrollBar";
107 public static final String VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "verticalScrollBarPolicy";
108 public static final String VIEWPORT_CHANGED_PROPERTY = "viewport";
109 public static final String VIEWPORT_BORDER_CHANGED_PROPERTY = "viewportBorder";
110 public static final String WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY = "wheelScrollingEnabled";
112 public JViewport getColumnHeader()
117 public Component getCorner(String key) {
118 if (getComponentOrientation()
119 == ComponentOrientation.LEFT_TO_RIGHT)
121 if (key == LOWER_LEADING_CORNER)
122 key = LOWER_LEFT_CORNER;
123 else if (key == LOWER_TRAILING_CORNER)
124 key = LOWER_RIGHT_CORNER;
125 else if (key == UPPER_LEADING_CORNER)
126 key = UPPER_LEFT_CORNER;
127 else if (key == UPPER_TRAILING_CORNER)
128 key = UPPER_RIGHT_CORNER;
130 else if (getComponentOrientation()
131 == ComponentOrientation.RIGHT_TO_LEFT)
133 if (key == LOWER_LEADING_CORNER)
134 key = LOWER_RIGHT_CORNER;
135 else if (key == LOWER_TRAILING_CORNER)
136 key = LOWER_LEFT_CORNER;
137 else if (key == UPPER_LEADING_CORNER)
138 key = UPPER_RIGHT_CORNER;
139 else if (key == UPPER_TRAILING_CORNER)
140 key = UPPER_LEFT_CORNER;
143 if (key == LOWER_RIGHT_CORNER)
145 else if (key == UPPER_RIGHT_CORNER)
147 else if (key == LOWER_LEFT_CORNER)
149 else if (key == UPPER_LEFT_CORNER)
154 public JScrollBar getHorizontalScrollBar()
156 return horizontalScrollBar;
159 public int getHorizontalScrollBarPolicy()
161 return horizontalScrollBarPolicy;
164 public JViewport getRowHeader()
169 public JScrollBar getVerticalScrollBar()
171 return verticalScrollBar;
174 public int getVerticalScrollBarPolicy()
176 return verticalScrollBarPolicy;
179 public JViewport getViewport()
184 public Border getViewportBorder()
186 return viewportBorder;
189 public Rectangle getViewportBorderBounds()
191 if (viewportBorder == null)
193 if (getViewport() == null)
194 return new Rectangle(0,0,0,0);
196 return getViewport().getBounds();
200 Insets i = viewportBorder.getBorderInsets(getViewport());
201 if (getViewport() == null)
202 return new Rectangle(0,0,
203 i.left+i.right, i.top+i.bottom);
206 Rectangle b = getViewport().getBounds();
207 return new Rectangle(b.x - i.left,
209 b.width + i.left + i.right,
210 b.height + i.top + i.bottom);
215 public boolean isWheelScrollingEnabled()
217 return wheelScrollingEnabled;
224 LayoutManager m = super.getLayout();
225 if (m != null && m instanceof ScrollPaneLayout)
227 ScrollPaneLayout sl = (ScrollPaneLayout) m;
228 sl.syncWithScrollPane(this);
232 private void removeNonNull(Component c)
238 private void addNonNull(Component c)
244 public void setComponentOrientation(ComponentOrientation co)
246 ComponentOrientation old = super.getComponentOrientation();
247 super.setComponentOrientation(co);
248 firePropertyChange(COMPONENT_ORIENTATION_CHANGED_PROPERTY, old, co);
252 public void setColumnHeader(JViewport h)
254 JViewport old = columnHeader;
258 firePropertyChange(COLUMN_HEADER_CHANGED_PROPERTY, old, h);
262 public void setColumnHeaderView(Component c)
264 if (columnHeader == null)
265 setColumnHeader(createViewport());
266 columnHeader.setView(c);
270 public void setCorner(String key, Component c)
272 if (getComponentOrientation()
273 == ComponentOrientation.LEFT_TO_RIGHT)
275 if (key == LOWER_LEADING_CORNER)
276 key = LOWER_LEFT_CORNER;
277 else if (key == LOWER_TRAILING_CORNER)
278 key = LOWER_RIGHT_CORNER;
279 else if (key == UPPER_LEADING_CORNER)
280 key = UPPER_LEFT_CORNER;
281 else if (key == UPPER_TRAILING_CORNER)
282 key = UPPER_RIGHT_CORNER;
284 else if (getComponentOrientation()
285 == ComponentOrientation.RIGHT_TO_LEFT)
287 if (key == LOWER_LEADING_CORNER)
288 key = LOWER_RIGHT_CORNER;
289 else if (key == LOWER_TRAILING_CORNER)
290 key = LOWER_LEFT_CORNER;
291 else if (key == UPPER_LEADING_CORNER)
292 key = UPPER_RIGHT_CORNER;
293 else if (key == UPPER_TRAILING_CORNER)
294 key = UPPER_LEFT_CORNER;
297 if (key == LOWER_RIGHT_CORNER)
299 removeNonNull(lowerRight);
303 else if (key == UPPER_RIGHT_CORNER)
305 removeNonNull(upperRight);
309 else if (key == LOWER_LEFT_CORNER)
311 removeNonNull(lowerLeft);
315 else if (key == UPPER_LEFT_CORNER)
317 removeNonNull(upperLeft);
322 throw new IllegalArgumentException("unknown corner " + key);
326 public void setHorizontalScrollBar(JScrollBar h)
328 JScrollBar old = horizontalScrollBar;
330 horizontalScrollBar = h;
332 firePropertyChange(HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY, old, h);
337 BoundedRangeModel model = old.getModel();
339 model.removeChangeListener(scrollListener);
343 BoundedRangeModel model = h.getModel();
345 model.addChangeListener(scrollListener);
349 public void setHorizontalScrollBarPolicy(int h)
351 if (h != HORIZONTAL_SCROLLBAR_AS_NEEDED
352 && h != HORIZONTAL_SCROLLBAR_NEVER
353 && h != HORIZONTAL_SCROLLBAR_ALWAYS)
354 throw new IllegalArgumentException("unknown horizontal scrollbar policy");
355 int old = horizontalScrollBarPolicy;
356 horizontalScrollBarPolicy = h;
357 firePropertyChange(HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, h);
361 public void setLayout(LayoutManager l)
363 LayoutManager old = super.getLayout();
364 ScrollPaneLayout tmp = (ScrollPaneLayout) l;
366 tmp.syncWithScrollPane(this);
367 firePropertyChange(LAYOUT_CHANGED_PROPERTY, old, l);
371 public void setRowHeader(JViewport v)
373 JViewport old = rowHeader;
377 firePropertyChange(ROW_HEADER_CHANGED_PROPERTY, old, v);
381 public void setRowHeaderView(Component c)
383 if (rowHeader == null)
384 setRowHeader(createViewport());
385 rowHeader.setView(c);
389 public void setVerticalScrollBar(JScrollBar v)
391 JScrollBar old = verticalScrollBar;
393 verticalScrollBar = v;
395 firePropertyChange(VERTICAL_SCROLLBAR_CHANGED_PROPERTY, old, v);
400 BoundedRangeModel model = old.getModel();
402 model.removeChangeListener(scrollListener);
406 BoundedRangeModel model = v.getModel();
408 model.addChangeListener(scrollListener);
412 public void setVerticalScrollBarPolicy(int v)
414 if (v != VERTICAL_SCROLLBAR_AS_NEEDED
415 && v != VERTICAL_SCROLLBAR_NEVER
416 && v != VERTICAL_SCROLLBAR_ALWAYS)
417 throw new IllegalArgumentException("unknown vertical scrollbar policy");
418 int old = verticalScrollBarPolicy;
419 verticalScrollBarPolicy = v;
420 firePropertyChange(VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, v);
424 public void setWheelScrollingEnabled(boolean b)
426 boolean old = wheelScrollingEnabled;
427 wheelScrollingEnabled = b;
428 firePropertyChange(WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY, old, b);
432 public void setViewport(JViewport v)
434 JViewport old = viewport;
437 old.removeChangeListener(scrollListener);
440 v.addChangeListener(scrollListener);
444 firePropertyChange(VIEWPORT_CHANGED_PROPERTY, old, v);
448 public void setViewportBorder(Border b)
450 Border old = viewportBorder;
452 firePropertyChange(VIEWPORT_BORDER_CHANGED_PROPERTY, old, b);
456 public void setViewportView(Component view)
458 if (getViewport() == null)
460 setViewport(createViewport());
465 getViewport().setView(view);
470 public boolean isValidateRoot()
475 ChangeListener createScrollListener()
477 return new ChangeListener()
480 public void stateChanged(ChangeEvent event)
482 JScrollBar vsb = JScrollPane.this.getVerticalScrollBar();
483 JScrollBar hsb = JScrollPane.this.getHorizontalScrollBar();
484 JViewport vp = JScrollPane.this.getViewport();
486 if (vp != null && event.getSource() == vp)
488 // if the viewport changed, we should update the VSB / HSB
489 // models according to the new vertical and horizontal sizes
490 Rectangle vr = vp.getViewRect();
491 Dimension vs = vp.getViewSize();
492 // System.err.println("got change from viewport, vr=" + vr + ", vs=" + vs);
494 && (vsb.getMinimum() != 0
495 || vsb.getMaximum() != vs.height
496 || vsb.getValue() != vr.y
497 || vsb.getVisibleAmount() != vr.height))
499 // System.err.println("setting vsb to "
501 // + ", ext=" + vr.height
503 // + ", max=" + vs.height);
504 vsb.setValue(vr.y, vr.height, 0, vs.height);
508 && (hsb.getMinimum() != 0
509 || hsb.getMaximum() != vs.width
510 || hsb.getValue() != vr.width
511 || hsb.getVisibleAmount() != vr.height))
512 hsb.setValue(vr.x, vr.width, 0, vs.width);
516 // otherwise we got a change update from either the VSB or
517 // HSB model, and we need to update the viewport position to
524 ypos = vsb.getValue();
527 xpos = hsb.getValue();
529 Point pt = new Point(xpos, ypos);
532 && vp.getViewPosition() != pt)
533 vp.setViewPosition(pt);
545 public JScrollPane(Component view)
548 VERTICAL_SCROLLBAR_AS_NEEDED,
549 HORIZONTAL_SCROLLBAR_AS_NEEDED);
552 public JScrollPane(int vsbPolicy, int hsbPolicy)
554 this(null, vsbPolicy, hsbPolicy);
557 public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
559 scrollListener = createScrollListener();
560 setVerticalScrollBarPolicy(vsbPolicy);
561 setVerticalScrollBar(createVerticalScrollBar());
562 setHorizontalScrollBarPolicy(hsbPolicy);
563 setHorizontalScrollBar(createHorizontalScrollBar());
564 setViewportView(view);
565 setLayout(new ScrollPaneLayout());
571 public JScrollBar createHorizontalScrollBar()
573 return new ScrollBar(SwingConstants.HORIZONTAL);
576 public JScrollBar createVerticalScrollBar()
578 return new ScrollBar(SwingConstants.VERTICAL);
581 public JViewport createViewport()
583 return new JViewport();
587 public String getUIClassID()
589 return "ScrollPaneUI";
592 public void updateUI()
594 ScrollPaneUI b = (ScrollPaneUI)UIManager.getUI(this);
601 implements UIResource
603 public ScrollBar(int orientation)
608 public int getBlockIncrement(int direction)
610 Component view = JScrollPane.this.getViewport().getView();
611 if (view == null || (! (view instanceof Scrollable)))
612 return super.getBlockIncrement(direction);
615 Scrollable s = (Scrollable) view;
616 return s.getScrollableBlockIncrement(JScrollPane.this.getViewport().getViewRect(),
617 this.getOrientation(),
622 public int getUnitIncrement(int direction)
624 Component view = JScrollPane.this.getViewport().getView();
625 if (view == null || (! (view instanceof Scrollable)))
626 return super.getUnitIncrement(direction);
629 Scrollable s = (Scrollable) view;
630 return s.getScrollableUnitIncrement(JScrollPane.this.getViewport().getViewRect(),
631 this.getOrientation(),