Merge from mainline.
[official-gcc.git] / libjava / classpath / javax / swing / JScrollPane.java
blob09e37378be98227fc6fd1c826ae9cfac42c01888
1 /* JScrollPane.java --
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)
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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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 javax.swing;
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;
57 /**
58 * A component that embeds another component and enables it to be scrolled
59 * both in horizontal and vertical direction.
61 * <table>
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>
79 * </table>
81 public class JScrollPane extends JComponent
82 implements Accessible, ScrollPaneConstants
84 /**
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
93 /**
94 * The viewport of the underlying scrollpane.
96 protected JViewport viewPort;
98 /**
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
136 * correctly.
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()
170 return columnHeader;
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)
200 return lowerRight;
201 else if (key == UPPER_RIGHT_CORNER)
202 return upperRight;
203 else if (key == LOWER_LEFT_CORNER)
204 return lowerLeft;
205 else if (key == UPPER_LEFT_CORNER)
206 return upperLeft;
207 return null;
210 public JScrollBar getHorizontalScrollBar()
212 return horizontalScrollBar;
215 public int getHorizontalScrollBarPolicy()
217 return horizontalScrollBarPolicy;
220 public JViewport getRowHeader()
222 return rowHeader;
225 public JScrollBar getVerticalScrollBar()
227 return verticalScrollBar;
230 public int getVerticalScrollBarPolicy()
232 return verticalScrollBarPolicy;
235 public JViewport getViewport()
237 return viewport;
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);
251 else
252 return getViewport().getBounds();
254 else
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);
260 else
262 Rectangle b = getViewport().getBounds();
263 return new Rectangle(b.x - i.left,
264 b.y - i.top,
265 b.width + i.left + i.right,
266 b.height + i.top + i.bottom);
271 public boolean isWheelScrollingEnabled()
273 return wheelScrollingEnabled;
278 private void sync()
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)
290 if (c != null)
291 remove(c);
294 private void addNonNull(Component c, Object constraints)
296 if (c != null)
297 add(c, constraints);
300 public void setComponentOrientation(ComponentOrientation co)
302 ComponentOrientation old = super.getComponentOrientation();
303 super.setComponentOrientation(co);
304 firePropertyChange("componentOrientation", old, co);
305 sync();
308 public void setColumnHeader(JViewport h)
310 if (columnHeader == h)
311 return;
313 JViewport old = columnHeader;
314 removeNonNull(old);
315 columnHeader = h;
316 addNonNull(h, JScrollPane.COLUMN_HEADER);
317 firePropertyChange("columnHeader", old, h);
318 sync();
321 public void setColumnHeaderView(Component c)
323 if (columnHeader == null)
324 setColumnHeader(createViewport());
325 columnHeader.setView(c);
326 sync();
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);
359 lowerRight = c;
360 addNonNull(c, JScrollPane.LOWER_RIGHT_CORNER);
362 else if (key == UPPER_RIGHT_CORNER)
364 removeNonNull(upperRight);
365 upperRight = c;
366 addNonNull(c, JScrollPane.UPPER_RIGHT_CORNER);
368 else if (key == LOWER_LEFT_CORNER)
370 removeNonNull(lowerLeft);
371 lowerLeft = c;
372 addNonNull(c, JScrollPane.LOWER_LEFT_CORNER);
374 else if (key == UPPER_LEFT_CORNER)
376 removeNonNull(upperLeft);
377 upperLeft = c;
378 addNonNull(c, JScrollPane.UPPER_LEFT_CORNER);
380 else
381 throw new IllegalArgumentException("unknown corner " + key);
382 sync();
385 public void setHorizontalScrollBar(JScrollBar h)
387 if (horizontalScrollBar == h)
388 return;
390 JScrollBar old = horizontalScrollBar;
391 removeNonNull(old);
392 horizontalScrollBar = h;
393 addNonNull(h, JScrollPane.HORIZONTAL_SCROLLBAR);
394 firePropertyChange("horizontalScrollBar", old, h);
395 sync();
399 public void setHorizontalScrollBarPolicy(int h)
401 if (horizontalScrollBarPolicy == h)
402 return;
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);
412 sync();
413 revalidate();
416 public void setLayout(LayoutManager l)
418 LayoutManager old = super.getLayout();
419 ScrollPaneLayout tmp = (ScrollPaneLayout) l;
420 super.setLayout(l);
421 tmp.syncWithScrollPane(this);
422 firePropertyChange("layout", old, l);
423 sync();
426 public void setRowHeader(JViewport v)
428 if (rowHeader == v)
429 return;
431 JViewport old = rowHeader;
432 removeNonNull(old);
433 rowHeader = v;
434 addNonNull(v, JScrollPane.ROW_HEADER);
435 firePropertyChange("rowHeader", old, v);
436 sync();
439 public void setRowHeaderView(Component c)
441 if (rowHeader == null)
442 setRowHeader(createViewport());
443 rowHeader.setView(c);
444 sync();
447 public void setVerticalScrollBar(JScrollBar v)
449 if (verticalScrollBar == v)
450 return;
452 JScrollBar old = verticalScrollBar;
453 removeNonNull(old);
454 verticalScrollBar = v;
455 addNonNull(v, JScrollPane.VERTICAL_SCROLLBAR);
456 firePropertyChange("verticalScrollBar", old, v);
457 sync();
460 public void setVerticalScrollBarPolicy(int v)
462 if (verticalScrollBarPolicy == v)
463 return;
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);
473 sync();
474 revalidate();
477 public void setWheelScrollingEnabled(boolean b)
479 if (wheelScrollingEnabled == b)
480 return;
482 boolean old = wheelScrollingEnabled;
483 wheelScrollingEnabled = b;
484 firePropertyChange("wheelScrollingEnabled", old, b);
485 sync();
488 public void setViewport(JViewport v)
490 if (viewport == v)
491 return;
493 JViewport old = viewport;
494 removeNonNull(old);
495 viewport = v;
496 addNonNull(v, JScrollPane.VIEWPORT);
497 revalidate();
498 repaint();
499 firePropertyChange("viewport", old, v);
500 sync();
501 if (accessibleContext != null)
503 AccessibleJScrollPane asp = (AccessibleJScrollPane) accessibleContext;
504 asp.resetViewPort();
508 public void setViewportBorder(Border b)
510 if (viewportBorder == b)
511 return;
513 Border old = viewportBorder;
514 viewportBorder = b;
515 firePropertyChange("viewportBorder", old, b);
516 sync();
519 public void setViewportView(Component view)
521 if (getViewport() == null)
523 setViewport(createViewport());
526 if (view != null)
528 getViewport().setView(view);
530 sync();
533 public boolean isValidateRoot()
535 return true;
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}.
543 public JScrollPane()
545 this(null);
549 * Creates a new <code>JScrollPane</code> that embeds the specified
550 * <code>view</code> component, displaying vertical and horizontal scrollbars
551 * as needed.
553 * @param view the component that is embedded inside the JScrollPane
555 public JScrollPane(Component view)
557 this(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();
603 if (view != null)
604 getViewport().setView(view);
605 add(viewport,0);
606 setLayout(new ScrollPaneLayout());
607 setOpaque(false);
608 updateUI();
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 setUI((ScrollPaneUI) UIManager.getUI(this));
638 * This method returns the scrollpane's UI delegate.
640 * @return The scrollpane's UI delegate.
642 public ScrollPaneUI getUI()
644 return (ScrollPaneUI) ui;
648 * This method sets the scrollpane's UI delegate.
650 * @param ui The scrollpane's UI delegate.
652 public void setUI(ScrollPaneUI ui)
654 super.setUI(ui);
657 protected class ScrollBar
658 extends JScrollBar
659 implements UIResource
661 private static final long serialVersionUID = -42032395320987283L;
663 public ScrollBar(int orientation)
665 super(orientation);
668 public int getBlockIncrement(int direction)
670 Component view = JScrollPane.this.getViewport().getView();
671 if (view == null || (! (view instanceof Scrollable)))
672 return super.getBlockIncrement(direction);
673 else
675 Scrollable s = (Scrollable) view;
676 return s.getScrollableBlockIncrement(JScrollPane.this.getViewport().getViewRect(),
677 this.getOrientation(),
678 direction);
682 public int getUnitIncrement(int direction)
684 Component view = JScrollPane.this.getViewport().getView();
685 if (view == null || (! (view instanceof Scrollable)))
686 return super.getUnitIncrement(direction);
687 else
689 Scrollable s = (Scrollable) view;
690 return s.getScrollableUnitIncrement(JScrollPane.this.getViewport().getViewRect(),
691 this.getOrientation(),
692 direction);
698 * Returns the accessible context associated with this
699 * <code>JScrollPane</code>.
701 * @return the accessible context associated with this
702 * <code>JScrollPane</code>
704 public AccessibleContext getAccessibleContext()
706 if (accessibleContext == null)
707 accessibleContext = new AccessibleJScrollPane();
708 return accessibleContext;