2 Copyright (C) 2002, 2004, 2005 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
.Component
;
42 import java
.awt
.ComponentOrientation
;
43 import java
.awt
.Insets
;
44 import java
.awt
.LayoutManager
;
45 import java
.awt
.Rectangle
;
46 import java
.beans
.PropertyChangeEvent
;
47 import java
.beans
.PropertyChangeListener
;
49 import javax
.accessibility
.Accessible
;
50 import javax
.accessibility
.AccessibleContext
;
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
;
58 * A component that embeds another component and enables it to be scrolled
59 * both in horizontal and vertical direction.
62 * <tr><th>Property </th><th>Stored in </th><th>Bound?</th></tr>
63 * <tr><td>columnHeader </td><td>scrollPane </td><td>yes </td></tr>
64 * <tr><td>columnHeaderView </td><td>columnHeader </td><td>no </td></tr>
65 * <tr><td>componentOrientation </td><td>scrollPane </td><td>yes </td></tr>
66 * <tr><td>horizontalScrollBar </td><td>scrollPane </td><td>yes </td></tr>
67 * <tr><td>horizontalScrollBarPolicy </td><td>scrollPane </td><td>yes </td></tr>
68 * <tr><td>layout </td><td>scrollPane </td><td>yes </td></tr>
69 * <tr><td>rowHeader </td><td>scrollPane </td><td>yes </td></tr>
70 * <tr><td>rowHeaderView </td><td>rowHeader </td><td>no </td></tr>
71 * <tr><td>validateRoot </td><td>scrollPane </td><td>no </td></tr>
72 * <tr><td>verticalScrollBar </td><td>scrollPane </td><td>yes </td></tr>
73 * <tr><td>verticalScrollBarPolicy </td><td>scrollPane </td><td>yes </td></tr>
74 * <tr><td>viewport </td><td>scrollPane </td><td>yes </td></tr>
75 * <tr><td>viewportBorder </td><td>scrollPane </td><td>yes </td></tr>
76 * <tr><td>viewportBorderBounds </td><td>scrollPane </td><td>no </td></tr>
77 * <tr><td>viewportView </td><td>viewport </td><td>no </td></tr>
78 * <tr><td>wheelScrollingEnabled </td><td>scrollPane </td><td>yes </td></tr>
81 public class JScrollPane
extends JComponent
82 implements Accessible
, ScrollPaneConstants
85 * Provides accessibility support for the <code>JScrollPane</code>.
87 * @author Roman Kennke (kennke@aicas.com)
89 protected class AccessibleJScrollPane
extends AccessibleJComponent
90 implements ChangeListener
, PropertyChangeListener
94 * The viewport of the underlying scrollpane.
96 protected JViewport viewPort
;
99 * Creates a new <code>AccessibleJScrollPane</code> object. This
100 * initializes the <code>viewport</code> field with the current viewport
101 * from the scrollpane associated with this
102 * <code>AccessibleJScrollPane</code>.
104 public AccessibleJScrollPane()
106 viewPort
= getViewport();
107 viewPort
.addChangeListener(this);
108 viewPort
.addPropertyChangeListener(this);
112 * Receives notification when the state of the viewport changes.
114 * @param event the change event
116 public void stateChanged(ChangeEvent event
)
118 // TODO: Figure out what should be done here, if anything.
122 * Receives notification if any of the viewport's bound properties changes.
124 * @param e the propery change event
126 public void propertyChange(PropertyChangeEvent e
)
128 // TODO: Figure out what should be done here, if anything.
132 * Resets the <code>viewPort</code> field when the scrollpane's viewport
133 * changes. This method is called by
134 * {@link JScrollPane#setViewport(JViewport)} in order to update the
135 * <code>viewPort</code> field and set up the listeners on this viewport
138 public void resetViewPort()
140 viewPort
.removeChangeListener(this);
141 viewPort
.removePropertyChangeListener(this);
142 viewPort
= getViewport();
143 viewPort
.addChangeListener(this);
144 viewPort
.addPropertyChangeListener(this);
148 private static final long serialVersionUID
= 5203525440012340014L;
150 protected JViewport columnHeader
;
151 protected JViewport rowHeader
;
153 protected Component lowerLeft
;
154 protected Component lowerRight
;
155 protected Component upperLeft
;
156 protected Component upperRight
;
158 protected JScrollBar horizontalScrollBar
;
159 protected int horizontalScrollBarPolicy
;
160 protected JScrollBar verticalScrollBar
;
161 protected int verticalScrollBarPolicy
;
163 protected JViewport viewport
;
165 Border viewportBorder
;
166 boolean wheelScrollingEnabled
;
168 public JViewport
getColumnHeader()
173 public Component
getCorner(String key
) {
174 if (getComponentOrientation()
175 == ComponentOrientation
.LEFT_TO_RIGHT
)
177 if (key
== LOWER_LEADING_CORNER
)
178 key
= LOWER_LEFT_CORNER
;
179 else if (key
== LOWER_TRAILING_CORNER
)
180 key
= LOWER_RIGHT_CORNER
;
181 else if (key
== UPPER_LEADING_CORNER
)
182 key
= UPPER_LEFT_CORNER
;
183 else if (key
== UPPER_TRAILING_CORNER
)
184 key
= UPPER_RIGHT_CORNER
;
186 else if (getComponentOrientation()
187 == ComponentOrientation
.RIGHT_TO_LEFT
)
189 if (key
== LOWER_LEADING_CORNER
)
190 key
= LOWER_RIGHT_CORNER
;
191 else if (key
== LOWER_TRAILING_CORNER
)
192 key
= LOWER_LEFT_CORNER
;
193 else if (key
== UPPER_LEADING_CORNER
)
194 key
= UPPER_RIGHT_CORNER
;
195 else if (key
== UPPER_TRAILING_CORNER
)
196 key
= UPPER_LEFT_CORNER
;
199 if (key
== LOWER_RIGHT_CORNER
)
201 else if (key
== UPPER_RIGHT_CORNER
)
203 else if (key
== LOWER_LEFT_CORNER
)
205 else if (key
== UPPER_LEFT_CORNER
)
210 public JScrollBar
getHorizontalScrollBar()
212 return horizontalScrollBar
;
215 public int getHorizontalScrollBarPolicy()
217 return horizontalScrollBarPolicy
;
220 public JViewport
getRowHeader()
225 public JScrollBar
getVerticalScrollBar()
227 return verticalScrollBar
;
230 public int getVerticalScrollBarPolicy()
232 return verticalScrollBarPolicy
;
235 public JViewport
getViewport()
240 public Border
getViewportBorder()
242 return viewportBorder
;
245 public Rectangle
getViewportBorderBounds()
247 if (viewportBorder
== null)
249 if (getViewport() == null)
250 return new Rectangle(0,0,0,0);
252 return getViewport().getBounds();
256 Insets i
= viewportBorder
.getBorderInsets(getViewport());
257 if (getViewport() == null)
258 return new Rectangle(0,0,
259 i
.left
+i
.right
, i
.top
+i
.bottom
);
262 Rectangle b
= getViewport().getBounds();
263 return new Rectangle(b
.x
- i
.left
,
265 b
.width
+ i
.left
+ i
.right
,
266 b
.height
+ i
.top
+ i
.bottom
);
271 public boolean isWheelScrollingEnabled()
273 return wheelScrollingEnabled
;
280 LayoutManager m
= super.getLayout();
281 if (m
!= null && m
instanceof ScrollPaneLayout
)
283 ScrollPaneLayout sl
= (ScrollPaneLayout
) m
;
284 sl
.syncWithScrollPane(this);
288 private void removeNonNull(Component c
)
294 private void addNonNull(Component c
, Object constraints
)
300 public void setComponentOrientation(ComponentOrientation co
)
302 ComponentOrientation old
= super.getComponentOrientation();
303 super.setComponentOrientation(co
);
304 firePropertyChange("componentOrientation", old
, co
);
308 public void setColumnHeader(JViewport h
)
310 if (columnHeader
== h
)
313 JViewport old
= columnHeader
;
316 addNonNull(h
, JScrollPane
.COLUMN_HEADER
);
317 firePropertyChange("columnHeader", old
, h
);
321 public void setColumnHeaderView(Component c
)
323 if (columnHeader
== null)
324 setColumnHeader(createViewport());
325 columnHeader
.setView(c
);
329 public void setCorner(String key
, Component c
)
331 if (getComponentOrientation()
332 == ComponentOrientation
.LEFT_TO_RIGHT
)
334 if (key
== LOWER_LEADING_CORNER
)
335 key
= LOWER_LEFT_CORNER
;
336 else if (key
== LOWER_TRAILING_CORNER
)
337 key
= LOWER_RIGHT_CORNER
;
338 else if (key
== UPPER_LEADING_CORNER
)
339 key
= UPPER_LEFT_CORNER
;
340 else if (key
== UPPER_TRAILING_CORNER
)
341 key
= UPPER_RIGHT_CORNER
;
343 else if (getComponentOrientation()
344 == ComponentOrientation
.RIGHT_TO_LEFT
)
346 if (key
== LOWER_LEADING_CORNER
)
347 key
= LOWER_RIGHT_CORNER
;
348 else if (key
== LOWER_TRAILING_CORNER
)
349 key
= LOWER_LEFT_CORNER
;
350 else if (key
== UPPER_LEADING_CORNER
)
351 key
= UPPER_RIGHT_CORNER
;
352 else if (key
== UPPER_TRAILING_CORNER
)
353 key
= UPPER_LEFT_CORNER
;
356 if (key
== LOWER_RIGHT_CORNER
)
358 removeNonNull(lowerRight
);
360 addNonNull(c
, JScrollPane
.LOWER_RIGHT_CORNER
);
362 else if (key
== UPPER_RIGHT_CORNER
)
364 removeNonNull(upperRight
);
366 addNonNull(c
, JScrollPane
.UPPER_RIGHT_CORNER
);
368 else if (key
== LOWER_LEFT_CORNER
)
370 removeNonNull(lowerLeft
);
372 addNonNull(c
, JScrollPane
.LOWER_LEFT_CORNER
);
374 else if (key
== UPPER_LEFT_CORNER
)
376 removeNonNull(upperLeft
);
378 addNonNull(c
, JScrollPane
.UPPER_LEFT_CORNER
);
381 throw new IllegalArgumentException("unknown corner " + key
);
385 public void setHorizontalScrollBar(JScrollBar h
)
387 if (horizontalScrollBar
== h
)
390 JScrollBar old
= horizontalScrollBar
;
392 horizontalScrollBar
= h
;
393 addNonNull(h
, JScrollPane
.HORIZONTAL_SCROLLBAR
);
394 firePropertyChange("horizontalScrollBar", old
, h
);
399 public void setHorizontalScrollBarPolicy(int h
)
401 if (horizontalScrollBarPolicy
== h
)
404 if (h
!= HORIZONTAL_SCROLLBAR_AS_NEEDED
405 && h
!= HORIZONTAL_SCROLLBAR_NEVER
406 && h
!= HORIZONTAL_SCROLLBAR_ALWAYS
)
407 throw new IllegalArgumentException("unknown horizontal scrollbar policy");
409 int old
= horizontalScrollBarPolicy
;
410 horizontalScrollBarPolicy
= h
;
411 firePropertyChange("horizontalScrollBarPolicy", old
, h
);
416 public void setLayout(LayoutManager l
)
418 LayoutManager old
= super.getLayout();
419 ScrollPaneLayout tmp
= (ScrollPaneLayout
) l
;
421 tmp
.syncWithScrollPane(this);
422 firePropertyChange("layout", old
, l
);
426 public void setRowHeader(JViewport v
)
431 JViewport old
= rowHeader
;
434 addNonNull(v
, JScrollPane
.ROW_HEADER
);
435 firePropertyChange("rowHeader", old
, v
);
439 public void setRowHeaderView(Component c
)
441 if (rowHeader
== null)
442 setRowHeader(createViewport());
443 rowHeader
.setView(c
);
447 public void setVerticalScrollBar(JScrollBar v
)
449 if (verticalScrollBar
== v
)
452 JScrollBar old
= verticalScrollBar
;
454 verticalScrollBar
= v
;
455 addNonNull(v
, JScrollPane
.VERTICAL_SCROLLBAR
);
456 firePropertyChange("verticalScrollBar", old
, v
);
460 public void setVerticalScrollBarPolicy(int v
)
462 if (verticalScrollBarPolicy
== v
)
465 if (v
!= VERTICAL_SCROLLBAR_AS_NEEDED
466 && v
!= VERTICAL_SCROLLBAR_NEVER
467 && v
!= VERTICAL_SCROLLBAR_ALWAYS
)
468 throw new IllegalArgumentException("unknown vertical scrollbar policy");
470 int old
= verticalScrollBarPolicy
;
471 verticalScrollBarPolicy
= v
;
472 firePropertyChange("verticalScrollBarPolicy", old
, v
);
477 public void setWheelScrollingEnabled(boolean b
)
479 if (wheelScrollingEnabled
== b
)
482 boolean old
= wheelScrollingEnabled
;
483 wheelScrollingEnabled
= b
;
484 firePropertyChange("wheelScrollingEnabled", old
, b
);
488 public void setViewport(JViewport v
)
493 JViewport old
= viewport
;
496 addNonNull(v
, JScrollPane
.VIEWPORT
);
499 firePropertyChange("viewport", old
, v
);
501 if (accessibleContext
!= null)
503 AccessibleJScrollPane asp
= (AccessibleJScrollPane
) accessibleContext
;
508 public void setViewportBorder(Border b
)
510 if (viewportBorder
== b
)
513 Border old
= viewportBorder
;
515 firePropertyChange("viewportBorder", old
, b
);
519 public void setViewportView(Component view
)
521 if (getViewport() == null)
523 setViewport(createViewport());
528 getViewport().setView(view
);
533 public boolean isValidateRoot()
539 * Creates a new <code>JScrollPane</code> without a view. The scrollbar
540 * policy is set to {@link #VERTICAL_SCROLLBAR_AS_NEEDED} and
541 * {@link #HORIZONTAL_SCROLLBAR_AS_NEEDED}.
549 * Creates a new <code>JScrollPane</code> that embeds the specified
550 * <code>view</code> component, displaying vertical and horizontal scrollbars
553 * @param view the component that is embedded inside the JScrollPane
555 public JScrollPane(Component view
)
558 VERTICAL_SCROLLBAR_AS_NEEDED
,
559 HORIZONTAL_SCROLLBAR_AS_NEEDED
);
563 * Creates a new <code>JScrollPane</code> without a view; The scrollbar
564 * policies are set to <code>vsbPolicy</code> and <code>hsbPolicy</code>.
566 * @param vsbPolicy the vertical scrollbar policy to set
567 * @param hsbPolicy the vertical scrollbar policy to set
569 * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS
570 * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED
571 * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER
572 * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS
573 * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED
574 * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER
576 public JScrollPane(int vsbPolicy
, int hsbPolicy
)
578 this(null, vsbPolicy
, hsbPolicy
);
582 * Creates a new <code>JScrollPane</code> that embeds the specified
583 * <code>view</code> component; The scrollbar
584 * policies are set to <code>vsbPolicy</code> and <code>hsbPolicy</code>.
586 * @param vsbPolicy the vertical scrollbar policy to set
587 * @param hsbPolicy the vertical scrollbar policy to set
589 * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_ALWAYS
590 * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_AS_NEEDED
591 * @see ScrollPaneConstants#HORIZONTAL_SCROLLBAR_NEVER
592 * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_ALWAYS
593 * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_AS_NEEDED
594 * @see ScrollPaneConstants#VERTICAL_SCROLLBAR_NEVER
596 public JScrollPane(Component view
, int vsbPolicy
, int hsbPolicy
)
598 setVerticalScrollBarPolicy(vsbPolicy
);
599 setVerticalScrollBar(createVerticalScrollBar());
600 setHorizontalScrollBarPolicy(hsbPolicy
);
601 setHorizontalScrollBar(createHorizontalScrollBar());
602 viewport
= createViewport();
604 getViewport().setView(view
);
606 setLayout(new ScrollPaneLayout());
612 public JScrollBar
createHorizontalScrollBar()
614 return new ScrollBar(SwingConstants
.HORIZONTAL
);
617 public JScrollBar
createVerticalScrollBar()
619 return new ScrollBar(SwingConstants
.VERTICAL
);
622 protected JViewport
createViewport()
624 return new JViewport();
627 public String
getUIClassID()
629 return "ScrollPaneUI";
632 public void updateUI()
634 ScrollPaneUI b
= (ScrollPaneUI
)UIManager
.getUI(this);
639 * This method returns the scrollpane's UI delegate.
641 * @return The scrollpane's UI delegate.
643 public ScrollPaneUI
getUI()
645 return (ScrollPaneUI
) ui
;
649 * This method sets the scrollpane's UI delegate.
651 * @param ui The scrollpane's UI delegate.
653 public void setUI(ScrollPaneUI ui
)
658 protected class ScrollBar
660 implements UIResource
662 private static final long serialVersionUID
= -42032395320987283L;
664 public ScrollBar(int orientation
)
669 public int getBlockIncrement(int direction
)
671 Component view
= JScrollPane
.this.getViewport().getView();
672 if (view
== null || (! (view
instanceof Scrollable
)))
673 return super.getBlockIncrement(direction
);
676 Scrollable s
= (Scrollable
) view
;
677 return s
.getScrollableBlockIncrement(JScrollPane
.this.getViewport().getViewRect(),
678 this.getOrientation(),
683 public int getUnitIncrement(int direction
)
685 Component view
= JScrollPane
.this.getViewport().getView();
686 if (view
== null || (! (view
instanceof Scrollable
)))
687 return super.getUnitIncrement(direction
);
690 Scrollable s
= (Scrollable
) view
;
691 return s
.getScrollableUnitIncrement(JScrollPane
.this.getViewport().getViewRect(),
692 this.getOrientation(),
699 * Returns the accessible context associated with this
700 * <code>JScrollPane</code>.
702 * @return the accessible context associated with this
703 * <code>JScrollPane</code>
705 public AccessibleContext
getAccessibleContext()
707 if (accessibleContext
== null)
708 accessibleContext
= new AccessibleJScrollPane();
709 return accessibleContext
;