1:
37:
38:
39: package ;
40:
41: import ;
42:
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55:
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77:
78:
81: public class BasicScrollPaneUI extends ScrollPaneUI
82: implements ScrollPaneConstants
83: {
84:
85:
91: public class HSBChangeListener implements ChangeListener
92: {
93:
94:
100: public void stateChanged(ChangeEvent event)
101: {
102: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
103: JViewport vp = scrollpane.getViewport();
104: Point viewPosition = vp.getViewPosition();
105: int xpos = hsb.getValue();
106:
107: if (xpos != viewPosition.x)
108: {
109: viewPosition.x = xpos;
110: vp.setViewPosition(viewPosition);
111: }
112:
113: viewPosition.y = 0;
114: JViewport columnHeader = scrollpane.getColumnHeader();
115: if (columnHeader != null
116: && !columnHeader.getViewPosition().equals(viewPosition))
117: columnHeader.setViewPosition(viewPosition);
118: }
119:
120: }
121:
122:
128: public class VSBChangeListener implements ChangeListener
129: {
130:
131:
137: public void stateChanged(ChangeEvent event)
138: {
139: JScrollBar vsb = scrollpane.getVerticalScrollBar();
140: JViewport vp = scrollpane.getViewport();
141: Point viewPosition = vp.getViewPosition();
142: int ypos = vsb.getValue();
143: if (ypos != viewPosition.y)
144: {
145: viewPosition.y = ypos;
146: vp.setViewPosition(viewPosition);
147: }
148:
149: viewPosition.x = 0;
150: JViewport rowHeader = scrollpane.getRowHeader();
151: if (rowHeader != null
152: && !rowHeader.getViewPosition().equals(viewPosition))
153: rowHeader.setViewPosition(viewPosition);
154: }
155:
156: }
157:
158:
164: public class ViewportChangeHandler implements ChangeListener
165: {
166:
167:
175: public void stateChanged(ChangeEvent event)
176: {
177: JViewport vp = scrollpane.getViewport();
178: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
179: JScrollBar vsb = scrollpane.getVerticalScrollBar();
180: syncScrollPaneWithViewport();
181: }
182:
183: }
184:
185:
191: public class PropertyChangeHandler implements PropertyChangeListener
192: {
193:
194:
206: public void propertyChange(PropertyChangeEvent e)
207: {
208: String propName = e.getPropertyName();
209: if (propName.equals("viewport"))
210: updateViewport(e);
211: else if (propName.equals("rowHeader"))
212: updateRowHeader(e);
213: else if (propName.equals("columnHeader"))
214: updateColumnHeader(e);
215: else if (propName.equals("horizontalScrollBarPolicy")
216: || e.getPropertyName().equals("verticalScrollBarPolicy"))
217: updateScrollBarDisplayPolicy(e);
218: else if (propName.equals("verticalScrollBar"))
219: {
220: JScrollBar oldSb = (JScrollBar) e.getOldValue();
221: oldSb.getModel().removeChangeListener(vsbChangeListener);
222: JScrollBar newSb = (JScrollBar) e.getNewValue();
223: newSb.getModel().addChangeListener(vsbChangeListener);
224: }
225: else if (propName.equals("horizontalScrollBar"))
226: {
227: JScrollBar oldSb = (JScrollBar) e.getOldValue();
228: oldSb.getModel().removeChangeListener(hsbChangeListener);
229: JScrollBar newSb = (JScrollBar) e.getNewValue();
230: newSb.getModel().addChangeListener(hsbChangeListener);
231: }
232: }
233:
234: }
235:
236:
243: protected class MouseWheelHandler implements MouseWheelListener
244: {
245:
248: final Rectangle rect = new Rectangle();
249:
250:
255: public void mouseWheelMoved(MouseWheelEvent e)
256: {
257: if (scrollpane.getViewport().getComponentCount() == 0)
258: return;
259:
260: Component target = scrollpane.getViewport().getComponent(0);
261: JScrollBar bar = scrollpane.getVerticalScrollBar();
262: Scrollable scrollable = (target instanceof Scrollable) ? (Scrollable) target
263: : null;
264:
265: boolean tracksHeight = scrollable != null
266: && scrollable.getScrollableTracksViewportHeight();
267: int wheel = e.getWheelRotation() * ROWS_PER_WHEEL_CLICK;
268: int delta;
269:
270:
271: if (bar != null && ! tracksHeight)
272: {
273: if (scrollable != null)
274: {
275: bounds(target);
276: delta = scrollable.getScrollableUnitIncrement(
277: rect, SwingConstants.VERTICAL, wheel);
278: }
279: else
280: {
281:
282: delta = wheel * SCROLL_NON_SCROLLABLES;
283: }
284: scroll(bar, delta);
285: }
286:
287: else
288: {
289: bar = scrollpane.getHorizontalScrollBar();
290: boolean tracksWidth = scrollable != null
291: && scrollable.getScrollableTracksViewportWidth();
292:
293: if (bar != null && ! tracksWidth)
294: {
295: if (scrollable != null)
296: {
297: bounds(target);
298: delta = scrollable.getScrollableUnitIncrement(
299: rect, SwingConstants.HORIZONTAL, wheel);
300: }
301: else
302: {
303:
304: delta = wheel * SCROLL_NON_SCROLLABLES;
305: }
306: scroll(bar, delta);
307: }
308: }
309: }
310:
311:
317: final void bounds(Component target)
318: {
319:
320: target.getParent().getBounds(rect);
321: rect.x = getValue(scrollpane.getHorizontalScrollBar());
322: rect.y = getValue(scrollpane.getVerticalScrollBar());
323: }
324:
325:
332: final int getValue(JScrollBar bar)
333: {
334: return bar != null ? bar.getValue() : 0;
335: }
336:
337:
343: final void scroll(JScrollBar bar, int delta)
344: {
345: int y = bar.getValue() + delta;
346:
347: if (y < bar.getMinimum())
348: y = bar.getMinimum();
349: if (y > bar.getMaximum())
350: y = bar.getMaximum();
351:
352: bar.setValue(y);
353: }
354: }
355:
356:
362: class ViewportContainerListener implements ContainerListener
363: {
364:
367: public void componentAdded(ContainerEvent e)
368: {
369: e.getChild().addMouseWheelListener(mouseWheelListener);
370: }
371:
372:
375: public void componentRemoved(ContainerEvent e)
376: {
377: e.getChild().removeMouseWheelListener(mouseWheelListener);
378: }
379: }
380:
381:
385: static int SCROLL_NON_SCROLLABLES = 10;
386:
387:
391: static int ROWS_PER_WHEEL_CLICK = 3;
392:
393:
394: protected JScrollPane scrollpane;
395:
396:
399: protected ChangeListener hsbChangeListener;
400:
401:
404: protected ChangeListener vsbChangeListener;
405:
406:
409: protected ChangeListener viewportChangeListener;
410:
411:
414: protected PropertyChangeListener spPropertyChangeListener;
415:
416:
419: MouseWheelListener mouseWheelListener;
420:
421:
425: ContainerListener containerListener;
426:
427: public static ComponentUI createUI(final JComponent c)
428: {
429: return new BasicScrollPaneUI();
430: }
431:
432: protected void installDefaults(JScrollPane p)
433: {
434: scrollpane = p;
435: LookAndFeel.installColorsAndFont(p, "ScrollPane.background",
436: "ScrollPane.foreground",
437: "ScrollPane.font");
438: LookAndFeel.installBorder(p, "ScrollPane.border");
439: p.setOpaque(true);
440: }
441:
442: protected void uninstallDefaults(JScrollPane p)
443: {
444: p.setForeground(null);
445: p.setBackground(null);
446: p.setFont(null);
447: p.setBorder(null);
448: scrollpane = null;
449: }
450:
451: public void installUI(final JComponent c)
452: {
453: super.installUI(c);
454: installDefaults((JScrollPane) c);
455: installListeners((JScrollPane) c);
456: installKeyboardActions((JScrollPane) c);
457: }
458:
459:
464: protected void installListeners(JScrollPane sp)
465: {
466: if (spPropertyChangeListener == null)
467: spPropertyChangeListener = createPropertyChangeListener();
468: sp.addPropertyChangeListener(spPropertyChangeListener);
469:
470: if (hsbChangeListener == null)
471: hsbChangeListener = createHSBChangeListener();
472: sp.getHorizontalScrollBar().getModel().addChangeListener(hsbChangeListener);
473:
474: if (vsbChangeListener == null)
475: vsbChangeListener = createVSBChangeListener();
476: sp.getVerticalScrollBar().getModel().addChangeListener(vsbChangeListener);
477:
478: if (viewportChangeListener == null)
479: viewportChangeListener = createViewportChangeListener();
480:
481: if (mouseWheelListener == null)
482: mouseWheelListener = createMouseWheelListener();
483:
484: if (containerListener == null)
485: containerListener = new ViewportContainerListener();
486:
487: JViewport v = sp.getViewport();
488: v.addChangeListener(viewportChangeListener);
489: v.addContainerListener(containerListener);
490:
491:
492:
493: for (int i = 0; i < v.getComponentCount(); i++)
494: v.getComponent(i).addMouseWheelListener(mouseWheelListener);
495: }
496:
497: InputMap getInputMap(int condition)
498: {
499: if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
500: return (InputMap) UIManager.get("ScrollPane.ancestorInputMap");
501: return null;
502: }
503:
504:
511: ActionMap getActionMap()
512: {
513: ActionMap map = (ActionMap) UIManager.get("ScrollPane.actionMap");
514:
515: if (map == null)
516: {
517: map = createActionMap();
518: if (map != null)
519: UIManager.put("ScrollPane.actionMap", map);
520: }
521: return map;
522: }
523:
524:
534: ActionMap createActionMap()
535: {
536: ActionMap map = new ActionMapUIResource();
537: map.put("scrollLeft",
538: new AbstractAction("scrollLeft") {
539: public void actionPerformed(ActionEvent event)
540: {
541: JScrollPane sp = (JScrollPane) event.getSource();
542: JScrollBar sb = sp.getHorizontalScrollBar();
543: if (sb.isVisible())
544: {
545: int delta = sb.getBlockIncrement(-1);
546: sb.setValue(sb.getValue() + delta);
547: }
548: }
549: }
550: );
551: map.put("scrollEnd",
552: new AbstractAction("scrollEnd") {
553: public void actionPerformed(ActionEvent event)
554: {
555: JScrollPane sp = (JScrollPane) event.getSource();
556: JScrollBar sb1 = sp.getHorizontalScrollBar();
557: if (sb1.isVisible())
558: {
559: sb1.setValue(sb1.getMaximum());
560: }
561: JScrollBar sb2 = sp.getVerticalScrollBar();
562: if (sb2.isVisible())
563: {
564: sb2.setValue(sb2.getMaximum());
565: }
566: }
567: }
568: );
569: map.put("unitScrollUp",
570: new AbstractAction("unitScrollUp") {
571: public void actionPerformed(ActionEvent event)
572: {
573: JScrollPane sp = (JScrollPane) event.getSource();
574: JScrollBar sb = sp.getVerticalScrollBar();
575: if (sb.isVisible())
576: {
577: int delta = sb.getUnitIncrement(-1);
578: sb.setValue(sb.getValue() + delta);
579: }
580: }
581: }
582: );
583: map.put("unitScrollLeft",
584: new AbstractAction("unitScrollLeft") {
585: public void actionPerformed(ActionEvent event)
586: {
587: JScrollPane sp = (JScrollPane) event.getSource();
588: JScrollBar sb = sp.getHorizontalScrollBar();
589: if (sb.isVisible())
590: {
591: int delta = sb.getUnitIncrement(-1);
592: sb.setValue(sb.getValue() + delta);
593: }
594: }
595: }
596: );
597: map.put("scrollUp",
598: new AbstractAction("scrollUp") {
599: public void actionPerformed(ActionEvent event)
600: {
601: JScrollPane sp = (JScrollPane) event.getSource();
602: JScrollBar sb = sp.getVerticalScrollBar();
603: if (sb.isVisible())
604: {
605: int delta = sb.getBlockIncrement(-1);
606: sb.setValue(sb.getValue() + delta);
607: }
608: }
609: }
610: );
611: map.put("scrollRight",
612: new AbstractAction("scrollRight") {
613: public void actionPerformed(ActionEvent event)
614: {
615: JScrollPane sp = (JScrollPane) event.getSource();
616: JScrollBar sb = sp.getHorizontalScrollBar();
617: if (sb.isVisible())
618: {
619: int delta = sb.getBlockIncrement(1);
620: sb.setValue(sb.getValue() + delta);
621: }
622: }
623: }
624: );
625: map.put("scrollHome",
626: new AbstractAction("scrollHome") {
627: public void actionPerformed(ActionEvent event)
628: {
629: JScrollPane sp = (JScrollPane) event.getSource();
630: JScrollBar sb1 = sp.getHorizontalScrollBar();
631: if (sb1.isVisible())
632: {
633: sb1.setValue(sb1.getMinimum());
634: }
635: JScrollBar sb2 = sp.getVerticalScrollBar();
636: if (sb2.isVisible())
637: {
638: sb2.setValue(sb2.getMinimum());
639: }
640: }
641: }
642: );
643: map.put("scrollDown",
644: new AbstractAction("scrollDown") {
645: public void actionPerformed(ActionEvent event)
646: {
647: JScrollPane sp = (JScrollPane) event.getSource();
648: JScrollBar sb = sp.getVerticalScrollBar();
649: if (sb.isVisible())
650: {
651: int delta = sb.getBlockIncrement(1);
652: sb.setValue(sb.getValue() + delta);
653: }
654: }
655: }
656: );
657: map.put("unitScrollDown",
658: new AbstractAction("unitScrollDown") {
659: public void actionPerformed(ActionEvent event)
660: {
661: JScrollPane sp = (JScrollPane) event.getSource();
662: JScrollBar sb = sp.getVerticalScrollBar();
663: if (sb.isVisible())
664: {
665: int delta = sb.getUnitIncrement(1);
666: sb.setValue(sb.getValue() + delta);
667: }
668: }
669: }
670: );
671: map.put("unitScrollRight",
672: new AbstractAction("unitScrollRight") {
673: public void actionPerformed(ActionEvent event)
674: {
675: JScrollPane sp = (JScrollPane) event.getSource();
676: JScrollBar sb = sp.getHorizontalScrollBar();
677: if (sb.isVisible())
678: {
679: int delta = sb.getUnitIncrement(1);
680: sb.setValue(sb.getValue() + delta);
681: }
682: }
683: }
684: );
685: return map;
686: }
687:
688:
695: protected void installKeyboardActions(JScrollPane sp)
696: {
697: InputMap keyMap = getInputMap(
698: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
699: SwingUtilities.replaceUIInputMap(sp,
700: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);
701: ActionMap map = getActionMap();
702: SwingUtilities.replaceUIActionMap(sp, map);
703: }
704:
705:
712: protected void uninstallKeyboardActions(JScrollPane sp)
713: {
714: SwingUtilities.replaceUIActionMap(sp, null);
715: SwingUtilities.replaceUIInputMap(sp,
716: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
717: }
718:
719:
724: protected ChangeListener createHSBChangeListener()
725: {
726: return new HSBChangeListener();
727: }
728:
729:
734: protected ChangeListener createVSBChangeListener()
735: {
736: return new VSBChangeListener();
737: }
738:
739:
744: protected ChangeListener createViewportChangeListener()
745: {
746: return new ViewportChangeHandler();
747: }
748:
749:
754: protected PropertyChangeListener createPropertyChangeListener()
755: {
756: return new PropertyChangeHandler();
757: }
758:
759:
766: protected MouseWheelListener createMouseWheelListener()
767: {
768: return new MouseWheelHandler();
769: }
770:
771: public void uninstallUI(final JComponent c)
772: {
773: super.uninstallUI(c);
774: this.uninstallDefaults((JScrollPane) c);
775: uninstallListeners((JScrollPane) c);
776: installKeyboardActions((JScrollPane) c);
777: }
778:
779:
785: protected void uninstallListeners(JComponent c)
786: {
787: JScrollPane sp = (JScrollPane) c;
788: sp.removePropertyChangeListener(spPropertyChangeListener);
789: sp.getHorizontalScrollBar().getModel()
790: .removeChangeListener(hsbChangeListener);
791: sp.getVerticalScrollBar().getModel()
792: .removeChangeListener(vsbChangeListener);
793:
794: JViewport v = sp.getViewport();
795: v.removeChangeListener(viewportChangeListener);
796: v.removeContainerListener(containerListener);
797:
798: for (int i = 0; i < v.getComponentCount(); i++)
799: v.getComponent(i).removeMouseWheelListener(mouseWheelListener);
800:
801: }
802:
803: public Dimension getMinimumSize(JComponent c)
804: {
805: JScrollPane p = (JScrollPane) c;
806: ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
807: return sl.minimumLayoutSize(c);
808: }
809:
810: public void paint(Graphics g, JComponent c)
811: {
812:
813:
814: }
815:
816:
819: protected void syncScrollPaneWithViewport()
820: {
821: JViewport vp = scrollpane.getViewport();
822:
823:
824: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
825: hsb.setMaximum(vp.getViewSize().width);
826: hsb.setValue(vp.getViewPosition().x);
827: hsb.setVisibleAmount(vp.getExtentSize().width);
828:
829:
830: JScrollBar vsb = scrollpane.getVerticalScrollBar();
831: vsb.setMaximum(vp.getViewSize().height);
832: vsb.setValue(vp.getViewPosition().y);
833: vsb.setVisibleAmount(vp.getExtentSize().height);
834: }
835:
836:
842: protected void updateColumnHeader(PropertyChangeEvent ev)
843: {
844:
845: }
846:
847:
853: protected void updateRowHeader(PropertyChangeEvent ev)
854: {
855:
856: }
857:
858:
864: protected void updateScrollBarDisplayPolicy(PropertyChangeEvent ev)
865: {
866:
867: }
868:
869:
878: protected void updateViewport(PropertyChangeEvent ev)
879: {
880: JViewport oldViewport = (JViewport) ev.getOldValue();
881: oldViewport.removeChangeListener(viewportChangeListener);
882: JViewport newViewport = (JViewport) ev.getNewValue();
883: newViewport.addChangeListener(viewportChangeListener);
884: syncScrollPaneWithViewport();
885: }
886: }
887:
888:
889:
890:
891:
892:
893:
894:
895:
896:
897: