View Javadoc
1   /*
2    * Copyright (c) 1997, 2013, 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&trade;
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 }