1 /* 2 * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javax.swing; 26 27 import java.awt.*; 28 import java.awt.event.*; 29 import java.io.*; 30 import java.beans.PropertyChangeListener; 31 import java.util.Locale; 32 import java.util.Vector; 33 34 import javax.accessibility.*; 35 36 /** 37 * This class is inserted in between cell renderers and the components that 38 * use them. It just exists to thwart the repaint() and invalidate() methods 39 * which would otherwise propagate up the tree when the renderer was configured. 40 * It's used by the implementations of JTable, JTree, and JList. For example, 41 * here's how CellRendererPane is used in the code the paints each row 42 * in a JList: 43 * <pre> 44 * cellRendererPane = new CellRendererPane(); 45 * ... 46 * Component rendererComponent = renderer.getListCellRendererComponent(); 47 * renderer.configureListCellRenderer(dataModel.getElementAt(row), row); 48 * cellRendererPane.paintComponent(g, rendererComponent, this, x, y, w, h); 49 * </pre> 50 * <p> 51 * A renderer component must override isShowing() and unconditionally return 52 * true to work correctly because the Swing paint does nothing for components 53 * with isShowing false. 54 * <p> 55 * <strong>Warning:</strong> 56 * Serialized objects of this class will not be compatible with 57 * future Swing releases. The current serialization support is 58 * appropriate for short term storage or RMI between applications running 59 * the same version of Swing. As of 1.4, support for long term storage 60 * of all JavaBeans™ 61 * has been added to the <code>java.beans</code> package. 62 * Please see {@link java.beans.XMLEncoder}. 63 * 64 * @author Hans Muller 65 */ 66 public class CellRendererPane extends Container implements Accessible 67 { 68 /** 69 * Construct a CellRendererPane object. 70 */ 71 public CellRendererPane() { 72 super(); 73 setLayout(null); 74 setVisible(false); 75 } 76 77 /** 78 * Overridden to avoid propagating a invalidate up the tree when the 79 * cell renderer child is configured. 80 */ 81 public void invalidate() { } 82 83 84 /** 85 * Shouldn't be called. 86 */ 87 public void paint(Graphics g) { } 88 89 90 /** 91 * Shouldn't be called. 92 */ 93 public void update(Graphics g) { } 94 95 96 /** 97 * If the specified component is already a child of this then we don't 98 * bother doing anything - stacking order doesn't matter for cell 99 * renderer components (CellRendererPane doesn't paint anyway). 100 */ 101 protected void addImpl(Component x, Object constraints, int index) { 102 if (x.getParent() == this) { 103 return; 104 } 105 else { 106 super.addImpl(x, constraints, index); 107 } 108 } 109 110 111 /** 112 * Paint a cell renderer component c on graphics object g. Before the component 113 * is drawn it's reparented to this (if that's necessary), it's bounds 114 * are set to w,h and the graphics object is (effectively) translated to x,y. 115 * If it's a JComponent, double buffering is temporarily turned off. After 116 * the component is painted it's bounds are reset to -w, -h, 0, 0 so that, if 117 * it's the last renderer component painted, it will not start consuming input. 118 * The Container p is the component we're actually drawing on, typically it's 119 * equal to this.getParent(). If shouldValidate is true the component c will be 120 * validated before painted. 121 */ 122 public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate) { 123 if (c == null) { 124 if (p != null) { 125 Color oldColor = g.getColor(); 126 g.setColor(p.getBackground()); 127 g.fillRect(x, y, w, h); 128 g.setColor(oldColor); 129 } 130 return; 131 } 132 133 if (c.getParent() != this) { 134 this.add(c); 135 } 136 137 c.setBounds(x, y, w, h); 138 139 if(shouldValidate) { 140 c.validate(); 141 } 142 143 boolean wasDoubleBuffered = false; 144 if ((c instanceof JComponent) && ((JComponent)c).isDoubleBuffered()) { 145 wasDoubleBuffered = true; 146 ((JComponent)c).setDoubleBuffered(false); 147 } 148 149 Graphics cg = g.create(x, y, w, h); 150 try { 151 c.paint(cg); 152 } 153 finally { 154 cg.dispose(); 155 } 156 157 if (wasDoubleBuffered && (c instanceof JComponent)) { 158 ((JComponent)c).setDoubleBuffered(true); 159 } 160 161 c.setBounds(-w, -h, 0, 0); 162 } 163 164 165 /** 166 * Calls this.paintComponent(g, c, p, x, y, w, h, false). 167 */ 168 public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) { 169 paintComponent(g, c, p, x, y, w, h, false); 170 } 171 172 173 /** 174 * Calls this.paintComponent() with the rectangles x,y,width,height fields. 175 */ 176 public void paintComponent(Graphics g, Component c, Container p, Rectangle r) { 177 paintComponent(g, c, p, r.x, r.y, r.width, r.height); 178 } 179 180 181 private void writeObject(ObjectOutputStream s) throws IOException { 182 removeAll(); 183 s.defaultWriteObject(); 184 } 185 186 187 ///////////////// 188 // Accessibility support 189 //////////////// 190 191 protected AccessibleContext accessibleContext = null; 192 193 /** 194 * Gets the AccessibleContext associated with this CellRendererPane. 195 * For CellRendererPanes, the AccessibleContext takes the form of an 196 * AccessibleCellRendererPane. 197 * A new AccessibleCellRendererPane instance is created if necessary. 198 * 199 * @return an AccessibleCellRendererPane that serves as the 200 * AccessibleContext of this CellRendererPane 201 */ 202 public AccessibleContext getAccessibleContext() { 203 if (accessibleContext == null) { 204 accessibleContext = new AccessibleCellRendererPane(); 205 } 206 return accessibleContext; 207 } 208 209 /** 210 * This class implements accessibility support for the 211 * <code>CellRendererPane</code> class. 212 */ 213 protected class AccessibleCellRendererPane extends AccessibleAWTContainer { 214 // AccessibleContext methods 215 // 216 /** 217 * Get the role of this object. 218 * 219 * @return an instance of AccessibleRole describing the role of the 220 * object 221 * @see AccessibleRole 222 */ 223 public AccessibleRole getAccessibleRole() { 224 return AccessibleRole.PANEL; 225 } 226 } // inner class AccessibleCellRendererPane 227 }