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:
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:
69: public class BasicScrollPaneUI extends ScrollPaneUI
70: implements ScrollPaneConstants
71: {
72:
73:
79: public class HSBChangeListener implements ChangeListener
80: {
81:
82:
88: public void stateChanged(ChangeEvent event)
89: {
90: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
91: JViewport vp = scrollpane.getViewport();
92: Point viewPosition = vp.getViewPosition();
93: int xpos = hsb.getValue();
94:
95: if (xpos != viewPosition.x)
96: {
97: viewPosition.x = xpos;
98: vp.setViewPosition(viewPosition);
99: }
100:
101: viewPosition.y = 0;
102: JViewport columnHeader = scrollpane.getColumnHeader();
103: if (columnHeader != null
104: && !columnHeader.getViewPosition().equals(viewPosition))
105: columnHeader.setViewPosition(viewPosition);
106: }
107:
108: }
109:
110:
116: public class VSBChangeListener implements ChangeListener
117: {
118:
119:
125: public void stateChanged(ChangeEvent event)
126: {
127: JScrollBar vsb = scrollpane.getVerticalScrollBar();
128: JViewport vp = scrollpane.getViewport();
129: Point viewPosition = vp.getViewPosition();
130: int ypos = vsb.getValue();
131: if (ypos != viewPosition.y)
132: {
133: viewPosition.y = ypos;
134: vp.setViewPosition(viewPosition);
135: }
136:
137: viewPosition.x = 0;
138: JViewport rowHeader = scrollpane.getRowHeader();
139: if (rowHeader != null
140: && !rowHeader.getViewPosition().equals(viewPosition))
141: rowHeader.setViewPosition(viewPosition);
142: }
143:
144: }
145:
146:
152: public class ViewportChangeHandler implements ChangeListener
153: {
154:
155:
163: public void stateChanged(ChangeEvent event)
164: {
165: JViewport vp = scrollpane.getViewport();
166: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
167: JScrollBar vsb = scrollpane.getVerticalScrollBar();
168: syncScrollPaneWithViewport();
169: }
170:
171: }
172:
173:
179: public class PropertyChangeHandler implements PropertyChangeListener
180: {
181:
182:
194: public void propertyChange(PropertyChangeEvent e)
195: {
196: String propName = e.getPropertyName();
197: if (propName.equals("viewport"))
198: updateViewport(e);
199: else if (propName.equals("rowHeader"))
200: updateRowHeader(e);
201: else if (propName.equals("columnHeader"))
202: updateColumnHeader(e);
203: else if (propName.equals("horizontalScrollBarPolicy")
204: || e.getPropertyName().equals("verticalScrollBarPolicy"))
205: updateScrollBarDisplayPolicy(e);
206: else if (propName.equals("verticalScrollBar"))
207: {
208: JScrollBar oldSb = (JScrollBar) e.getOldValue();
209: oldSb.getModel().removeChangeListener(vsbChangeListener);
210: JScrollBar newSb = (JScrollBar) e.getNewValue();
211: newSb.getModel().addChangeListener(vsbChangeListener);
212: }
213: else if (propName.equals("horizontalScrollBar"))
214: {
215: JScrollBar oldSb = (JScrollBar) e.getOldValue();
216: oldSb.getModel().removeChangeListener(hsbChangeListener);
217: JScrollBar newSb = (JScrollBar) e.getNewValue();
218: newSb.getModel().addChangeListener(hsbChangeListener);
219: }
220: }
221:
222: }
223:
224:
231: protected class MouseWheelHandler implements MouseWheelListener
232: {
233:
236: final Rectangle rect = new Rectangle();
237:
238:
243: public void mouseWheelMoved(MouseWheelEvent e)
244: {
245: if (scrollpane.getViewport().getComponentCount() == 0)
246: return;
247:
248: Component target = scrollpane.getViewport().getComponent(0);
249: JScrollBar bar = scrollpane.getVerticalScrollBar();
250: Scrollable scrollable = (target instanceof Scrollable) ? (Scrollable) target
251: : null;
252:
253: boolean tracksHeight = scrollable != null
254: && scrollable.getScrollableTracksViewportHeight();
255: int wheel = e.getWheelRotation() * ROWS_PER_WHEEL_CLICK;
256: int delta;
257:
258:
259: if (bar != null && ! tracksHeight)
260: {
261: if (scrollable != null)
262: {
263: bounds(target);
264: delta = scrollable.getScrollableUnitIncrement(
265: rect, SwingConstants.VERTICAL, wheel);
266: }
267: else
268: {
269:
270: delta = wheel * SCROLL_NON_SCROLLABLES;
271: }
272: scroll(bar, delta);
273: }
274:
275: else
276: {
277: bar = scrollpane.getHorizontalScrollBar();
278: boolean tracksWidth = scrollable != null
279: && scrollable.getScrollableTracksViewportWidth();
280:
281: if (bar != null && ! tracksWidth)
282: {
283: if (scrollable != null)
284: {
285: bounds(target);
286: delta = scrollable.getScrollableUnitIncrement(
287: rect, SwingConstants.HORIZONTAL, wheel);
288: }
289: else
290: {
291:
292: delta = wheel * SCROLL_NON_SCROLLABLES;
293: }
294: scroll(bar, delta);
295: }
296: }
297: }
298:
299:
305: final void bounds(Component target)
306: {
307:
308: target.getParent().getBounds(rect);
309: rect.x = getValue(scrollpane.getHorizontalScrollBar());
310: rect.y = getValue(scrollpane.getVerticalScrollBar());
311: }
312:
313:
316: final int getValue(JScrollBar bar)
317: {
318: return bar != null ? bar.getValue() : 0;
319: }
320:
321:
327: final void scroll(JScrollBar bar, int delta)
328: {
329: int y = bar.getValue() + delta;
330:
331: if (y < bar.getMinimum())
332: y = bar.getMinimum();
333: if (y > bar.getMaximum())
334: y = bar.getMaximum();
335:
336: bar.setValue(y);
337: }
338: }
339:
340:
346: class ViewportContainerListener implements ContainerListener
347: {
348:
351: public void componentAdded(ContainerEvent e)
352: {
353: e.getChild().addMouseWheelListener(mouseWheelListener);
354: }
355:
356:
359: public void componentRemoved(ContainerEvent e)
360: {
361: e.getChild().removeMouseWheelListener(mouseWheelListener);
362: }
363: }
364:
365:
369: static int SCROLL_NON_SCROLLABLES = 10;
370:
371:
375: static int ROWS_PER_WHEEL_CLICK = 3;
376:
377:
378: protected JScrollPane scrollpane;
379:
380:
383: protected ChangeListener hsbChangeListener;
384:
385:
388: protected ChangeListener vsbChangeListener;
389:
390:
393: protected ChangeListener viewportChangeListener;
394:
395:
398: protected PropertyChangeListener spPropertyChangeListener;
399:
400:
403: MouseWheelListener mouseWheelListener;
404:
405:
409: ContainerListener containerListener;
410:
411: public static ComponentUI createUI(final JComponent c)
412: {
413: return new BasicScrollPaneUI();
414: }
415:
416: protected void installDefaults(JScrollPane p)
417: {
418: scrollpane = p;
419: LookAndFeel.installColorsAndFont(p, "ScrollPane.background",
420: "ScrollPane.foreground",
421: "ScrollPane.font");
422: LookAndFeel.installBorder(p, "ScrollPane.border");
423: p.setOpaque(true);
424: }
425:
426: protected void uninstallDefaults(JScrollPane p)
427: {
428: p.setForeground(null);
429: p.setBackground(null);
430: p.setFont(null);
431: p.setBorder(null);
432: scrollpane = null;
433: }
434:
435: public void installUI(final JComponent c)
436: {
437: super.installUI(c);
438: installDefaults((JScrollPane) c);
439: installListeners((JScrollPane) c);
440: installKeyboardActions((JScrollPane) c);
441: }
442:
443:
448: protected void installListeners(JScrollPane sp)
449: {
450: if (spPropertyChangeListener == null)
451: spPropertyChangeListener = createPropertyChangeListener();
452: sp.addPropertyChangeListener(spPropertyChangeListener);
453:
454: if (hsbChangeListener == null)
455: hsbChangeListener = createHSBChangeListener();
456: sp.getHorizontalScrollBar().getModel().addChangeListener(hsbChangeListener);
457:
458: if (vsbChangeListener == null)
459: vsbChangeListener = createVSBChangeListener();
460: sp.getVerticalScrollBar().getModel().addChangeListener(vsbChangeListener);
461:
462: if (viewportChangeListener == null)
463: viewportChangeListener = createViewportChangeListener();
464:
465: if (mouseWheelListener == null)
466: mouseWheelListener = createMouseWheelListener();
467:
468: if (containerListener == null)
469: containerListener = new ViewportContainerListener();
470:
471: JViewport v = sp.getViewport();
472: v.addChangeListener(viewportChangeListener);
473: v.addContainerListener(containerListener);
474:
475:
476:
477: for (int i = 0; i < v.getComponentCount(); i++)
478: v.getComponent(i).addMouseWheelListener(mouseWheelListener);
479: }
480:
481:
488: protected void installKeyboardActions(JScrollPane sp)
489: throws NotImplementedException
490: {
491:
492:
493: }
494:
495:
500: protected ChangeListener createHSBChangeListener()
501: {
502: return new HSBChangeListener();
503: }
504:
505:
510: protected ChangeListener createVSBChangeListener()
511: {
512: return new VSBChangeListener();
513: }
514:
515:
520: protected ChangeListener createViewportChangeListener()
521: {
522: return new ViewportChangeHandler();
523: }
524:
525:
530: protected PropertyChangeListener createPropertyChangeListener()
531: {
532: return new PropertyChangeHandler();
533: }
534:
535:
540: protected MouseWheelListener createMouseWheelListener()
541: {
542: return new MouseWheelHandler();
543: }
544:
545: public void uninstallUI(final JComponent c)
546: {
547: super.uninstallUI(c);
548: this.uninstallDefaults((JScrollPane)c);
549: uninstallListeners((JScrollPane) c);
550: installKeyboardActions((JScrollPane) c);
551: }
552:
553:
559: protected void uninstallListeners(JComponent c)
560: {
561: JScrollPane sp = (JScrollPane) c;
562: sp.removePropertyChangeListener(spPropertyChangeListener);
563: sp.getHorizontalScrollBar().getModel()
564: .removeChangeListener(hsbChangeListener);
565: sp.getVerticalScrollBar().getModel()
566: .removeChangeListener(vsbChangeListener);
567:
568: JViewport v = sp.getViewport();
569: v.removeChangeListener(viewportChangeListener);
570: v.removeContainerListener(containerListener);
571:
572: for (int i = 0; i < v.getComponentCount(); i++)
573: v.getComponent(i).removeMouseWheelListener(mouseWheelListener);
574:
575: }
576:
577:
584: protected void uninstallKeyboardActions(JScrollPane sp)
585: throws NotImplementedException
586: {
587:
588:
589: }
590:
591: public Dimension getMinimumSize(JComponent c)
592: {
593: JScrollPane p = (JScrollPane ) c;
594: ScrollPaneLayout sl = (ScrollPaneLayout) p.getLayout();
595: return sl.minimumLayoutSize(c);
596: }
597:
598: public void paint(Graphics g, JComponent c)
599: {
600:
601:
602: }
603:
604:
607: protected void syncScrollPaneWithViewport()
608: {
609: JViewport vp = scrollpane.getViewport();
610:
611:
612: JScrollBar hsb = scrollpane.getHorizontalScrollBar();
613: hsb.setMaximum(vp.getViewSize().width);
614: hsb.setValue(vp.getViewPosition().x);
615: hsb.setVisibleAmount(vp.getExtentSize().width);
616:
617:
618: JScrollBar vsb = scrollpane.getVerticalScrollBar();
619: vsb.setMaximum(vp.getViewSize().height);
620: vsb.setValue(vp.getViewPosition().y);
621: vsb.setVisibleAmount(vp.getExtentSize().height);
622: }
623:
624:
630: protected void updateColumnHeader(PropertyChangeEvent ev)
631: {
632:
633: }
634:
635:
641: protected void updateRowHeader(PropertyChangeEvent ev)
642: {
643:
644: }
645:
646:
652: protected void updateScrollBarDisplayPolicy(PropertyChangeEvent ev)
653: {
654:
655: }
656:
657:
666: protected void updateViewport(PropertyChangeEvent ev)
667: {
668: JViewport oldViewport = (JViewport) ev.getOldValue();
669: oldViewport.removeChangeListener(viewportChangeListener);
670: JViewport newViewport = (JViewport) ev.getNewValue();
671: newViewport.addChangeListener(viewportChangeListener);
672: syncScrollPaneWithViewport();
673: }
674: }
675:
676:
677:
678:
679:
680:
681:
682:
683:
684:
685: