Path: blob/master/src/java.desktop/share/classes/javax/swing/CellRendererPane.java
41153 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.swing;2627import java.awt.Color;28import java.awt.Component;29import java.awt.Container;30import java.awt.Graphics;31import java.awt.Rectangle;32import java.io.IOException;33import java.io.ObjectOutputStream;34import java.io.Serial;3536import javax.accessibility.Accessible;37import javax.accessibility.AccessibleContext;38import javax.accessibility.AccessibleRole;3940/**41* This class is inserted in between cell renderers and the components that42* use them. It just exists to thwart the repaint() and invalidate() methods43* which would otherwise propagate up the tree when the renderer was configured.44* It's used by the implementations of JTable, JTree, and JList. For example,45* here's how CellRendererPane is used in the code the paints each row46* in a JList:47* <pre>48* cellRendererPane = new CellRendererPane();49* ...50* Component rendererComponent = renderer.getListCellRendererComponent();51* renderer.configureListCellRenderer(dataModel.getElementAt(row), row);52* cellRendererPane.paintComponent(g, rendererComponent, this, x, y, w, h);53* </pre>54* <p>55* A renderer component must override isShowing() and unconditionally return56* true to work correctly because the Swing paint does nothing for components57* with isShowing false.58* <p>59* <strong>Warning:</strong>60* Serialized objects of this class will not be compatible with61* future Swing releases. The current serialization support is62* appropriate for short term storage or RMI between applications running63* the same version of Swing. As of 1.4, support for long term storage64* of all JavaBeans65* has been added to the <code>java.beans</code> package.66* Please see {@link java.beans.XMLEncoder}.67*68* @author Hans Muller69* @since 1.270*/71@SuppressWarnings("serial") // Same-version serialization only72public class CellRendererPane extends Container implements Accessible73{74/**75* Construct a CellRendererPane object.76*/77public CellRendererPane() {78super();79setLayout(null);80setVisible(false);81}8283/**84* Overridden to avoid propagating a invalidate up the tree when the85* cell renderer child is configured.86*/87public void invalidate() { }888990/**91* Shouldn't be called.92*/93public void paint(Graphics g) { }949596/**97* Shouldn't be called.98*/99public void update(Graphics g) { }100101102/**103* If the specified component is already a child of this then we don't104* bother doing anything - stacking order doesn't matter for cell105* renderer components (CellRendererPane doesn't paint anyway).106*/107protected void addImpl(Component x, Object constraints, int index) {108if (x.getParent() == this) {109return;110}111else {112super.addImpl(x, constraints, index);113}114}115116117/**118* Paint a cell renderer component c on graphics object g. Before the component119* is drawn it's reparented to this (if that's necessary), it's bounds120* are set to w,h and the graphics object is (effectively) translated to x,y.121* If it's a JComponent, double buffering is temporarily turned off. After122* the component is painted it's bounds are reset to -w, -h, 0, 0 so that, if123* it's the last renderer component painted, it will not start consuming input.124* The Container p is the component we're actually drawing on, typically it's125* equal to this.getParent(). If shouldValidate is true the component c will be126* validated before painted.127*128* @param g the {@code Graphics} object to draw on129* @param c the {@code Component} to draw130* @param p the {@code Container} component actually drawn on131* @param x an int specifying the left side of the area draw in, in pixels,132* measured from the left edge of the graphics context133* @param y an int specifying the top of the area to draw in, in pixels134* measured down from the top edge of the graphics context135* @param w an int specifying the width of the area draw in, in pixels136* @param h an int specifying the height of the area draw in, in pixels137* @param shouldValidate if true, component {@code c} will be validated138* before being painted139*/140public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate) {141if (c == null) {142if (p != null) {143Color oldColor = g.getColor();144g.setColor(p.getBackground());145g.fillRect(x, y, w, h);146g.setColor(oldColor);147}148return;149}150151if (c.getParent() != this) {152this.add(c);153}154155c.setBounds(x, y, w, h);156157if(shouldValidate) {158c.validate();159}160161boolean wasDoubleBuffered = false;162if ((c instanceof JComponent) && ((JComponent)c).isDoubleBuffered()) {163wasDoubleBuffered = true;164((JComponent)c).setDoubleBuffered(false);165}166167Graphics cg = g.create(x, y, w, h);168try {169c.paint(cg);170}171finally {172cg.dispose();173}174175if (wasDoubleBuffered && (c instanceof JComponent)) {176((JComponent)c).setDoubleBuffered(true);177}178179c.setBounds(-w, -h, 0, 0);180}181182183/**184* Calls this.paintComponent(g, c, p, x, y, w, h, false).185*186* @param g the {@code Graphics} object to draw on187* @param c the {@code Component} to draw188* @param p the {@code Container} component actually drawn on189* @param x an int specifying the left side of the area draw in, in pixels,190* measured from the left edge of the graphics context191* @param y an int specifying the top of the area to draw in, in pixels192* measured down from the top edge of the graphics context193* @param w an int specifying the width of the area draw in, in pixels194* @param h an int specifying the height of the area draw in, in pixels195*/196public void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) {197paintComponent(g, c, p, x, y, w, h, false);198}199200201/**202* Calls this.paintComponent(g, c, p, r.x, r.y, r.width, r.height) where203* {@code r} is the input {@code Rectangle} parameter.204*205* @param g the {@code Graphics} object to draw on206* @param c the {@code Component} to draw207* @param p the {@code Container} component actually drawn on208* @param r the {@code Rectangle} to draw in209*/210public void paintComponent(Graphics g, Component c, Container p, Rectangle r) {211paintComponent(g, c, p, r.x, r.y, r.width, r.height);212}213214215@Serial216private void writeObject(ObjectOutputStream s) throws IOException {217removeAll();218s.defaultWriteObject();219}220221222/////////////////223// Accessibility support224////////////////225226/**227* {@code AccessibleContext} associated with this {@code CellRendererPan}228*/229protected AccessibleContext accessibleContext = null;230231232/**233* Gets the AccessibleContext associated with this CellRendererPane.234* For CellRendererPanes, the AccessibleContext takes the form of an235* AccessibleCellRendererPane.236* A new AccessibleCellRendererPane instance is created if necessary.237*238* @return an AccessibleCellRendererPane that serves as the239* AccessibleContext of this CellRendererPane240*/241public AccessibleContext getAccessibleContext() {242if (accessibleContext == null) {243accessibleContext = new AccessibleCellRendererPane();244}245return accessibleContext;246}247248/**249* This class implements accessibility support for the250* <code>CellRendererPane</code> class.251*/252protected class AccessibleCellRendererPane extends AccessibleAWTContainer {253254/**255* Constructs an {@code AccessibleCellRendererPane}.256*/257protected AccessibleCellRendererPane() {}258259// AccessibleContext methods260//261/**262* Get the role of this object.263*264* @return an instance of AccessibleRole describing the role of the265* object266* @see AccessibleRole267*/268public AccessibleRole getAccessibleRole() {269return AccessibleRole.PANEL;270}271} // inner class AccessibleCellRendererPane272}273274275