1 /* 2 * Copyright (c) 1997, 2014, 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 * @since 1.2 66 */ 67 @SuppressWarnings("serial") // Same-version serialization only 68 public class CellRendererPane extends Container implements Accessible 69 { 70 /** 71 * Construct a CellRendererPane object. 72 */ 73 public CellRendererPane() { 74 super(); 75 setLayout(null); 76 setVisible(false); 77 } 78 79 /** 80 * Overridden to avoid propagating a invalidate up the tree when the 81 * cell renderer child is configured. 82 */ 83 public void invalidate() { } 84 85 86 /** 87 * Shouldn't be called. 88 */ 89 public void paint(Graphics g) { } 90 91 92 /** 93 * Shouldn't be called. 94 */ 95 public void update(Graphics g) { } 96 97 98 /** 99 * If the specified component is already a child of this then we don't 100 * bother doing anything - stacking order doesn't matter for cell 101 * renderer components (CellRendererPane doesn't paint anyway). 102 */ 103 protected void addImpl(Component x, Object constraints, int index) { 104 if (x.getParent() == this) { 105 return; 106 } 107 else { 108 super.addImpl(x, constraints, index); 109 } 110 } 111 112 113 /** 114 * Paint a cell renderer component c on graphics object g. Before the component 115 * is drawn it's reparented to this (if that's necessary), it's bounds 116 * are set to w,h and the graphics object is (effectively) translated to x,y. 117 * If it's a JComponent, double buffering is temporarily turned off. After 118 * the component is painted it's bounds are reset to -w, -h, 0, 0 so that, if 119 * it's the last renderer component painted, it will not start consuming input. 120 * The Container p is the component we're actually drawing on, typically it's 121 * equal to this.getParent(). If shouldValidate is true the component c will be 122 * validated before painted. 123 * 124 * @param g the {@code Graphics} object to draw on 125 * @param c the {@code Component} to draw 126 * @param p the {@code Container} component actually drawn on 127 * @param x an int specifying the left side of the area draw in, in pixels, 128 * measured from the left edge of the graphics context 129 * @param y an int specifying the top of the area to draw in, in pixels 130 * measured down from the top edge of the graphics context 131 * @param w an int specifying the width of the area draw in, in pixels 132 * @param h an int specifying the height of the area draw in, in pixels 133 * @param shouldValidate if true, component {@code c} will be validated 134 * before being painted 135 */ 136 public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate) { 137 if (c == null) { 138 if (p != null) { 139 Color oldColor = g.getColor(); 140 g.setColor(p.getBackground()); 141 g.fillRect(x, y, w, h); 142 g.setColor(oldColor); 143 } 144 return; 145 } 146 147 if (c.getParent() != this) { 148 this.add(c); 149 } 150 151 c.setBounds(x, y, w, h); 152 153 if(shouldValidate) { 154 c.validate(); 155 } 156 157 boolean wasDoubleBuffered = false; 158 if ((c instanceof JComponent) && ((JComponent)c).isDoubleBuffered()) { 159 wasDoubleBuffered = true; 160 ((JComponent)c).setDoubleBuffered(false); 161 } 162 163 Graphics cg = g.create(x, y, w, h); 164 try { 165 c.paint(cg); 166 } 167 finally { 168 cg.dispose(); 169 } 170 171 if (wasDoubleBuffered && (c instanceof JComponent)) { 172 ((JComponent)c).setDoubleBuffered(true); 173 } 174 175 c.setBounds(-w, -h, 0, 0); 176 } 177 178 179 /** 180 * Calls this.paintComponent(g, c, p, x, y, w, h, false). 181 * 182 * @param g the {@code Graphics} object to draw on 183 * @param c the {@code Component} to draw 184 * @param p the {@code Container} component actually drawn on 185 * @param x an int specifying the left side of the area draw in, in pixels, 186 * measured from the left edge of the graphics context 187 * @param y an int specifying the top of the area to draw in, in pixels 188 * measured down from the top edge of the graphics context 189 * @param w an int specifying the width of the area draw in, in pixels 190 * @param h an int specifying the height of the area draw in, in pixels 191 */ 192 public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) { 193 paintComponent(g, c, p, x, y, w, h, false); 194 } 195 196 197 /** 198 * Calls this.paintComponent() with the rectangles x,y,width,height fields. 199 * 200 * @param g the {@code Graphics} object to draw on 201 * @param c the {@code Component} to draw 202 * @param p the {@code Container} component actually drawn on 203 * @param r the {@code Rectangle} to draw in 204 */ 205 public void paintComponent(Graphics g, Component c, Container p, Rectangle r) { 206 paintComponent(g, c, p, r.x, r.y, r.width, r.height); 207 } 208 209 210 private void writeObject(ObjectOutputStream s) throws IOException { 211 removeAll(); 212 s.defaultWriteObject(); 213 } 214 215 216 ///////////////// 217 // Accessibility support 218 //////////////// 219 220 /** 221 * {@code AccessibleContext} associated with this {@code CellRendererPan} 222 */ 223 protected AccessibleContext accessibleContext = null; 224 225 226 /** 227 * Gets the AccessibleContext associated with this CellRendererPane. 228 * For CellRendererPanes, the AccessibleContext takes the form of an 229 * AccessibleCellRendererPane. 230 * A new AccessibleCellRendererPane instance is created if necessary. 231 * 232 * @return an AccessibleCellRendererPane that serves as the 233 * AccessibleContext of this CellRendererPane 234 */ 235 public AccessibleContext getAccessibleContext() { 236 if (accessibleContext == null) { 237 accessibleContext = new AccessibleCellRendererPane(); 238 } 239 return accessibleContext; 240 } 241 242 /** 243 * This class implements accessibility support for the 244 * <code>CellRendererPane</code> class. 245 */ 246 protected class AccessibleCellRendererPane extends AccessibleAWTContainer { 247 // AccessibleContext methods 248 // 249 /** 250 * Get the role of this object. 251 * 252 * @return an instance of AccessibleRole describing the role of the 253 * object 254 * @see AccessibleRole 255 */ 256 public AccessibleRole getAccessibleRole() { 257 return AccessibleRole.PANEL; 258 } 259 } // inner class AccessibleCellRendererPane 260 }