org.jdesktop.swingx.renderer.WrappingIconPanel Maven / Gradle / Ivy
Show all versions of swingx-all Show documentation
/*
* $Id: WrappingIconPanel.java 4252 2012-11-13 18:37:17Z kschaefe $
*
* Copyright 2007 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 org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.painter.Painter;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.border.Border;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ComponentOrientation;
import java.awt.Font;
import java.awt.Rectangle;
/**
* Compound component for usage in tree renderer.
*
* Supports setting an icon for the node and a delegate component
* which is used to show the text/content of the node. The delegate
* component can be shared across renderers.
*
* This implements the PainterAware by delegating to the delegate component if that
* is of type PainterAware. Does nothing if not.
*/
public class WrappingIconPanel extends JXPanel implements PainterAware, IconAware {
protected JComponent delegate;
private final JLabel iconLabel;
private final String labelPosition = BorderLayout.CENTER; //2;
private final int iconLabelGap;
private Border ltorBorder;
private Border rtolBorder;
private boolean dropHackEnabled;
private boolean extendsComponentOpacity;
/**
* Instantiates and configures a WrappingIconPanel with the dropHack
* enabled.
*/
public WrappingIconPanel() {
this(true);
}
/**
* Instantiates and configures a WrappingIconPanel with the dropHack
* property set as indicated by the boolean.
*
* @param dropHackEnabled a boolean indicating whether the drop hack should
* be enabled.
* @see #isVisible()
*/
public WrappingIconPanel(boolean dropHackEnabled) {
setOpaque(false);
iconLabel = new JRendererLabel();
iconLabelGap = iconLabel.getIconTextGap();
iconLabel.setOpaque(false);
updateIconBorder();
setBorder(null);
setLayout(new BorderLayout());
add(iconLabel, BorderLayout.LINE_START);
setDropHackEnabled(dropHackEnabled);
}
/**
* {@inheritDoc}
*
* Overridden to update the icon position.
*/
@Override
public void setComponentOrientation(ComponentOrientation o) {
super.setComponentOrientation(o);
updateIconBorder();
}
/**
* Updates the icon position according to ComponentOrientation.
*/
private void updateIconBorder() {
if (ltorBorder == null) {
ltorBorder = BorderFactory.createEmptyBorder(0, 0, 0, iconLabelGap);
rtolBorder = BorderFactory.createEmptyBorder(0, iconLabelGap, 0, 0);
}
if (getComponentOrientation().isLeftToRight()) {
iconLabel.setBorder(ltorBorder);
} else {
iconLabel.setBorder(rtolBorder);
}
}
/**
* Sets the icon.
*
* @param icon the icon to use.
*/
@Override
public void setIcon(Icon icon) {
iconLabel.setIcon(icon);
iconLabel.setText(null);
validate();
}
/**
* Returns the icon used in this panel, may be null.
*
* @return the icon used in this panel, may be null.
*/
@Override
public Icon getIcon() {
return iconLabel.getIcon();
}
/**
* Sets the delegate component.
*
* @param comp the component to add as delegate.
*/
public void setComponent(JComponent comp) {
JComponent old = getComponent();
if (delegate != null) {
remove(delegate);
}
delegate = comp;
if (extendsComponentOpacity) {
iconLabel.setOpaque(comp.isOpaque());
} else {
iconLabel.setOpaque(false);
}
add(delegate, labelPosition);
validate();
firePropertyChange("component", old, getComponent());
}
/**
* Returns the delegate component.
*
* @return the delegate component.
*/
public JComponent getComponent() {
return delegate;
}
/**
* {@inheritDoc}
*
* Overridden to set the background of the delegate and icon label as well.
*/
@Override
public void setBackground(Color bg) {
super.setBackground(bg);
if (iconLabel != null) {
iconLabel.setBackground(bg);
}
if (delegate != null) {
delegate.setBackground(bg);
}
}
/**
* {@inheritDoc}
*
* Overridden to set the foreground of the delegate and icon label as well.
*/
@Override
public void setForeground(Color bg) {
super.setForeground(bg);
if (iconLabel != null) {
iconLabel.setForeground(bg);
}
if (delegate != null) {
delegate.setForeground(bg);
}
}
/**
* {@inheritDoc}
*
* Overridden to set the Font of the delegate as well.
*/
@Override
public void setFont(Font font) {
if (delegate != null) {
delegate.setFont(font);
}
super.setFont(font);
}
/**
* {@inheritDoc}
*
*
* Overridden to hack around #766-swingx: cursor flickering in DnD when
* dragging over tree column. This is a core bug (#6700748) related to
* painting the rendering component on a CellRendererPane. A trick around is
* to let this return false.
*
*
* Some LayoutManagers don't layout an invisible component, so need to make
* the hack-enabled configurable. This implementation will return false
* if isDropHackEnabled, super.isVisible otherwise.
*/
@Override
public boolean isVisible() {
return dropHackEnabled ? false : super.isVisible();
}
/**
* {@inheritDoc}
*
*
* Returns the delegate's Painter if it is of type PainterAware or null
* otherwise.
*
* @return the delegate's Painter or null.
*/
@Override
public Painter> getPainter() {
if (delegate instanceof PainterAware) {
return ((PainterAware) delegate).getPainter();
}
return null;
}
/**
* Sets the delegate's Painter if it is of type PainterAware. Does nothing otherwise.
*
* @param painter the Painter to apply to the delegate.
*/
@Override
public void setPainter(Painter> painter) {
if (delegate instanceof PainterAware) {
((PainterAware) delegate).setPainter(painter);
}
}
/**
* Returns the bounds of the delegate component or null if the delegate is null.
*
* PENDING JW: where do we use it? Maybe it was for testing only?
*
* @return the bounds of the delegate, or null if the delegate is null.
*/
public Rectangle getDelegateBounds() {
if (delegate == null)
return null;
return delegate.getBounds();
}
/**
* Sets the dropHackEnabled property.
*
* The default value is true.
*
* @param dropHackEnabled
* @see #isVisible()
*/
public void setDropHackEnabled(boolean dropHackEnabled) {
this.dropHackEnabled = dropHackEnabled;
}
/**
* Sets a boolean indicating whether or not the main component's opacity
* should be applied to the Icon region.
*
* The default value is false. This covers the main use case in a JTree.
*
* @param extendsComponentOpacity
*/
public void setExtendsComponentOpacity(boolean extendsComponentOpacity) {
this.extendsComponentOpacity = extendsComponentOpacity;
}
/**
* @return the extendsComponentOpacity
*/
public boolean getExtendsComponentOpacity() {
return extendsComponentOpacity;
}
}