org.jdesktop.swingx.renderer.JRendererCheckBox Maven / Gradle / Ivy
Show all versions of swingx-all Show documentation
/*
* $Id$
*
* Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
* Santa Clara, California 95054, U.S.A. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.jdesktop.swingx.renderer;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JCheckBox;
import javax.swing.UIManager;
import org.jdesktop.swingx.painter.Painter;
/**
* A JCheckBox
optimized for usage in renderers and
* with a minimal background painter support.
*
* Note: As of revision #4223, there's a complete overhaul (aka: changed the tricksery) to
* fix Issue swingx-1513 (allow client code to set renderer transparent) while keeping
* fix Issue swingx-897 (striping/background lost when painter installed)
*
*
* Note: The change of logic _did_ introduce a regression (swingx-1546)
* which was fixed by forcing the box's opacity to true (for regression release
* 1.6.5-1). Further improvements (like f.i. the option to delegate to the ui's
* update - to allow LAF installed painters - instead of paint) are deferred
* to a later normal release, more discussions needed.
*
*
* @author Jeanette Winzenburg
*
* @see #paintComponent(Graphics)
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class JRendererCheckBox extends JCheckBox implements PainterAware {
/** the swingx painter */
protected Painter painter;
/** a flag to prevent ui painting from filling the background. */
private boolean fakeTransparency;
/**
* Instantiates a JRendererCheckBox with opacity true.
*/
public JRendererCheckBox() {
super();
// fix # 1546-swingx: striping lost in synth-based lafs
// forcing opaque to enable painting the background
setOpaque(true);
}
/**
* {@inheritDoc}
*/
@Override
public Painter getPainter() {
return painter;
}
/**
* {@inheritDoc}
*/
@Override
public void setPainter(Painter painter) {
Painter old = getPainter();
this.painter = painter;
firePropertyChange("painter", old, getPainter());
}
/**
* {@inheritDoc}
*
* Overridden to return false if painting flag is true.
*
*/
@Override
public boolean isOpaque() {
if (fakeTransparency) {
return false;
}
return super.isOpaque();
}
/**
* {@inheritDoc}
*
* Overridden to return false if painting flag is true.
*
*/
@Override
public boolean isContentAreaFilled() {
if (fakeTransparency) {
return false;
}
return super.isContentAreaFilled();
}
/**
* {@inheritDoc}
*
* Overridden to not automatically de/register itself from/to the ToolTipManager.
* As rendering component it is not considered to be active in any way, so the
* manager must not listen.
*/
@Override
public void setToolTipText(String text) {
putClientProperty(TOOL_TIP_TEXT_KEY, text);
}
/**
* Overridden to snatch painting from super if a painter installed or Nimbus
* detected.
*
* The overall logic currently (since 1.6.5) is to simply call super without SwingX
* painter. Otherwise, that is with SwingX painter:
*
* - if opaque
*
* - set a flag which fakes transparency, that is both
*
contentAreaFilled
and
* opaque
return false
* - fill background with the component's background color
*
- apply swingx painter
*
- hook into
ui.paint(...)
* - reset the flag
*
* - else
*
apply swingx painter
* call super
* -
*
*
*
* Note that Nimbus is special cased (mainly due to its bug of
* even row striping instead of odd)
* and handled as if a SwingX painter were set.
*
*/
@Override
protected void paintComponent(Graphics g) {
// JW: hack around for #1178-swingx (core issue)
// grab painting if Nimbus detected
if ((painter != null) || isNimbus()) {
// we have a custom (background) painter
// try to inject if possible
// there's no guarantee - some LFs have their own background
// handling elsewhere
if (isOpaque()) {
// replace the paintComponent completely
fakeTransparency = true;
paintComponentWithPainter((Graphics2D) g);
fakeTransparency = false;
} else {
// transparent apply the background painter before calling super
paintPainter(g);
super.paintComponent(g);
}
} else {
// nothing to worry about - delegate to super
super.paintComponent(g);
}
}
/**
* Hack around Nimbus not respecting background colors if UIResource.
* So by-pass ...
*
* @return
*/
private boolean isNimbus() {
return UIManager.getLookAndFeel().getName().contains("Nimbus");
}
/**
*
* Hack around AbstractPainter.paint bug which disposes the Graphics.
* So here we give it a scratch to paint on.
* TODO - remove again, the issue is fixed?
*
* @param g the graphics to paint on
*/
private void paintPainter(Graphics g) {
if (painter == null) return;
// fail fast: we assume that g must not be null
// which throws an NPE here instead deeper down the bowels
// this differs from corresponding core implementation!
Graphics2D scratch = (Graphics2D) g.create();
try {
painter.paint(scratch, this, getWidth(), getHeight());
}
finally {
scratch.dispose();
}
}
/**
*
* @param g
*/
protected void paintComponentWithPainter(Graphics2D g) {
// 1. be sure to fill the background
// 2. paint the painter
// by-pass ui.update and hook into ui.paint directly
if (ui != null) {
// fail fast: we assume that g must not be null
// which throws an NPE here instead deeper down the bowels
// this differs from corresponding core implementation!
Graphics scratchGraphics = g.create();
try {
scratchGraphics.setColor(getBackground());
scratchGraphics.fillRect(0, 0, getWidth(), getHeight());
paintPainter(g);
ui.paint(scratchGraphics, this);
// super.paintComponent(g);
} finally {
scratchGraphics.dispose();
}
}
}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*
* @since 1.5
*/
@Override
public void invalidate() {}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*/
@Override
public void validate() {}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*/
@Override
public void revalidate() {}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*/
@Override
public void repaint(long tm, int x, int y, int width, int height) {}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*/
@Override
public void repaint(Rectangle r) { }
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*
* @since 1.5
*/
@Override
public void repaint() {
}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*/
@Override
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
// Strings get interned...
if ("text".equals(propertyName)) {
super.firePropertyChange(propertyName, oldValue, newValue);
}
}
/**
* Overridden for performance reasons.
* See the Implementation Note
* for more information.
*/
@Override
public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) { }
}