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 private static final long serialVersionUID
= 5203525440012340014L;
84 protected JViewport columnHeader
;
85 protected JViewport rowHeader
;
87 protected Component lowerLeft
;
88 protected Component lowerRight
;
89 protected Component upperLeft
;
90 protected Component upperRight
;
92 protected JScrollBar horizontalScrollBar
;
93 protected int horizontalScrollBarPolicy
;
94 protected JScrollBar verticalScrollBar
;
95 protected int verticalScrollBarPolicy
;
97 protected JViewport viewport
;
99 Border viewportBorder
;
100 boolean wheelScrollingEnabled
;
101 ChangeListener scrollListener
;
103 public static final String COLUMN_HEADER_CHANGED_PROPERTY
= "columnHeader";
104 public static final String COMPONENT_ORIENTATION_CHANGED_PROPERTY
= "componentOrientation";
105 public static final String HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY
= "horizontalScrollBar";
106 public static final String HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY
= "horizontalScrollBarPolicy";
107 public static final String LAYOUT_CHANGED_PROPERTY
= "layout";
108 public static final String ROW_HEADER_CHANGED_PROPERTY
= "rowHeader";
109 public static final String VERTICAL_SCROLLBAR_CHANGED_PROPERTY
= "verticalScrollBar";
110 public static final String VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY
= "verticalScrollBarPolicy";
111 public static final String VIEWPORT_CHANGED_PROPERTY
= "viewport";
112 public static final String VIEWPORT_BORDER_CHANGED_PROPERTY
= "viewportBorder";
113 public static final String WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY
= "wheelScrollingEnabled";
115 public JViewport
getColumnHeader()
120 public Component
getCorner(String key
) {
121 if (getComponentOrientation()
122 == ComponentOrientation
.LEFT_TO_RIGHT
)
124 if (key
== LOWER_LEADING_CORNER
)
125 key
= LOWER_LEFT_CORNER
;
126 else if (key
== LOWER_TRAILING_CORNER
)
127 key
= LOWER_RIGHT_CORNER
;
128 else if (key
== UPPER_LEADING_CORNER
)
129 key
= UPPER_LEFT_CORNER
;
130 else if (key
== UPPER_TRAILING_CORNER
)
131 key
= UPPER_RIGHT_CORNER
;
133 else if (getComponentOrientation()
134 == ComponentOrientation
.RIGHT_TO_LEFT
)
136 if (key
== LOWER_LEADING_CORNER
)
137 key
= LOWER_RIGHT_CORNER
;
138 else if (key
== LOWER_TRAILING_CORNER
)
139 key
= LOWER_LEFT_CORNER
;
140 else if (key
== UPPER_LEADING_CORNER
)
141 key
= UPPER_RIGHT_CORNER
;
142 else if (key
== UPPER_TRAILING_CORNER
)
143 key
= UPPER_LEFT_CORNER
;
146 if (key
== LOWER_RIGHT_CORNER
)
148 else if (key
== UPPER_RIGHT_CORNER
)
150 else if (key
== LOWER_LEFT_CORNER
)
152 else if (key
== UPPER_LEFT_CORNER
)
157 public JScrollBar
getHorizontalScrollBar()
159 return horizontalScrollBar
;
162 public int getHorizontalScrollBarPolicy()
164 return horizontalScrollBarPolicy
;
167 public JViewport
getRowHeader()
172 public JScrollBar
getVerticalScrollBar()
174 return verticalScrollBar
;
177 public int getVerticalScrollBarPolicy()
179 return verticalScrollBarPolicy
;
182 public JViewport
getViewport()
187 public Border
getViewportBorder()
189 return viewportBorder
;
192 public Rectangle
getViewportBorderBounds()
194 if (viewportBorder
== null)
196 if (getViewport() == null)
197 return new Rectangle(0,0,0,0);
199 return getViewport().getBounds();
203 Insets i
= viewportBorder
.getBorderInsets(getViewport());
204 if (getViewport() == null)
205 return new Rectangle(0,0,
206 i
.left
+i
.right
, i
.top
+i
.bottom
);
209 Rectangle b
= getViewport().getBounds();
210 return new Rectangle(b
.x
- i
.left
,
212 b
.width
+ i
.left
+ i
.right
,
213 b
.height
+ i
.top
+ i
.bottom
);
218 public boolean isWheelScrollingEnabled()
220 return wheelScrollingEnabled
;
227 LayoutManager m
= super.getLayout();
228 if (m
!= null && m
instanceof ScrollPaneLayout
)
230 ScrollPaneLayout sl
= (ScrollPaneLayout
) m
;
231 sl
.syncWithScrollPane(this);
235 private void removeNonNull(Component c
)
241 private void addNonNull(Component c
)
247 public void setComponentOrientation(ComponentOrientation co
)
249 ComponentOrientation old
= super.getComponentOrientation();
250 super.setComponentOrientation(co
);
251 firePropertyChange(COMPONENT_ORIENTATION_CHANGED_PROPERTY
, old
, co
);
255 public void setColumnHeader(JViewport h
)
257 JViewport old
= columnHeader
;
261 firePropertyChange(COLUMN_HEADER_CHANGED_PROPERTY
, old
, h
);
265 public void setColumnHeaderView(Component c
)
267 if (columnHeader
== null)
268 setColumnHeader(createViewport());
269 columnHeader
.setView(c
);
273 public void setCorner(String key
, Component c
)
275 if (getComponentOrientation()
276 == ComponentOrientation
.LEFT_TO_RIGHT
)
278 if (key
== LOWER_LEADING_CORNER
)
279 key
= LOWER_LEFT_CORNER
;
280 else if (key
== LOWER_TRAILING_CORNER
)
281 key
= LOWER_RIGHT_CORNER
;
282 else if (key
== UPPER_LEADING_CORNER
)
283 key
= UPPER_LEFT_CORNER
;
284 else if (key
== UPPER_TRAILING_CORNER
)
285 key
= UPPER_RIGHT_CORNER
;
287 else if (getComponentOrientation()
288 == ComponentOrientation
.RIGHT_TO_LEFT
)
290 if (key
== LOWER_LEADING_CORNER
)
291 key
= LOWER_RIGHT_CORNER
;
292 else if (key
== LOWER_TRAILING_CORNER
)
293 key
= LOWER_LEFT_CORNER
;
294 else if (key
== UPPER_LEADING_CORNER
)
295 key
= UPPER_RIGHT_CORNER
;
296 else if (key
== UPPER_TRAILING_CORNER
)
297 key
= UPPER_LEFT_CORNER
;
300 if (key
== LOWER_RIGHT_CORNER
)
302 removeNonNull(lowerRight
);
306 else if (key
== UPPER_RIGHT_CORNER
)
308 removeNonNull(upperRight
);
312 else if (key
== LOWER_LEFT_CORNER
)
314 removeNonNull(lowerLeft
);
318 else if (key
== UPPER_LEFT_CORNER
)
320 removeNonNull(upperLeft
);
325 throw new IllegalArgumentException("unknown corner " + key
);
329 public void setHorizontalScrollBar(JScrollBar h
)
331 JScrollBar old
= horizontalScrollBar
;
333 horizontalScrollBar
= h
;
335 firePropertyChange(HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY
, old
, h
);
340 BoundedRangeModel model
= old
.getModel();
342 model
.removeChangeListener(scrollListener
);
346 BoundedRangeModel model
= h
.getModel();
348 model
.addChangeListener(scrollListener
);
352 public void setHorizontalScrollBarPolicy(int h
)
354 if (h
!= HORIZONTAL_SCROLLBAR_AS_NEEDED
355 && h
!= HORIZONTAL_SCROLLBAR_NEVER
356 && h
!= HORIZONTAL_SCROLLBAR_ALWAYS
)
357 throw new IllegalArgumentException("unknown horizontal scrollbar policy");
358 int old
= horizontalScrollBarPolicy
;
359 horizontalScrollBarPolicy
= h
;
360 firePropertyChange(HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY
, old
, h
);
364 public void setLayout(LayoutManager l
)
366 LayoutManager old
= super.getLayout();
367 ScrollPaneLayout tmp
= (ScrollPaneLayout
) l
;
369 tmp
.syncWithScrollPane(this);
370 firePropertyChange(LAYOUT_CHANGED_PROPERTY
, old
, l
);
374 public void setRowHeader(JViewport v
)
376 JViewport old
= rowHeader
;
380 firePropertyChange(ROW_HEADER_CHANGED_PROPERTY
, old
, v
);
384 public void setRowHeaderView(Component c
)
386 if (rowHeader
== null)
387 setRowHeader(createViewport());
388 rowHeader
.setView(c
);
392 public void setVerticalScrollBar(JScrollBar v
)
394 JScrollBar old
= verticalScrollBar
;
396 verticalScrollBar
= v
;
398 firePropertyChange(VERTICAL_SCROLLBAR_CHANGED_PROPERTY
, old
, v
);
403 BoundedRangeModel model
= old
.getModel();
405 model
.removeChangeListener(scrollListener
);
409 BoundedRangeModel model
= v
.getModel();
411 model
.addChangeListener(scrollListener
);
415 public void setVerticalScrollBarPolicy(int v
)
417 if (v
!= VERTICAL_SCROLLBAR_AS_NEEDED
418 && v
!= VERTICAL_SCROLLBAR_NEVER
419 && v
!= VERTICAL_SCROLLBAR_ALWAYS
)
420 throw new IllegalArgumentException("unknown vertical scrollbar policy");
421 int old
= verticalScrollBarPolicy
;
422 verticalScrollBarPolicy
= v
;
423 firePropertyChange(VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY
, old
, v
);
427 public void setWheelScrollingEnabled(boolean b
)
429 boolean old
= wheelScrollingEnabled
;
430 wheelScrollingEnabled
= b
;
431 firePropertyChange(WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY
, old
, b
);
435 public void setViewport(JViewport v
)
437 JViewport old
= viewport
;
440 old
.removeChangeListener(scrollListener
);
443 v
.addChangeListener(scrollListener
);
447 firePropertyChange(VIEWPORT_CHANGED_PROPERTY
, old
, v
);
451 public void setViewportBorder(Border b
)
453 Border old
= viewportBorder
;
455 firePropertyChange(VIEWPORT_BORDER_CHANGED_PROPERTY
, old
, b
);
459 public void setViewportView(Component view
)
461 if (getViewport() == null)
463 setViewport(createViewport());
468 getViewport().setView(view
);
473 public boolean isValidateRoot()
478 ChangeListener
createScrollListener()
480 return new ChangeListener()
483 public void stateChanged(ChangeEvent event
)
485 JScrollBar vsb
= JScrollPane
.this.getVerticalScrollBar();
486 JScrollBar hsb
= JScrollPane
.this.getHorizontalScrollBar();
487 JViewport vp
= JScrollPane
.this.getViewport();
489 if (vp
!= null && event
.getSource() == vp
)
491 // if the viewport changed, we should update the VSB / HSB
492 // models according to the new vertical and horizontal sizes
494 Rectangle vr
= vp
.getViewRect();
495 Dimension vs
= vp
.getViewSize();
497 && (vsb
.getMinimum() != 0
498 || vsb
.getMaximum() != vs
.height
499 || vsb
.getValue() != vr
.y
500 || vsb
.getVisibleAmount() != vr
.height
))
501 vsb
.setValue(vr
.y
, vr
.height
, 0, vs
.height
);
504 && (hsb
.getMinimum() != 0
505 || hsb
.getMaximum() != vs
.width
506 || hsb
.getValue() != vr
.width
507 || hsb
.getVisibleAmount() != vr
.height
))
508 hsb
.setValue(vr
.x
, vr
.width
, 0, vs
.width
);
512 // otherwise we got a change update from either the VSB or
513 // HSB model, and we need to update the viewport position to
520 ypos
= vsb
.getValue();
523 xpos
= hsb
.getValue();
525 Point pt
= new Point(xpos
, ypos
);
528 && vp
.getViewPosition() != pt
)
529 vp
.setViewPosition(pt
);
541 public JScrollPane(Component view
)
544 VERTICAL_SCROLLBAR_AS_NEEDED
,
545 HORIZONTAL_SCROLLBAR_AS_NEEDED
);
548 public JScrollPane(int vsbPolicy
, int hsbPolicy
)
550 this(null, vsbPolicy
, hsbPolicy
);
553 public JScrollPane(Component view
, int vsbPolicy
, int hsbPolicy
)
555 scrollListener
= createScrollListener();
556 setVerticalScrollBarPolicy(vsbPolicy
);
557 setVerticalScrollBar(createVerticalScrollBar());
558 setHorizontalScrollBarPolicy(hsbPolicy
);
559 setHorizontalScrollBar(createHorizontalScrollBar());
560 setViewportView(view
);
561 setLayout(new ScrollPaneLayout());
567 public JScrollBar
createHorizontalScrollBar()
569 return new ScrollBar(SwingConstants
.HORIZONTAL
);
572 public JScrollBar
createVerticalScrollBar()
574 return new ScrollBar(SwingConstants
.VERTICAL
);
577 public JViewport
createViewport()
579 return new JViewport();
583 public String
getUIClassID()
585 return "ScrollPaneUI";
588 public void updateUI()
590 ScrollPaneUI b
= (ScrollPaneUI
)UIManager
.getUI(this);
597 implements UIResource
599 public ScrollBar(int orientation
)
604 public int getBlockIncrement(int direction
)
606 Component view
= JScrollPane
.this.getViewport().getView();
607 if (view
== null || (! (view
instanceof Scrollable
)))
608 return super.getBlockIncrement(direction
);
611 Scrollable s
= (Scrollable
) view
;
612 return s
.getScrollableBlockIncrement(JScrollPane
.this.getViewport().getViewRect(),
613 this.getOrientation(),
618 public int getUnitIncrement(int direction
)
620 Component view
= JScrollPane
.this.getViewport().getView();
621 if (view
== null || (! (view
instanceof Scrollable
)))
622 return super.getUnitIncrement(direction
);
625 Scrollable s
= (Scrollable
) view
;
626 return s
.getScrollableUnitIncrement(JScrollPane
.this.getViewport().getViewRect(),
627 this.getOrientation(),