1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52:
53: import ;
54: import ;
55: import ;
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:
74:
77: public class BasicScrollPaneUI extends ScrollPaneUI
78: implements ScrollPaneConstants
79: {
80:
81:
87: public class HSBChangeListener implements ChangeListener
88: {
89:
90:
96: public void stateChanged(ChangeEvent event)
97: {
98: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
99: JViewport vp = scrollpane.getViewport();
100: Point viewPosition = vp.getViewPosition();
101: viewPosition.x = hsb.getValue();
102: vp.setViewPosition(viewPosition);
103: }
104:
105: }
106:
107:
113: public class VSBChangeListener implements ChangeListener
114: {
115:
116:
122: public void stateChanged(ChangeEvent event)
123: {
124: JScrollBar vsb = scrollpane.getVerticalScrollBar();
125: JViewport vp = scrollpane.getViewport();
126: Point viewPosition = vp.getViewPosition();
127: viewPosition.y = vsb.getValue();
128: vp.setViewPosition(viewPosition);
129: }
130:
131: }
132:
133:
139: public class ViewportChangeHandler implements ChangeListener
140: {
141:
142:
150: public void stateChanged(ChangeEvent event)
151: {
152: syncScrollPaneWithViewport();
153: }
154:
155: }
156:
157:
163: public class PropertyChangeHandler implements PropertyChangeListener
164: {
165:
166:
178: public void propertyChange(PropertyChangeEvent e)
179: {
180: String propName = e.getPropertyName();
181: if (propName.equals("viewport"))
182: updateViewport(e);
183: else if (propName.equals("rowHeader"))
184: updateRowHeader(e);
185: else if (propName.equals("columnHeader"))
186: updateColumnHeader(e);
187: else if (propName.equals("horizontalScrollBarPolicy")
188: || e.getPropertyName().equals("verticalScrollBarPolicy"))
189: updateScrollBarDisplayPolicy(e);
190: else if (propName.equals("verticalScrollBar"))
191: {
192: JScrollBar oldSb = (JScrollBar) e.getOldValue();
193: oldSb.getModel().removeChangeListener(vsbChangeListener);
194: JScrollBar newSb = (JScrollBar) e.getNewValue();
195: newSb.getModel().addChangeListener(vsbChangeListener);
196: }
197: else if (propName.equals("horizontalScrollBar"))
198: {
199: JScrollBar oldSb = (JScrollBar) e.getOldValue();
200: oldSb.getModel().removeChangeListener(hsbChangeListener);
201: JScrollBar newSb = (JScrollBar) e.getNewValue();
202: newSb.getModel().addChangeListener(hsbChangeListener);
203: }
204: }
205:
206: }
207:
208:
215: protected class MouseWheelHandler implements MouseWheelListener
216: {
217:
220: final Rectangle rect = new Rectangle();
221:
222:
227: public void mouseWheelMoved(MouseWheelEvent e)
228: {
229: if (scrollpane.isWheelScrollingEnabled() && e.getScrollAmount() != 0)
230: {
231:
232: JScrollBar scrollBar = scrollpane.getVerticalScrollBar();
233: if (scrollBar == null || ! scrollBar.isVisible())
234: scrollBar = scrollpane.getHorizontalScrollBar();
235: if (scrollBar != null && scrollBar.isVisible())
236: {
237: int direction = e.getWheelRotation() < 0 ? -1 : 1;
238: int scrollType = e.getScrollType();
239: if (scrollType == MouseWheelEvent.WHEEL_UNIT_SCROLL)
240: BasicScrollBarUI.scrollByUnits(scrollBar, direction,
241: e.getScrollAmount());
242: else if (scrollType == MouseWheelEvent.WHEEL_BLOCK_SCROLL)
243: BasicScrollBarUI.scrollByBlock(scrollBar, direction);
244: }
245: }
246: }
247: }
248:
249:
255: class ViewportContainerListener implements ContainerListener
256: {
257:
260: public void componentAdded(ContainerEvent e)
261: {
262: e.getChild().addMouseWheelListener(mouseWheelListener);
263: }
264:
265:
268: public void componentRemoved(ContainerEvent e)
269: {
270: e.getChild().removeMouseWheelListener(mouseWheelListener);
271: }
272: }
273:
274:
278: static int SCROLL_NON_SCROLLABLES = 10;
279:
280:
284: static int ROWS_PER_WHEEL_CLICK = 3;
285:
286:
287: protected JScrollPane scrollpane;
288:
289:
292: protected ChangeListener hsbChangeListener;
293:
294:
297: protected ChangeListener vsbChangeListener;
298:
299:
302: protected ChangeListener viewportChangeListener;
303:
304:
307: protected PropertyChangeListener spPropertyChangeListener;
308:
309:
312: MouseWheelListener mouseWheelListener;
313:
314:
318: ContainerListener containerListener;
319:
320: public static ComponentUI createUI(final JComponent c)
321: {
322: return new BasicScrollPaneUI();
323: }
324:
325: protected void installDefaults(JScrollPane p)
326: {
327: scrollpane = p;
328: LookAndFeel.installColorsAndFont(p, "ScrollPane.background",
329: "ScrollPane.foreground",
330: "ScrollPane.font");
331: LookAndFeel.installBorder(p, "ScrollPane.border");
332:
333:
334: Border vpBorder = p.getViewportBorder();
335: if (vpBorder == null || vpBorder instanceof UIResource)
336: {
337: vpBorder = UIManager.getBorder("ScrollPane.viewportBorder");
338: p.setViewportBorder(vpBorder);
339: }
340:
341: p.setOpaque(true);
342: }
343:
344: protected void uninstallDefaults(JScrollPane p)
345: {
346: LookAndFeel.uninstallBorder(p);
347: Border vpBorder = p.getViewportBorder();
348: if (vpBorder != null && vpBorder instanceof UIResource)
349: p.setViewportBorder(null);
350: }
351:
352: public void installUI(final JComponent c)
353: {
354: super.installUI(c);
355: installDefaults((JScrollPane) c);
356: installListeners((JScrollPane) c);
357: installKeyboardActions((JScrollPane) c);
358: }
359:
360:
365: protected void installListeners(JScrollPane sp)
366: {
367: if (spPropertyChangeListener == null)
368: spPropertyChangeListener = createPropertyChangeListener();
369: sp.addPropertyChangeListener(spPropertyChangeListener);
370:
371: if (hsbChangeListener == null)
372: hsbChangeListener = createHSBChangeListener();
373: sp.getHorizontalScrollBar().getModel().addChangeListener(hsbChangeListener);
374:
375: if (vsbChangeListener == null)
376: vsbChangeListener = createVSBChangeListener();
377: sp.getVerticalScrollBar().getModel().addChangeListener(vsbChangeListener);
378:
379: if (viewportChangeListener == null)
380: viewportChangeListener = createViewportChangeListener();
381:
382: if (mouseWheelListener == null)
383: mouseWheelListener = createMouseWheelListener();
384:
385: if (containerListener == null)
386: containerListener = new ViewportContainerListener();
387:
388: JViewport v = sp.getViewport();
389: v.addChangeListener(viewportChangeListener);
390: v.addContainerListener(containerListener);
391:
392:
393:
394: for (int i = 0; i < v.getComponentCount(); i++)
395: v.getComponent(i).addMouseWheelListener(mouseWheelListener);
396: }
397:
398: InputMap getInputMap(int condition)
399: {
400: if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
401: return (InputMap) UIManager.get("ScrollPane.ancestorInputMap");
402: return null;
403: }
404:
405:
412: ActionMap getActionMap()
413: {
414: ActionMap map = (ActionMap) UIManager.get("ScrollPane.actionMap");
415:
416: if (map == null)
417: {
418: map = createActionMap();
419: if (map != null)
420: UIManager.put("ScrollPane.actionMap", map);
421: }
422: return map;
423: }
424:
425:
435: ActionMap createActionMap()
436: {
437: ActionMap map = new ActionMapUIResource();
438: map.put("scrollLeft",
439: new AbstractAction("scrollLeft") {
440: public void actionPerformed(ActionEvent event)
441: {
442: JScrollPane sp = (JScrollPane) event.getSource();
443: JScrollBar sb = sp.getHorizontalScrollBar();
444: if (sb.isVisible())
445: {
446: int delta = sb.getBlockIncrement(-1);
447: sb.setValue(sb.getValue() + delta);
448: }
449: }
450: }
451: );
452: map.put("scrollEnd",
453: new AbstractAction("scrollEnd") {
454: public void actionPerformed(ActionEvent event)
455: {
456: JScrollPane sp = (JScrollPane) event.getSource();
457: JScrollBar sb1 = sp.getHorizontalScrollBar();
458: if (sb1.isVisible())
459: {
460: sb1.setValue(sb1.getMaximum());
461: }
462: JScrollBar sb2 = sp.getVerticalScrollBar();
463: if (sb2.isVisible())
464: {
465: sb2.setValue(sb2.getMaximum());
466: }
467: }
468: }
469: );
470: map.put("unitScrollUp",
471: new AbstractAction("unitScrollUp") {
472: public void actionPerformed(ActionEvent event)
473: {
474: JScrollPane sp = (JScrollPane) event.getSource();
475: JScrollBar sb = sp.getVerticalScrollBar();
476: if (sb.isVisible())
477: {
478: int delta = sb.getUnitIncrement(-1);
479: sb.setValue(sb.getValue() + delta);
480: }
481: }
482: }
483: );
484: map.put("unitScrollLeft",
485: new AbstractAction("unitScrollLeft") {
486: public void actionPerformed(ActionEvent event)
487: {
488: JScrollPane sp = (JScrollPane) event.getSource();
489: JScrollBar sb = sp.getHorizontalScrollBar();
490: if (sb.isVisible())
491: {
492: int delta = sb.getUnitIncrement(-1);
493: sb.setValue(sb.getValue() + delta);
494: }
495: }
496: }
497: );
498: map.put("scrollUp",
499: new AbstractAction("scrollUp") {
500: public void actionPerformed(ActionEvent event)
501: {
502: JScrollPane sp = (JScrollPane) event.getSource();
503: JScrollBar sb = sp.getVerticalScrollBar();
504: if (sb.isVisible())
505: {
506: int delta = sb.getBlockIncrement(-1);
507: sb.setValue(sb.getValue() + delta);
508: }
509: }
510: }
511: );
512: map.put("scrollRight",
513: new AbstractAction("scrollRight") {
514: public void actionPerformed(ActionEvent event)
515: {
516: JScrollPane sp = (JScrollPane) event.getSource();
517: JScrollBar sb = sp.getHorizontalScrollBar();
518: if (sb.isVisible())
519: {
520: int delta = sb.getBlockIncrement(1);
521: sb.setValue(sb.getValue() + delta);
522: }
523: }
524: }
525: );
526: map.put("scrollHome",
527: new AbstractAction("scrollHome") {
528: public void actionPerformed(ActionEvent event)
529: {
530: JScrollPane sp = (JScrollPane) event.getSource();
531: JScrollBar sb1 = sp.getHorizontalScrollBar();
532: if (sb1.isVisible())
533: {
534: sb1.setValue(sb1.getMinimum());
535: }
536: JScrollBar sb2 = sp.getVerticalScrollBar();
537: if (sb2.isVisible())
538: {
539: sb2.setValue(sb2.getMinimum());
540: }
541: }
542: }
543: );
544: map.put("scrollDown",
545: new AbstractAction("scrollDown") {
546: public void actionPerformed(ActionEvent event)
547: {
548: JScrollPane sp = (JScrollPane) event.getSource();
549: JScrollBar sb = sp.getVerticalScrollBar();
550: if (sb.isVisible())
551: {
552: int delta = sb.getBlockIncrement(1);
553: sb.setValue(sb.getValue() + delta);
554: }
555: }
556: }
557: );
558: map.put("unitScrollDown",
559: new AbstractAction("unitScrollDown") {
560: public void actionPerformed(ActionEvent event)
561: {
562: JScrollPane sp = (JScrollPane) event.getSource();
563: JScrollBar sb = sp.getVerticalScrollBar();
564: if (sb.isVisible())
565: {
566: int delta = sb.getUnitIncrement(1);
567: sb.setValue(sb.getValue() + delta);
568: }
569: }
570: }
571: );
572: map.put("unitScrollRight",
573: new AbstractAction("unitScrollRight") {
574: public void actionPerformed(ActionEvent event)
575: {
576: JScrollPane sp = (JScrollPane) event.getSource();
577: JScrollBar sb = sp.getHorizontalScrollBar();
578: if (sb.isVisible())
579: {
580: int delta = sb.getUnitIncrement(1);
581: sb.setValue(sb.getValue() + delta);
582: }
583: }
584: }
585: );
586: return map;
587: }
588:
589:
596: protected void installKeyboardActions(JScrollPane sp)
597: {
598: InputMap keyMap = getInputMap(
599: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
600: SwingUtilities.replaceUIInputMap(sp,
601: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);
602: ActionMap map = getActionMap();
603: SwingUtilities.replaceUIActionMap(sp, map);
604: }
605:
606:
613: protected void uninstallKeyboardActions(JScrollPane sp)
614: {
615: SwingUtilities.replaceUIActionMap(sp, null);
616: SwingUtilities.replaceUIInputMap(sp,
617: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
618: }
619:
620:
625: protected ChangeListener createHSBChangeListener()
626: {
627: return new HSBChangeListener();
628: }
629:
630:
635: protected ChangeListener createVSBChangeListener()
636: {
637: return new VSBChangeListener();
638: }
639:
640:
645: protected ChangeListener createViewportChangeListener()
646: {
647: return new ViewportChangeHandler();
648: }
649:
650:
655: protected PropertyChangeListener createPropertyChangeListener()
656: {
657: return new PropertyChangeHandler();
658: }
659:
660:
667: protected MouseWheelListener createMouseWheelListener()
668: {
669: return new MouseWheelHandler();
670: }
671:
672: public void uninstallUI(final JComponent c)
673: {
674: uninstallDefaults((JScrollPane) c);
675: uninstallListeners(c);
676: installKeyboardActions((JScrollPane) c);
677: }
678:
679:
685: protected void uninstallListeners(JComponent c)
686: {
687: JScrollPane sp = (JScrollPane) c;
688: sp.removePropertyChangeListener(spPropertyChangeListener);
689: sp.getHorizontalScrollBar().getModel()
690: .removeChangeListener(hsbChangeListener);
691: sp.getVerticalScrollBar().getModel()
692: .removeChangeListener(vsbChangeListener);
693:
694: JViewport v = sp.getViewport();
695: v.removeChangeListener(viewportChangeListener);
696: v.removeContainerListener(containerListener);
697:
698: for (int i = 0; i < v.getComponentCount(); i++)
699: v.getComponent(i).removeMouseWheelListener(mouseWheelListener);
700:
701: }
702:
703: public Dimension getMinimumSize(JComponent c)
704: {
705: JScrollPane p = (JScrollPane) c;
706: ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
707: return sl.minimumLayoutSize(c);
708: }
709:
710: public void paint(Graphics g, JComponent c)
711: {
712: Border vpBorder = scrollpane.getViewportBorder();
713: if (vpBorder != null)
714: {
715: Rectangle r = scrollpane.getViewportBorderBounds();
716: vpBorder.paintBorder(scrollpane, g, r.x, r.y, r.width, r.height);
717: }
718: }
719:
720:
724: protected void syncScrollPaneWithViewport()
725: {
726: JViewport vp = scrollpane.getViewport();
727:
728: if (vp != null)
729: {
730: Dimension extentSize = vp.getExtentSize();
731: Point viewPos = vp.getViewPosition();
732: Dimension viewSize = vp.getViewSize();
733:
734:
735: JScrollBar vsb = scrollpane.getVerticalScrollBar();
736: if (vsb != null)
737: {
738: int extent = extentSize.height;
739: int max = viewSize.height;
740: int val = Math.max(0, Math.min(viewPos.y, max - extent));
741: vsb.setValues(val, extent, 0, max);
742: }
743:
744:
745: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
746: if (hsb != null)
747: {
748: int extent = extentSize.width;
749: int max = viewSize.width;
750: int val = Math.max(0, Math.min(viewPos.x, max - extent));
751: hsb.setValues(val, extent, 0, max);
752: }
753:
754:
755: JViewport rowHeader = scrollpane.getRowHeader();
756: if (rowHeader != null)
757: {
758: Point p = new Point(0, viewPos.y);
759: rowHeader.setViewPosition(p);
760: }
761:
762:
763: JViewport colHeader = scrollpane.getColumnHeader();
764: if (colHeader != null)
765: {
766: Point p = new Point(viewPos.x, 0);
767: colHeader.setViewPosition(p);
768: }
769: }
770: }
771:
772:
778: protected void updateColumnHeader(PropertyChangeEvent ev)
779: {
780:
781: }
782:
783:
789: protected void updateRowHeader(PropertyChangeEvent ev)
790: {
791:
792: }
793:
794:
800: protected void updateScrollBarDisplayPolicy(PropertyChangeEvent ev)
801: {
802: scrollpane.revalidate();
803: scrollpane.repaint();
804: }
805:
806:
815: protected void updateViewport(PropertyChangeEvent ev)
816: {
817: JViewport oldViewport = (JViewport) ev.getOldValue();
818: oldViewport.removeChangeListener(viewportChangeListener);
819: JViewport newViewport = (JViewport) ev.getNewValue();
820: newViewport.addChangeListener(viewportChangeListener);
821: syncScrollPaneWithViewport();
822: }
823: }