KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > basic > BasicScrollPaneUI


1 /*
2  * @(#)BasicScrollPaneUI.java 1.70 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing.plaf.basic;
9
10 import sun.swing.DefaultLookup;
11 import sun.swing.UIAction;
12
13 import javax.swing.*;
14 import javax.swing.event.*;
15 import javax.swing.border.*;
16 import javax.swing.plaf.*;
17
18 import java.beans.PropertyChangeListener JavaDoc;
19 import java.beans.PropertyChangeEvent JavaDoc;
20
21 import java.awt.Component JavaDoc;
22 import java.awt.Container JavaDoc;
23 import java.awt.LayoutManager JavaDoc;
24 import java.awt.Rectangle JavaDoc;
25 import java.awt.Dimension JavaDoc;
26 import java.awt.Point JavaDoc;
27 import java.awt.Insets JavaDoc;
28 import java.awt.Graphics JavaDoc;
29 import java.awt.event.*;
30 import java.io.Serializable JavaDoc;
31 import java.awt.Toolkit JavaDoc;
32
33 /**
34  * A default L&F implementation of ScrollPaneUI.
35  *
36  * @version 1.70 12/19/03
37  * @author Hans Muller
38  */

39 public class BasicScrollPaneUI
40     extends ScrollPaneUI implements ScrollPaneConstants
41 {
42     protected JScrollPane scrollpane;
43     protected ChangeListener JavaDoc vsbChangeListener;
44     protected ChangeListener JavaDoc hsbChangeListener;
45     protected ChangeListener JavaDoc viewportChangeListener;
46     protected PropertyChangeListener JavaDoc spPropertyChangeListener;
47     private MouseWheelListener mouseScrollListener;
48
49     /**
50      * PropertyChangeListener installed on the vertical scrollbar.
51      */

52     private PropertyChangeListener JavaDoc vsbPropertyChangeListener;
53
54     /**
55      * PropertyChangeListener installed on the horizontal scrollbar.
56      */

57     private PropertyChangeListener JavaDoc hsbPropertyChangeListener;
58
59     private Handler handler;
60
61     /**
62      * State flag that shows whether setValue() was called from a user program
63      * before the value of "extent" was set in right-to-left component
64      * orientation.
65      */

66     private boolean setValueCalled = false;
67
68
69     public static ComponentUI createUI(JComponent x) {
70     return new BasicScrollPaneUI JavaDoc();
71     }
72
73     static void loadActionMap(LazyActionMap JavaDoc map) {
74         map.put(new Actions(Actions.SCROLL_UP));
75     map.put(new Actions(Actions.SCROLL_DOWN));
76     map.put(new Actions(Actions.SCROLL_HOME));
77     map.put(new Actions(Actions.SCROLL_END));
78     map.put(new Actions(Actions.UNIT_SCROLL_UP));
79     map.put(new Actions(Actions.UNIT_SCROLL_DOWN));
80         map.put(new Actions(Actions.SCROLL_LEFT));
81         map.put(new Actions(Actions.SCROLL_RIGHT));
82         map.put(new Actions(Actions.UNIT_SCROLL_RIGHT));
83         map.put(new Actions(Actions.UNIT_SCROLL_LEFT));
84     }
85
86
87
88     public void paint(Graphics JavaDoc g, JComponent c) {
89     Border vpBorder = scrollpane.getViewportBorder();
90     if (vpBorder != null) {
91         Rectangle JavaDoc r = scrollpane.getViewportBorderBounds();
92         vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
93     }
94     }
95
96
97     /**
98      * @return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)
99      */

100     public Dimension JavaDoc getMaximumSize(JComponent c) {
101     return new Dimension JavaDoc(Short.MAX_VALUE, Short.MAX_VALUE);
102     }
103
104
105     protected void installDefaults(JScrollPane scrollpane)
106     {
107     LookAndFeel.installBorder(scrollpane, "ScrollPane.border");
108     LookAndFeel.installColorsAndFont(scrollpane,
109         "ScrollPane.background",
110         "ScrollPane.foreground",
111             "ScrollPane.font");
112
113         Border vpBorder = scrollpane.getViewportBorder();
114         if ((vpBorder == null) ||( vpBorder instanceof UIResource)) {
115         vpBorder = UIManager.getBorder("ScrollPane.viewportBorder");
116         scrollpane.setViewportBorder(vpBorder);
117         }
118         LookAndFeel.installProperty(scrollpane, "opaque", Boolean.TRUE);
119     }
120
121
122     protected void installListeners(JScrollPane c)
123     {
124     vsbChangeListener = createVSBChangeListener();
125         vsbPropertyChangeListener = createVSBPropertyChangeListener();
126     hsbChangeListener = createHSBChangeListener();
127         hsbPropertyChangeListener = createHSBPropertyChangeListener();
128     viewportChangeListener = createViewportChangeListener();
129     spPropertyChangeListener = createPropertyChangeListener();
130
131     JViewport viewport = scrollpane.getViewport();
132     JScrollBar vsb = scrollpane.getVerticalScrollBar();
133     JScrollBar hsb = scrollpane.getHorizontalScrollBar();
134
135     if (viewport != null) {
136         viewport.addChangeListener(viewportChangeListener);
137     }
138     if (vsb != null) {
139         vsb.getModel().addChangeListener(vsbChangeListener);
140             vsb.addPropertyChangeListener(vsbPropertyChangeListener);
141     }
142     if (hsb != null) {
143         hsb.getModel().addChangeListener(hsbChangeListener);
144             hsb.addPropertyChangeListener(hsbPropertyChangeListener);
145     }
146
147     scrollpane.addPropertyChangeListener(spPropertyChangeListener);
148
149     mouseScrollListener = createMouseWheelListener();
150     scrollpane.addMouseWheelListener(mouseScrollListener);
151
152     }
153
154     protected void installKeyboardActions(JScrollPane c) {
155     InputMap inputMap = getInputMap(JComponent.
156                   WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
157
158     SwingUtilities.replaceUIInputMap(c, JComponent.
159                    WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap);
160
161         LazyActionMap.installLazyActionMap(c, BasicScrollPaneUI JavaDoc.class,
162                                            "ScrollPane.actionMap");
163     }
164
165     InputMap getInputMap(int condition) {
166     if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
167         InputMap keyMap = (InputMap)DefaultLookup.get(scrollpane, this,
168                                         "ScrollPane.ancestorInputMap");
169         InputMap rtlKeyMap;
170
171         if (scrollpane.getComponentOrientation().isLeftToRight() ||
172             ((rtlKeyMap = (InputMap)DefaultLookup.get(scrollpane, this,
173                     "ScrollPane.ancestorInputMap.RightToLeft")) == null)) {
174         return keyMap;
175         } else {
176         rtlKeyMap.setParent(keyMap);
177         return rtlKeyMap;
178         }
179     }
180     return null;
181     }
182
183     public void installUI(JComponent x) {
184     scrollpane = (JScrollPane)x;
185     installDefaults(scrollpane);
186     installListeners(scrollpane);
187     installKeyboardActions(scrollpane);
188     }
189
190
191     protected void uninstallDefaults(JScrollPane c) {
192     LookAndFeel.uninstallBorder(scrollpane);
193
194         if (scrollpane.getViewportBorder() instanceof UIResource) {
195             scrollpane.setViewportBorder(null);
196         }
197     }
198
199
200     protected void uninstallListeners(JComponent c) {
201     JViewport viewport = scrollpane.getViewport();
202     JScrollBar vsb = scrollpane.getVerticalScrollBar();
203     JScrollBar hsb = scrollpane.getHorizontalScrollBar();
204
205     if (viewport != null) {
206         viewport.removeChangeListener(viewportChangeListener);
207     }
208     if (vsb != null) {
209         vsb.getModel().removeChangeListener(vsbChangeListener);
210             vsb.removePropertyChangeListener(vsbPropertyChangeListener);
211     }
212     if (hsb != null) {
213         hsb.getModel().removeChangeListener(hsbChangeListener);
214             hsb.removePropertyChangeListener(hsbPropertyChangeListener);
215     }
216
217     scrollpane.removePropertyChangeListener(spPropertyChangeListener);
218
219     if (mouseScrollListener != null) {
220         scrollpane.removeMouseWheelListener(mouseScrollListener);
221     }
222
223     vsbChangeListener = null;
224     hsbChangeListener = null;
225     viewportChangeListener = null;
226     spPropertyChangeListener = null;
227         mouseScrollListener = null;
228         handler = null;
229     }
230
231
232     protected void uninstallKeyboardActions(JScrollPane c) {
233     SwingUtilities.replaceUIActionMap(c, null);
234     SwingUtilities.replaceUIInputMap(c, JComponent.
235                WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
236     }
237
238
239     public void uninstallUI(JComponent c) {
240     uninstallDefaults(scrollpane);
241     uninstallListeners(scrollpane);
242     uninstallKeyboardActions(scrollpane);
243     scrollpane = null;
244     }
245
246     private Handler getHandler() {
247         if (handler == null) {
248             handler = new Handler();
249         }
250         return handler;
251     }
252
253     protected void syncScrollPaneWithViewport()
254     {
255     JViewport viewport = scrollpane.getViewport();
256     JScrollBar vsb = scrollpane.getVerticalScrollBar();
257     JScrollBar hsb = scrollpane.getHorizontalScrollBar();
258     JViewport rowHead = scrollpane.getRowHeader();
259     JViewport colHead = scrollpane.getColumnHeader();
260     boolean ltr = scrollpane.getComponentOrientation().isLeftToRight();
261
262     if (viewport != null) {
263         Dimension JavaDoc extentSize = viewport.getExtentSize();
264         Dimension JavaDoc viewSize = viewport.getViewSize();
265         Point JavaDoc viewPosition = viewport.getViewPosition();
266
267         if (vsb != null) {
268         int extent = extentSize.height;
269         int max = viewSize.height;
270         int value = Math.max(0, Math.min(viewPosition.y, max - extent));
271         vsb.setValues(value, extent, 0, max);
272         }
273
274         if (hsb != null) {
275         int extent = extentSize.width;
276         int max = viewSize.width;
277         int value;
278
279         if (ltr) {
280             value = Math.max(0, Math.min(viewPosition.x, max - extent));
281         } else {
282             int currentValue = hsb.getValue();
283
284             /* Use a particular formula to calculate "value"
285              * until effective x coordinate is calculated.
286              */

287             if (setValueCalled && ((max - currentValue) == viewPosition.x)) {
288             value = Math.max(0, Math.min(max - extent, currentValue));
289             /* After "extent" is set, turn setValueCalled flag off.
290              */

291             if (extent != 0) {
292                 setValueCalled = false;
293             }
294             } else {
295             if (extent > max) {
296                 viewPosition.x = max - extent;
297                 viewport.setViewPosition(viewPosition);
298                 value = 0;
299             } else {
300                /* The following line can't handle a small value of
301                 * viewPosition.x like Integer.MIN_VALUE correctly
302                 * because (max - extent - viewPositoiin.x) causes
303                 * an overflow. As a result, value becomes zero.
304                 * (e.g. setViewPosition(Integer.MAX_VALUE, ...)
305                 * in a user program causes a overflow.
306                 * Its expected value is (max - extent).)
307                 * However, this seems a trivial bug and adding a
308                 * fix makes this often-called method slow, so I'll
309                 * leave it until someone claims.
310                 */

311                 value = Math.max(0, Math.min(max - extent, max - extent - viewPosition.x));
312             }
313             }
314         }
315         hsb.setValues(value, extent, 0, max);
316         }
317
318         if (rowHead != null) {
319         Point JavaDoc p = rowHead.getViewPosition();
320         p.y = viewport.getViewPosition().y;
321                 p.x = 0;
322         rowHead.setViewPosition(p);
323         }
324
325         if (colHead != null) {
326         Point JavaDoc p = colHead.getViewPosition();
327         if (ltr) {
328             p.x = viewport.getViewPosition().x;
329         } else {
330             p.x = Math.max(0, viewport.getViewPosition().x);
331         }
332                 p.y = 0;
333         colHead.setViewPosition(p);
334         }
335     }
336     }
337
338
339     /**
340      * Listener for viewport events.
341      */

342     public class ViewportChangeHandler implements ChangeListener JavaDoc
343     {
344
345         // NOTE: This class exists only for backward compatability. All
346
// its functionality has been moved into Handler. If you need to add
347
// new functionality add it to the Handler, but make sure this
348
// class calls into the Handler.
349

350     public void stateChanged(ChangeEvent JavaDoc e) {
351             getHandler().stateChanged(e);
352     }
353     }
354
355     protected ChangeListener JavaDoc createViewportChangeListener() {
356     return getHandler();
357     }
358
359
360     /**
361      * Horizontal scrollbar listener.
362      */

363     public class HSBChangeListener implements ChangeListener JavaDoc
364     {
365
366         // NOTE: This class exists only for backward compatability. All
367
// its functionality has been moved into Handler. If you need to add
368
// new functionality add it to the Handler, but make sure this
369
// class calls into the Handler.
370

371     public void stateChanged(ChangeEvent JavaDoc e)
372     {
373             getHandler().stateChanged(e);
374     }
375     }
376
377     /**
378      * Returns a <code>PropertyChangeListener</code> that will be installed
379      * on the horizontal <code>JScrollBar</code>.
380      */

381     private PropertyChangeListener JavaDoc createHSBPropertyChangeListener() {
382         return getHandler();
383     }
384
385     protected ChangeListener JavaDoc createHSBChangeListener() {
386     return getHandler();
387     }
388
389
390     /**
391      * Vertical scrollbar listener.
392      */

393     public class VSBChangeListener implements ChangeListener JavaDoc
394     {
395
396         // NOTE: This class exists only for backward compatability. All
397
// its functionality has been moved into Handler. If you need to add
398
// new functionality add it to the Handler, but make sure this
399
// class calls into the Handler.
400

401     public void stateChanged(ChangeEvent JavaDoc e)
402     {
403             getHandler().stateChanged(e);
404     }
405     }
406
407
408     /**
409      * Returns a <code>PropertyChangeListener</code> that will be installed
410      * on the vertical <code>JScrollBar</code>.
411      */

412     private PropertyChangeListener JavaDoc createVSBPropertyChangeListener() {
413         return getHandler();
414     }
415
416     protected ChangeListener JavaDoc createVSBChangeListener() {
417     return getHandler();
418     }
419
420     /**
421      * MouseWheelHandler is an inner class which implements the
422      * MouseWheelListener interface. MouseWheelHandler responds to
423      * MouseWheelEvents by scrolling the JScrollPane appropriately.
424      * If the scroll pane's
425      * <code>isWheelScrollingEnabled</code>
426      * method returns false, no scrolling occurs.
427      *
428      * @see javax.swing.JScrollPane#isWheelScrollingEnabled
429      * @see #createMouseWheelListener
430      * @see java.awt.event.MouseWheelListener
431      * @see java.awt.event.MouseWheelEvent
432      * @since 1.4
433      */

434     protected class MouseWheelHandler implements MouseWheelListener {
435
436         // NOTE: This class exists only for backward compatability. All
437
// its functionality has been moved into Handler. If you need to add
438
// new functionality add it to the Handler, but make sure this
439
// class calls into the Handler.
440

441         /**
442          * Called when the mouse wheel is rotated while over a
443          * JScrollPane.
444          *
445          * @param e MouseWheelEvent to be handled
446          * @since 1.4
447          */

448         public void mouseWheelMoved(MouseWheelEvent e) {
449             getHandler().mouseWheelMoved(e);
450         }
451     }
452
453     /**
454      * Creates an instance of MouseWheelListener, which is added to the
455      * JScrollPane by installUI(). The returned MouseWheelListener is used
456      * to handle mouse wheel-driven scrolling.
457      *
458      * @return MouseWheelListener which implements wheel-driven scrolling
459      * @see #installUI
460      * @see MouseWheelHandler
461      * @since 1.4
462      */

463     protected MouseWheelListener createMouseWheelListener() {
464         return getHandler();
465     }
466
467     protected void updateScrollBarDisplayPolicy(PropertyChangeEvent JavaDoc e) {
468     scrollpane.revalidate();
469     scrollpane.repaint();
470     }
471
472
473     protected void updateViewport(PropertyChangeEvent JavaDoc e)
474     {
475     JViewport oldViewport = (JViewport)(e.getOldValue());
476     JViewport newViewport = (JViewport)(e.getNewValue());
477
478     if (oldViewport != null) {
479         oldViewport.removeChangeListener(viewportChangeListener);
480     }
481     
482     if (newViewport != null) {
483         Point JavaDoc p = newViewport.getViewPosition();
484         if (scrollpane.getComponentOrientation().isLeftToRight()) {
485         p.x = Math.max(p.x, 0);
486         } else {
487         int max = newViewport.getViewSize().width;
488         int extent = newViewport.getExtentSize().width;
489         if (extent > max) {
490             p.x = max - extent;
491         } else {
492             p.x = Math.max(0, Math.min(max - extent, p.x));
493         }
494         }
495         p.y = Math.max(p.y, 0);
496         newViewport.setViewPosition(p);
497         newViewport.addChangeListener(viewportChangeListener);
498     }
499     }
500
501
502     protected void updateRowHeader(PropertyChangeEvent JavaDoc e)
503     {
504     JViewport newRowHead = (JViewport)(e.getNewValue());
505     if (newRowHead != null) {
506         JViewport viewport = scrollpane.getViewport();
507         Point JavaDoc p = newRowHead.getViewPosition();
508         p.y = (viewport != null) ? viewport.getViewPosition().y : 0;
509         newRowHead.setViewPosition(p);
510     }
511     }
512
513
514     protected void updateColumnHeader(PropertyChangeEvent JavaDoc e)
515     {
516     JViewport newColHead = (JViewport)(e.getNewValue());
517     if (newColHead != null) {
518         JViewport viewport = scrollpane.getViewport();
519         Point JavaDoc p = newColHead.getViewPosition();
520         if (viewport == null) {
521         p.x = 0;
522         } else {
523         if (scrollpane.getComponentOrientation().isLeftToRight()) {
524             p.x = viewport.getViewPosition().x;
525         } else {
526             p.x = Math.max(0, viewport.getViewPosition().x);
527         }
528         }
529         newColHead.setViewPosition(p);
530         scrollpane.add(newColHead, COLUMN_HEADER);
531     }
532     }
533
534     private void updateHorizontalScrollBar(PropertyChangeEvent JavaDoc pce) {
535     updateScrollBar(pce, hsbChangeListener, hsbPropertyChangeListener);
536     }
537
538     private void updateVerticalScrollBar(PropertyChangeEvent JavaDoc pce) {
539     updateScrollBar(pce, vsbChangeListener, vsbPropertyChangeListener);
540     }
541
542     private void updateScrollBar(PropertyChangeEvent JavaDoc pce, ChangeListener JavaDoc cl,
543                                  PropertyChangeListener JavaDoc pcl) {
544         JScrollBar sb = (JScrollBar)pce.getOldValue();
545         if (sb != null) {
546             if (cl != null) {
547                 sb.getModel().removeChangeListener(cl);
548             }
549             if (pcl != null) {
550                 sb.removePropertyChangeListener(pcl);
551             }
552         }
553         sb = (JScrollBar)pce.getNewValue();
554         if (sb != null) {
555             if (cl != null) {
556                 sb.getModel().addChangeListener(cl);
557             }
558             if (pcl != null) {
559                 sb.addPropertyChangeListener(pcl);
560             }
561     }
562     }
563
564     public class PropertyChangeHandler implements PropertyChangeListener JavaDoc
565     {
566
567         // NOTE: This class exists only for backward compatability. All
568
// its functionality has been moved into Handler. If you need to add
569
// new functionality add it to the Handler, but make sure this
570
// class calls into the Handler.
571

572         public void propertyChange(PropertyChangeEvent JavaDoc e)
573         {
574             getHandler().propertyChange(e);
575     }
576     }
577
578
579
580     /**
581      * Creates an instance of PropertyChangeListener that's added to
582      * the JScrollPane by installUI(). Subclasses can override this method
583      * to return a custom PropertyChangeListener, e.g.
584      * <pre>
585      * class MyScrollPaneUI extends BasicScrollPaneUI {
586      * protected PropertyChangeListener <b>createPropertyChangeListener</b>() {
587      * return new MyPropertyChangeListener();
588      * }
589      * public class MyPropertyChangeListener extends PropertyChangeListener {
590      * public void propertyChange(PropertyChangeEvent e) {
591      * if (e.getPropertyName().equals("viewport")) {
592      * // do some extra work when the viewport changes
593      * }
594      * super.propertyChange(e);
595      * }
596      * }
597      * }
598      * </pre>
599      *
600      * @see java.beans.PropertyChangeListener
601      * @see #installUI
602      */

603     protected PropertyChangeListener JavaDoc createPropertyChangeListener() {
604         return getHandler();
605     }
606
607
608     private static class Actions extends UIAction {
609         private static final String JavaDoc SCROLL_UP = "scrollUp";
610         private static final String JavaDoc SCROLL_DOWN = "scrollDown";
611         private static final String JavaDoc SCROLL_HOME = "scrollHome";
612         private static final String JavaDoc SCROLL_END = "scrollEnd";
613         private static final String JavaDoc UNIT_SCROLL_UP = "unitScrollUp";
614         private static final String JavaDoc UNIT_SCROLL_DOWN = "unitScrollDown";
615         private static final String JavaDoc SCROLL_LEFT = "scrollLeft";
616         private static final String JavaDoc SCROLL_RIGHT = "scrollRight";
617         private static final String JavaDoc UNIT_SCROLL_LEFT = "unitScrollLeft";
618         private static final String JavaDoc UNIT_SCROLL_RIGHT = "unitScrollRight";
619
620
621         Actions(String JavaDoc key) {
622             super(key);
623         }
624
625         public void actionPerformed(ActionEvent e) {
626             JScrollPane scrollPane = (JScrollPane)e.getSource();
627             boolean ltr = scrollPane.getComponentOrientation().isLeftToRight();
628             String JavaDoc key = getName();
629
630             if (key == SCROLL_UP) {
631                 scroll(scrollPane, SwingConstants.VERTICAL, -1, true);
632             }
633             else if (key == SCROLL_DOWN) {
634                 scroll(scrollPane, SwingConstants.VERTICAL, 1, true);
635             }
636             else if (key == SCROLL_HOME) {
637                 scrollHome(scrollPane);
638             }
639             else if (key == SCROLL_END) {
640                 scrollEnd(scrollPane);
641             }
642             else if (key == UNIT_SCROLL_UP) {
643                 scroll(scrollPane, SwingConstants.VERTICAL, -1, false);
644             }
645             else if (key == UNIT_SCROLL_DOWN) {
646                 scroll(scrollPane, SwingConstants.VERTICAL, 1, false);
647             }
648             else if (key == SCROLL_LEFT) {
649                 scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? -1 : 1,
650                        true);
651             }
652             else if (key == SCROLL_RIGHT) {
653                 scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? 1 : -1,
654                        true);
655             }
656             else if (key == UNIT_SCROLL_LEFT) {
657                 scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? -1 : 1,
658                        false);
659             }
660             else if (key == UNIT_SCROLL_RIGHT) {
661                 scroll(scrollPane, SwingConstants.HORIZONTAL, ltr ? 1 : -1,
662                        false);
663             }
664         }
665
666         private void scrollEnd(JScrollPane scrollpane) {
667         JViewport vp = scrollpane.getViewport();
668         Component JavaDoc view;
669         if (vp != null && (view = vp.getView()) != null) {
670         Rectangle JavaDoc visRect = vp.getViewRect();
671         Rectangle JavaDoc bounds = view.getBounds();
672         if (scrollpane.getComponentOrientation().isLeftToRight()) {
673             vp.setViewPosition(new Point JavaDoc(bounds.width - visRect.width,
674                          bounds.height - visRect.height));
675         } else {
676             vp.setViewPosition(new Point JavaDoc(0,
677                          bounds.height - visRect.height));
678         }
679         }
680         }
681
682         private void scrollHome(JScrollPane scrollpane) {
683         JViewport vp = scrollpane.getViewport();
684         Component JavaDoc view;
685         if (vp != null && (view = vp.getView()) != null) {
686         if (scrollpane.getComponentOrientation().isLeftToRight()) {
687             vp.setViewPosition(new Point JavaDoc(0, 0));
688         } else {
689             Rectangle JavaDoc visRect = vp.getViewRect();
690             Rectangle JavaDoc bounds = view.getBounds();
691             vp.setViewPosition(new Point JavaDoc(bounds.width - visRect.width, 0));
692         }
693             }
694         }
695
696     private void scroll(JScrollPane scrollpane, int orientation,
697                             int direction, boolean block) {
698         JViewport vp = scrollpane.getViewport();
699         Component JavaDoc view;
700         if (vp != null && (view = vp.getView()) != null) {
701         Rectangle JavaDoc visRect = vp.getViewRect();
702         Dimension JavaDoc vSize = view.getSize();
703         int amount;
704
705         if (view instanceof Scrollable) {
706             if (block) {
707             amount = ((Scrollable)view).getScrollableBlockIncrement
708                      (visRect, orientation, direction);
709             }
710             else {
711             amount = ((Scrollable)view).getScrollableUnitIncrement
712                      (visRect, orientation, direction);
713             }
714         }
715         else {
716             if (block) {
717             if (orientation == SwingConstants.VERTICAL) {
718                 amount = visRect.height;
719             }
720             else {
721                 amount = visRect.width;
722             }
723             }
724             else {
725             amount = 10;
726             }
727         }
728         if (orientation == SwingConstants.VERTICAL) {
729             visRect.y += (amount * direction);
730             if ((visRect.y + visRect.height) > vSize.height) {
731             visRect.y = Math.max(0, vSize.height - visRect.height);
732             }
733             else if (visRect.y < 0) {
734             visRect.y = 0;
735             }
736         }
737         else {
738             if (scrollpane.getComponentOrientation().isLeftToRight()) {
739             visRect.x += (amount * direction);
740             if ((visRect.x + visRect.width) > vSize.width) {
741                 visRect.x = Math.max(0, vSize.width - visRect.width);
742             } else if (visRect.x < 0) {
743                 visRect.x = 0;
744             }
745             } else {
746             visRect.x -= (amount * direction);
747                         if (visRect.width > vSize.width) {
748                             visRect.x = vSize.width - visRect.width;
749                         } else {
750                             visRect.x = Math.max(0, Math.min(vSize.width - visRect.width, visRect.x));
751             }
752             }
753         }
754         vp.setViewPosition(visRect.getLocation());
755         }
756     }
757     }
758
759
760     class Handler implements ChangeListener JavaDoc, PropertyChangeListener JavaDoc, MouseWheelListener {
761         //
762
// MouseWheelListener
763
//
764
public void mouseWheelMoved(MouseWheelEvent e) {
765             if (scrollpane.isWheelScrollingEnabled() &&
766                 e.getScrollAmount() != 0) {
767                 JScrollBar toScroll = scrollpane.getVerticalScrollBar();
768                 int direction = 0;
769                 // find which scrollbar to scroll, or return if none
770
if (toScroll == null || !toScroll.isVisible()) {
771                     toScroll = scrollpane.getHorizontalScrollBar();
772                     if (toScroll == null || !toScroll.isVisible()) {
773                         return;
774                     }
775                 }
776                 direction = e.getWheelRotation() < 0 ? -1 : 1;
777                 if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
778                     BasicScrollBarUI.scrollByUnits(toScroll, direction,
779                                                          e.getScrollAmount());
780                 }
781                 else if (e.getScrollType() ==
782                          MouseWheelEvent.WHEEL_BLOCK_SCROLL) {
783                     BasicScrollBarUI.scrollByBlock(toScroll, direction);
784                 }
785             }
786         }
787
788
789         //
790
// ChangeListener: This is added to the vieport, and hsb/vsb models.
791
//
792
public void stateChanged(ChangeEvent JavaDoc e) {
793             JViewport viewport = scrollpane.getViewport();
794
795             if (viewport != null) {
796                 if (e.getSource() == viewport) {
797                     viewportStateChanged(e);
798                 }
799                 else {
800                     JScrollBar hsb = scrollpane.getHorizontalScrollBar();
801                     if (hsb != null && e.getSource() == hsb.getModel()) {
802                         hsbStateChanged(viewport, e);
803                     }
804                     else {
805                         JScrollBar vsb = scrollpane.getVerticalScrollBar();
806                         if (vsb != null && e.getSource() == vsb.getModel()) {
807                             vsbStateChanged(viewport, e);
808                         }
809                     }
810                 }
811             }
812         }
813
814         private void vsbStateChanged(JViewport viewport, ChangeEvent JavaDoc e) {
815             BoundedRangeModel model = (BoundedRangeModel)(e.getSource());
816             Point JavaDoc p = viewport.getViewPosition();
817             p.y = model.getValue();
818             viewport.setViewPosition(p);
819         }
820
821         private void hsbStateChanged(JViewport viewport, ChangeEvent JavaDoc e) {
822             BoundedRangeModel model = (BoundedRangeModel)(e.getSource());
823             Point JavaDoc p = viewport.getViewPosition();
824             int value = model.getValue();
825             if (scrollpane.getComponentOrientation().isLeftToRight()) {
826                 p.x = value;
827             } else {
828                 int max = viewport.getViewSize().width;
829                 int extent = viewport.getExtentSize().width;
830                 int oldX = p.x;
831
832                 /* Set new X coordinate based on "value".
833                  */

834                 p.x = max - extent - value;
835
836                 /* If setValue() was called before "extent" was fixed,
837                  * turn setValueCalled flag on.
838                  */

839                 if ((extent == 0) && (value != 0) && (oldX == max)) {
840                     setValueCalled = true;
841                 } else {
842                     /* When a pane without a horizontal scroll bar was
843                      * reduced and the bar appeared, the viewport should
844                      * show the right side of the view.
845                      */

846                     if ((extent != 0) && (oldX < 0) && (p.x == 0)) {
847                         p.x += value;
848                     }
849                 }
850             }
851             viewport.setViewPosition(p);
852         }
853
854         private void viewportStateChanged(ChangeEvent JavaDoc e) {
855             syncScrollPaneWithViewport();
856     }
857
858
859         //
860
// PropertyChangeListener: This is installed on both the JScrollPane
861
// and the horizontal/vertical scrollbars.
862
//
863

864         // Listens for changes in the model property and reinstalls the
865
// horizontal/vertical PropertyChangeListeners.
866
public void propertyChange(PropertyChangeEvent JavaDoc e) {
867             if (e.getSource() == scrollpane) {
868                 scrollPanePropertyChange(e);
869             }
870             else {
871                 sbPropertyChange(e);
872             }
873         }
874
875         private void scrollPanePropertyChange(PropertyChangeEvent JavaDoc e) {
876             String JavaDoc propertyName = e.getPropertyName();
877
878         if (propertyName == "verticalScrollBarDisplayPolicy") {
879         updateScrollBarDisplayPolicy(e);
880         }
881         else if (propertyName == "horizontalScrollBarDisplayPolicy") {
882         updateScrollBarDisplayPolicy(e);
883         }
884         else if (propertyName == "viewport") {
885         updateViewport(e);
886         }
887         else if (propertyName == "rowHeader") {
888         updateRowHeader(e);
889         }
890         else if (propertyName == "columnHeader") {
891         updateColumnHeader(e);
892         }
893         else if (propertyName == "verticalScrollBar") {
894         updateVerticalScrollBar(e);
895         }
896         else if (propertyName == "horizontalScrollBar") {
897         updateHorizontalScrollBar(e);
898         }
899         else if (propertyName == "componentOrientation") {
900         scrollpane.revalidate();
901         scrollpane.repaint();
902         }
903         }
904
905         // PropertyChangeListener for the horizontal and vertical scrollbars.
906
private void sbPropertyChange(PropertyChangeEvent JavaDoc e) {
907             String JavaDoc propertyName = e.getPropertyName();
908             Object JavaDoc source = e.getSource();
909
910             if ("model" == propertyName) {
911                 JScrollBar sb = scrollpane.getVerticalScrollBar();
912                 BoundedRangeModel oldModel = (BoundedRangeModel)e.
913                                      getOldValue();
914                 ChangeListener JavaDoc cl = null;
915
916                 if (source == sb) {
917                     cl = vsbChangeListener;
918                 }
919                 else if (source == scrollpane.getHorizontalScrollBar()) {
920                     sb = scrollpane.getHorizontalScrollBar();
921                     cl = hsbChangeListener;
922                 }
923                 if (cl != null) {
924                     if (oldModel != null) {
925                         oldModel.removeChangeListener(cl);
926                     }
927                     if (sb.getModel() != null) {
928                         sb.getModel().addChangeListener(cl);
929                     }
930                 }
931             }
932             else if ("componentOrientation" == propertyName) {
933                 if (source == scrollpane.getHorizontalScrollBar()) {
934             JScrollBar hsb = scrollpane.getHorizontalScrollBar();
935             JViewport viewport = scrollpane.getViewport();
936                     Point JavaDoc p = viewport.getViewPosition();
937                     if (scrollpane.getComponentOrientation().isLeftToRight()) {
938                         p.x = hsb.getValue();
939                     } else {
940                         p.x = viewport.getViewSize().width - viewport.getExtentSize().width - hsb.getValue();
941                     }
942                     viewport.setViewPosition(p);
943                 }
944             }
945         }
946     }
947 }
948
Popular Tags