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.Insets;
45 import java.awt.LayoutManager;
46 import java.awt.Point;
47 import java.awt.Rectangle;
49 import javax.accessibility.Accessible;
50 import javax.swing.border.Border;
51 import javax.swing.event.ChangeEvent;
52 import javax.swing.event.ChangeListener;
53 import javax.swing.plaf.ScrollPaneUI;
54 import javax.swing.plaf.UIResource;
58 * <tr><th>Property </th><th>Stored in </th><th>Bound?</th></tr>
59 * <tr><td>columnHeader </td><td>scrollPane </td><td>yes </td></tr>
60 * <tr><td>columnHeaderView </td><td>columnHeader </td><td>no </td></tr>
61 * <tr><td>componentOrientation </td><td>scrollPane </td><td>yes </td></tr>
62 * <tr><td>horizontalScrollBar </td><td>scrollPane </td><td>yes </td></tr>
63 * <tr><td>horizontalScrollBarPolicy </td><td>scrollPane </td><td>yes </td></tr>
64 * <tr><td>layout </td><td>scrollPane </td><td>yes </td></tr>
65 * <tr><td>rowHeader </td><td>scrollPane </td><td>yes </td></tr>
66 * <tr><td>rowHeaderView </td><td>rowHeader </td><td>no </td></tr>
67 * <tr><td>validateRoot </td><td>scrollPane </td><td>no </td></tr>
68 * <tr><td>verticalScrollBar </td><td>scrollPane </td><td>yes </td></tr>
69 * <tr><td>verticalScrollBarPolicy </td><td>scrollPane </td><td>yes </td></tr>
70 * <tr><td>viewport </td><td>scrollPane </td><td>yes </td></tr>
71 * <tr><td>viewportBorder </td><td>scrollPane </td><td>yes </td></tr>
72 * <tr><td>viewportBorderBounds </td><td>scrollPane </td><td>no </td></tr>
73 * <tr><td>viewportView </td><td>viewport </td><td>no </td></tr>
74 * <tr><td>wheelScrollingEnabled </td><td>scrollPane </td><td>yes </td></tr>
77 public class JScrollPane
79 implements Accessible, ScrollPaneConstants
81 private static final long serialVersionUID = 5203525440012340014L;
83 protected JViewport columnHeader;
84 protected JViewport rowHeader;
86 protected Component lowerLeft;
87 protected Component lowerRight;
88 protected Component upperLeft;
89 protected Component upperRight;
91 protected JScrollBar horizontalScrollBar;
92 protected int horizontalScrollBarPolicy;
93 protected JScrollBar verticalScrollBar;
94 protected int verticalScrollBarPolicy;
96 protected JViewport viewport;
98 Border viewportBorder;
99 boolean wheelScrollingEnabled;
100 ChangeListener scrollListener;
102 public static final String COLUMN_HEADER_CHANGED_PROPERTY = "columnHeader";
103 public static final String COMPONENT_ORIENTATION_CHANGED_PROPERTY = "componentOrientation";
104 public static final String HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY = "horizontalScrollBar";
105 public static final String HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "horizontalScrollBarPolicy";
106 public static final String LAYOUT_CHANGED_PROPERTY = "layout";
107 public static final String ROW_HEADER_CHANGED_PROPERTY = "rowHeader";
108 public static final String VERTICAL_SCROLLBAR_CHANGED_PROPERTY = "verticalScrollBar";
109 public static final String VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "verticalScrollBarPolicy";
110 public static final String VIEWPORT_CHANGED_PROPERTY = "viewport";
111 public static final String VIEWPORT_BORDER_CHANGED_PROPERTY = "viewportBorder";
112 public static final String WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY = "wheelScrollingEnabled";
114 public JViewport getColumnHeader()
119 public Component getCorner(String key) {
120 if (getComponentOrientation()
121 == ComponentOrientation.LEFT_TO_RIGHT)
123 if (key == LOWER_LEADING_CORNER)
124 key = LOWER_LEFT_CORNER;
125 else if (key == LOWER_TRAILING_CORNER)
126 key = LOWER_RIGHT_CORNER;
127 else if (key == UPPER_LEADING_CORNER)
128 key = UPPER_LEFT_CORNER;
129 else if (key == UPPER_TRAILING_CORNER)
130 key = UPPER_RIGHT_CORNER;
132 else if (getComponentOrientation()
133 == ComponentOrientation.RIGHT_TO_LEFT)
135 if (key == LOWER_LEADING_CORNER)
136 key = LOWER_RIGHT_CORNER;
137 else if (key == LOWER_TRAILING_CORNER)
138 key = LOWER_LEFT_CORNER;
139 else if (key == UPPER_LEADING_CORNER)
140 key = UPPER_RIGHT_CORNER;
141 else if (key == UPPER_TRAILING_CORNER)
142 key = UPPER_LEFT_CORNER;
145 if (key == LOWER_RIGHT_CORNER)
147 else if (key == UPPER_RIGHT_CORNER)
149 else if (key == LOWER_LEFT_CORNER)
151 else if (key == UPPER_LEFT_CORNER)
156 public JScrollBar getHorizontalScrollBar()
158 return horizontalScrollBar;
161 public int getHorizontalScrollBarPolicy()
163 return horizontalScrollBarPolicy;
166 public JViewport getRowHeader()
171 public JScrollBar getVerticalScrollBar()
173 return verticalScrollBar;
176 public int getVerticalScrollBarPolicy()
178 return verticalScrollBarPolicy;
181 public JViewport getViewport()
186 public Border getViewportBorder()
188 return viewportBorder;
191 public Rectangle getViewportBorderBounds()
193 if (viewportBorder == null)
195 if (getViewport() == null)
196 return new Rectangle(0,0,0,0);
198 return getViewport().getBounds();
202 Insets i = viewportBorder.getBorderInsets(getViewport());
203 if (getViewport() == null)
204 return new Rectangle(0,0,
205 i.left+i.right, i.top+i.bottom);
208 Rectangle b = getViewport().getBounds();
209 return new Rectangle(b.x - i.left,
211 b.width + i.left + i.right,
212 b.height + i.top + i.bottom);
217 public boolean isWheelScrollingEnabled()
219 return wheelScrollingEnabled;
226 LayoutManager m = super.getLayout();
227 if (m != null && m instanceof ScrollPaneLayout)
229 ScrollPaneLayout sl = (ScrollPaneLayout) m;
230 sl.syncWithScrollPane(this);
234 private void removeNonNull(Component c)
240 private void addNonNull(Component c)
246 public void setComponentOrientation(ComponentOrientation co)
248 ComponentOrientation old = super.getComponentOrientation();
249 super.setComponentOrientation(co);
250 firePropertyChange(COMPONENT_ORIENTATION_CHANGED_PROPERTY, old, co);
254 public void setColumnHeader(JViewport h)
256 JViewport old = columnHeader;
260 firePropertyChange(COLUMN_HEADER_CHANGED_PROPERTY, old, h);
264 public void setColumnHeaderView(Component c)
266 if (columnHeader == null)
267 setColumnHeader(createViewport());
268 columnHeader.setView(c);
272 public void setCorner(String key, Component c)
274 if (getComponentOrientation()
275 == ComponentOrientation.LEFT_TO_RIGHT)
277 if (key == LOWER_LEADING_CORNER)
278 key = LOWER_LEFT_CORNER;
279 else if (key == LOWER_TRAILING_CORNER)
280 key = LOWER_RIGHT_CORNER;
281 else if (key == UPPER_LEADING_CORNER)
282 key = UPPER_LEFT_CORNER;
283 else if (key == UPPER_TRAILING_CORNER)
284 key = UPPER_RIGHT_CORNER;
286 else if (getComponentOrientation()
287 == ComponentOrientation.RIGHT_TO_LEFT)
289 if (key == LOWER_LEADING_CORNER)
290 key = LOWER_RIGHT_CORNER;
291 else if (key == LOWER_TRAILING_CORNER)
292 key = LOWER_LEFT_CORNER;
293 else if (key == UPPER_LEADING_CORNER)
294 key = UPPER_RIGHT_CORNER;
295 else if (key == UPPER_TRAILING_CORNER)
296 key = UPPER_LEFT_CORNER;
299 if (key == LOWER_RIGHT_CORNER)
301 removeNonNull(lowerRight);
305 else if (key == UPPER_RIGHT_CORNER)
307 removeNonNull(upperRight);
311 else if (key == LOWER_LEFT_CORNER)
313 removeNonNull(lowerLeft);
317 else if (key == UPPER_LEFT_CORNER)
319 removeNonNull(upperLeft);
324 throw new IllegalArgumentException("unknown corner " + key);
328 public void setHorizontalScrollBar(JScrollBar h)
330 JScrollBar old = horizontalScrollBar;
332 horizontalScrollBar = h;
334 firePropertyChange(HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY, old, h);
339 BoundedRangeModel model = old.getModel();
341 model.removeChangeListener(scrollListener);
345 BoundedRangeModel model = h.getModel();
347 model.addChangeListener(scrollListener);
351 public void setHorizontalScrollBarPolicy(int h)
353 if (h != HORIZONTAL_SCROLLBAR_AS_NEEDED
354 && h != HORIZONTAL_SCROLLBAR_NEVER
355 && h != HORIZONTAL_SCROLLBAR_ALWAYS)
356 throw new IllegalArgumentException("unknown horizontal scrollbar policy");
357 int old = horizontalScrollBarPolicy;
358 horizontalScrollBarPolicy = h;
359 firePropertyChange(HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, h);
363 public void setLayout(LayoutManager l)
365 LayoutManager old = super.getLayout();
366 ScrollPaneLayout tmp = (ScrollPaneLayout) l;
368 tmp.syncWithScrollPane(this);
369 firePropertyChange(LAYOUT_CHANGED_PROPERTY, old, l);
373 public void setRowHeader(JViewport v)
375 JViewport old = rowHeader;
379 firePropertyChange(ROW_HEADER_CHANGED_PROPERTY, old, v);
383 public void setRowHeaderView(Component c)
385 if (rowHeader == null)
386 setRowHeader(createViewport());
387 rowHeader.setView(c);
391 public void setVerticalScrollBar(JScrollBar v)
393 JScrollBar old = verticalScrollBar;
395 verticalScrollBar = v;
397 firePropertyChange(VERTICAL_SCROLLBAR_CHANGED_PROPERTY, old, v);
402 BoundedRangeModel model = old.getModel();
404 model.removeChangeListener(scrollListener);
408 BoundedRangeModel model = v.getModel();
410 model.addChangeListener(scrollListener);
414 public void setVerticalScrollBarPolicy(int v)
416 if (v != VERTICAL_SCROLLBAR_AS_NEEDED
417 && v != VERTICAL_SCROLLBAR_NEVER
418 && v != VERTICAL_SCROLLBAR_ALWAYS)
419 throw new IllegalArgumentException("unknown vertical scrollbar policy");
420 int old = verticalScrollBarPolicy;
421 verticalScrollBarPolicy = v;
422 firePropertyChange(VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, v);
426 public void setWheelScrollingEnabled(boolean b)
428 boolean old = wheelScrollingEnabled;
429 wheelScrollingEnabled = b;
430 firePropertyChange(WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY, old, b);
434 public void setViewport(JViewport v)
436 JViewport old = viewport;
439 old.removeChangeListener(scrollListener);
442 v.addChangeListener(scrollListener);
446 firePropertyChange(VIEWPORT_CHANGED_PROPERTY, old, v);
450 public void setViewportBorder(Border b)
452 Border old = viewportBorder;
454 firePropertyChange(VIEWPORT_BORDER_CHANGED_PROPERTY, old, b);
458 public void setViewportView(Component view)
460 if (getViewport() == null)
462 setViewport(createViewport());
467 getViewport().setView(view);
472 public boolean isValidateRoot()
477 ChangeListener createScrollListener()
479 return new ChangeListener()
482 public void stateChanged(ChangeEvent event)
484 JScrollBar vsb = JScrollPane.this.getVerticalScrollBar();
485 JScrollBar hsb = JScrollPane.this.getHorizontalScrollBar();
486 JViewport vp = JScrollPane.this.getViewport();
488 if (vp != null && event.getSource() == vp)
490 // if the viewport changed, we should update the VSB / HSB
491 // models according to the new vertical and horizontal sizes
493 Rectangle vr = vp.getViewRect();
494 Dimension vs = vp.getViewSize();
496 && (vsb.getMinimum() != 0
497 || vsb.getMaximum() != vs.height
498 || vsb.getValue() != vr.y
499 || vsb.getVisibleAmount() != vr.height))
500 vsb.setValues(vr.y, vr.height, 0, vs.height);
503 && (hsb.getMinimum() != 0
504 || hsb.getMaximum() != vs.width
505 || hsb.getValue() != vr.width
506 || hsb.getVisibleAmount() != vr.height))
507 hsb.setValues(vr.x, vr.width, 0, vs.width);
511 // otherwise we got a change update from either the VSB or
512 // HSB model, and we need to update the viewport positions of
513 // both the main viewport and any row or column headers to
520 ypos = vsb.getValue();
523 xpos = hsb.getValue();
525 Point pt = new Point(xpos, ypos);
528 && vp.getViewPosition() != pt)
529 vp.setViewPosition(pt);
533 if (rowHeader != null
534 && rowHeader.getViewPosition() != pt)
535 rowHeader.setViewPosition(pt);
540 if (columnHeader != null
541 && columnHeader.getViewPosition() != pt)
542 columnHeader.setViewPosition(pt);
555 public JScrollPane(Component view)
558 VERTICAL_SCROLLBAR_AS_NEEDED,
559 HORIZONTAL_SCROLLBAR_AS_NEEDED);
562 public JScrollPane(int vsbPolicy, int hsbPolicy)
564 this(null, vsbPolicy, hsbPolicy);
567 public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
569 scrollListener = createScrollListener();
570 setVerticalScrollBarPolicy(vsbPolicy);
571 setVerticalScrollBar(createVerticalScrollBar());
572 setHorizontalScrollBarPolicy(hsbPolicy);
573 setHorizontalScrollBar(createHorizontalScrollBar());
574 setViewportView(view);
575 setLayout(new ScrollPaneLayout());
581 public JScrollBar createHorizontalScrollBar()
583 return new ScrollBar(SwingConstants.HORIZONTAL);
586 public JScrollBar createVerticalScrollBar()
588 return new ScrollBar(SwingConstants.VERTICAL);
591 public JViewport createViewport()
593 return new JViewport();
596 public String getUIClassID()
598 return "ScrollPaneUI";
601 public void updateUI()
603 ScrollPaneUI b = (ScrollPaneUI)UIManager.getUI(this);
608 * This method returns the scrollpane's UI delegate.
610 * @return The scrollpane's UI delegate.
612 public ScrollPaneUI getUI()
614 return (ScrollPaneUI) ui;
618 * This method sets the scrollpane's UI delegate.
620 * @param ui The scrollpane's UI delegate.
622 public void setUI(ScrollPaneUI ui)
629 implements UIResource
631 public ScrollBar(int orientation)
636 public int getBlockIncrement(int direction)
638 Component view = JScrollPane.this.getViewport().getView();
639 if (view == null || (! (view instanceof Scrollable)))
640 return super.getBlockIncrement(direction);
643 Scrollable s = (Scrollable) view;
644 return s.getScrollableBlockIncrement(JScrollPane.this.getViewport().getViewRect(),
645 this.getOrientation(),
650 public int getUnitIncrement(int direction)
652 Component view = JScrollPane.this.getViewport().getView();
653 if (view == null || (! (view instanceof Scrollable)))
654 return super.getUnitIncrement(direction);
657 Scrollable s = (Scrollable) view;
658 return s.getScrollableUnitIncrement(JScrollPane.this.getViewport().getViewRect(),
659 this.getOrientation(),