1 /* 2 * @(#)QuaquaViewportUI.java 1.4 2007-11-1 3 * 4 * Copyright (c) 2004-2007 Werner Randelshofer 5 * Staldenmattweg 2, Immensee, CH-6405, Switzerland. 6 * All rights reserved. 7 * 8 * The copyright of this software is owned by Werner Randelshofer. 9 * You may not use, copy or modify this software, except in 10 * accordance with the license agreement you entered into with 11 * Werner Randelshofer. For details see accompanying license terms. 12 */ 13 14 package ch.randelshofer.quaqua; 15 16 import ch.randelshofer.quaqua.util.*; 17 import ch.randelshofer.quaqua.util.ViewportPainter; 18 import java.awt.*; 19 import java.awt.datatransfer.*; 20 import java.awt.dnd.*; 21 import java.awt.event.*; 22 import java.awt.image.*; 23 import java.beans.*; 24 import java.util.*; 25 import javax.swing.*; 26 import javax.swing.event.*; 27 import javax.swing.plaf.*; 28 import javax.swing.plaf.basic.*; 29 import javax.swing.table.*; 30 import javax.swing.event.*; 31 import javax.swing.text.*; 32 33 /** 34 * The Quaqua user interface delegate for a JViewport. 35 * 36 * @author Werner Randelshofer 37 * @version 1.4 2007-11-11 Added property change listener. 38 * <br>1.3 2007-01-16 Listen to focus changes on the viewport and its 39 * child component, and repaint the parent scroll pane border on focus change. 40 * <br>1.2.2 2005-11-26 Retrieve default opaqueness from UIManager. 41 * Fixed broken invocation of ViewportPainter. 42 * <br>1.2.1 2005-09-17 Only paint viewport if it is opaque. 43 * <br>1.2 2005-08-25 Fill the viewport with the background color of its 44 * viewport view if the UI of the viewport is not an instance of ViewportPainter. 45 * <br>1.1 2004-12-14 Do not check whether the view is striped or not, 46 * always use the view for drawing the viewport. 47 * <br>1.0 June 22, 2004 Created. 48 */ 49 public class QuaquaViewportUI extends BasicViewportUI { 50 private ChangeListener changeListener; 51 private ContainerListener containerListener; 52 private FocusListener focusListener; 53 private PropertyChangeListener propertyChangeListener; 54 private JViewport viewport; 55 createUI(JComponent c)56 public static ComponentUI createUI(JComponent c) { 57 return new QuaquaViewportUI(); 58 } paint(Graphics g, JComponent c)59 public void paint(Graphics g, JComponent c) { 60 if (c.isOpaque()) { 61 Component view = viewport.getView(); 62 Object ui = (view == null) ? null : Methods.invokeGetter(view, "getUI", null); 63 if (ui instanceof ViewportPainter) { 64 ((ViewportPainter) ui).paintViewport(g, viewport); 65 } else { 66 if (viewport.getView() != null) { 67 g.setColor(viewport.getView().getBackground()); 68 g.fillRect(0,0,c.getWidth(),c.getHeight()); 69 } 70 } 71 } 72 Debug.paint(g, c, this); 73 } 74 installUI(JComponent c)75 public void installUI(JComponent c) { 76 viewport = (JViewport) c; 77 super.installUI(c); 78 //c.setOpaque(QuaquaManager.getBoolean("Viewport.opaque")); 79 QuaquaUtilities.installProperty(c, "opaque", UIManager.get("Viewport.opaque")); 80 installListeners(); 81 } 82 uninstallUI(JComponent c)83 public void uninstallUI(JComponent c) { 84 viewport = (JViewport) c; 85 super.uninstallUI(c); 86 uninstallListeners(); 87 } 88 /** 89 * Attaches listeners to the JTable. 90 */ installListeners()91 protected void installListeners() { 92 changeListener = createChangeListener(); 93 viewport.addChangeListener(changeListener); 94 containerListener = createContainerListener(); 95 viewport.addContainerListener(containerListener); 96 focusListener = createFocusListener(); 97 viewport.addFocusListener(focusListener); 98 propertyChangeListener = createPropertyChangeListener(); 99 viewport.addPropertyChangeListener(propertyChangeListener); 100 if (viewport.getView() != null) { 101 viewport.getView().addFocusListener(focusListener); 102 } 103 } uninstallListeners()104 protected void uninstallListeners() { 105 viewport.removeChangeListener(changeListener); 106 viewport.removeContainerListener(containerListener); 107 viewport.removeFocusListener(focusListener); 108 viewport.removePropertyChangeListener(propertyChangeListener); 109 changeListener = null; 110 containerListener = null; 111 112 } createPropertyChangeListener()113 protected PropertyChangeListener createPropertyChangeListener() { 114 return new QuaquaPropertyChangeHandler(); 115 } 116 createChangeListener()117 private ChangeListener createChangeListener() { 118 return new ChangeHandler(); 119 } createContainerListener()120 private ContainerListener createContainerListener() { 121 return new ContainerHandler(); 122 } createFocusListener()123 private FocusListener createFocusListener() { 124 return QuaquaFocusHandler.getInstance(); 125 } 126 127 /** 128 * We need to repaint the viewport if the location of a striped view 129 * changes. 130 */ 131 private class ChangeHandler implements ChangeListener { 132 private Point previousLocation = new Point(); stateChanged(ChangeEvent e)133 public void stateChanged(ChangeEvent e) { 134 135 if (viewport.getView() != null) { 136 Component view = viewport.getView(); 137 138 Point newLocation = view.getLocation(); 139 if (! previousLocation.equals(newLocation)) { 140 if (view.getHeight() < viewport.getHeight()) { 141 if (newLocation.x > previousLocation.x) { 142 viewport.repaint(0, view.getHeight(), newLocation.x - previousLocation.x, viewport.getHeight() - view.getHeight()); 143 } 144 if (newLocation.x < previousLocation.x) { 145 viewport.repaint(viewport.getWidth() + newLocation.x - previousLocation.x, view.getHeight(), previousLocation.x - newLocation.x, viewport.getHeight() - view.getHeight()); 146 } 147 } 148 if (view.getWidth() < viewport.getWidth()) { 149 if (newLocation.y > previousLocation.y) { 150 viewport.repaint(view.getWidth(), 0, viewport.getWidth() - view.getWidth(), Math.min(view.getHeight(),newLocation.y - previousLocation.y)); 151 } 152 if (newLocation.y < previousLocation.y) { 153 viewport.repaint( 154 view.getWidth(), 155 Math.min(view.getHeight(),viewport.getHeight()) - previousLocation.y + newLocation.y, 156 viewport.getWidth() - view.getWidth(), 157 previousLocation.y - newLocation.y 158 ); 159 } 160 } 161 previousLocation = newLocation; 162 } 163 } 164 } 165 } 166 private class ContainerHandler implements ContainerListener { componentRemoved(ContainerEvent e)167 public void componentRemoved(ContainerEvent e) { 168 e.getChild().removeFocusListener(focusListener); 169 } 170 componentAdded(ContainerEvent e)171 public void componentAdded(ContainerEvent e) { 172 e.getChild().addFocusListener(focusListener); 173 } 174 } 175 public class QuaquaPropertyChangeHandler implements PropertyChangeListener { propertyChange(PropertyChangeEvent e)176 public void propertyChange(PropertyChangeEvent e) { 177 String name = e.getPropertyName(); 178 if ("Frame.active" == name) { 179 // we don't need to do anything here yet. 180 } else if (name.equals("JComponent.sizeVariant")) { 181 QuaquaUtilities.applySizeVariant(viewport); 182 } 183 } 184 } 185 } 186