1 /*
2 * Copyright 1997-2003 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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<sup><font size="-2">TM</font></sup>
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 }