org.jdesktop.swingx.border.IconBorder Maven / Gradle / Ivy
Show all versions of swingx-all Show documentation
/*
* $Id$
*
* Copyright 2004 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.border;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.io.Serializable;
import javax.swing.Icon;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import org.jdesktop.beans.JavaBean;
import org.jdesktop.swingx.icon.EmptyIcon;
/**
* {@code IconBorder} creates a border that places an {@code Icon} in the border
* on the horizontal axis. The border does not add any additional insets other
* than the inset required to produce the space for the icon. If additional
* insets are required, users should create a
* {@link javax.swing.border.CompoundBorder compund border}.
*
* This border is useful when attempting to add {@code Icon}s to pre-existing
* components without requiring specialty painting.
*
* @author Amy Fowler
* @author Karl Schaefer
*
* @version 1.1
*/
@JavaBean
public class IconBorder implements Border, Serializable {
/**
* An empty icon.
*/
public static final Icon EMPTY_ICON = new EmptyIcon();
private int padding;
private Icon icon;
private int iconPosition;
private Rectangle iconBounds = new Rectangle();
/**
* Creates an {@code IconBorder} with an empty icon in a trailing position
* with a padding of 4.
*
* @see #EMPTY_ICON
*/
public IconBorder() {
this(null);
}
/**
* Creates an {@code IconBorder} with the specified icon in a trailing
* position with a padding of 4.
*
* @param validIcon
* the icon to set. This may be {@code null} to represent an
* empty icon.
* @see #EMPTY_ICON
*/
public IconBorder(Icon validIcon) {
this(validIcon, SwingConstants.TRAILING);
}
/**
* Creates an {@code IconBorder} with the specified constraints and a
* padding of 4.
*
* @param validIcon
* the icon to set. This may be {@code null} to represent an
* empty icon.
* @param iconPosition
* the position to place the icon relative to the component
* contents. This must be one of the following
* {@code SwingConstants}:
*
* - {@code LEADING}
* - {@code TRAILING}
* - {@code EAST}
* - {@code WEST}
*
* @throws IllegalArgumentException
* if {@code iconPosition} is not a valid position.
* @see #EMPTY_ICON
*/
public IconBorder(Icon validIcon, int iconPosition) {
this(validIcon, iconPosition, 4);
}
/**
* Creates an {@code IconBorder} with the specified constraints. If
* {@code validIcon} is {@code null}, {@code EMPTY_ICON} is used instead.
* If {@code padding} is negative, then the border does not use padding.
*
* @param validIcon
* the icon to set. This may be {@code null} to represent an
* empty icon.
* @param iconPosition
* the position to place the icon relative to the component
* contents. This must be one of the following
* {@code SwingConstants}:
*
* - {@code LEADING}
* - {@code TRAILING}
* - {@code EAST}
* - {@code WEST}
*
* @param padding
* the padding to surround the icon with. All non-positive values
* set the padding to 0.
* @throws IllegalArgumentException
* if {@code iconPosition} is not a valid position.
* @see #EMPTY_ICON
*/
public IconBorder(Icon validIcon, int iconPosition, int padding) {
setIcon(validIcon);
setPadding(padding);
setIconPosition(iconPosition);
}
private boolean isValidPosition(int position) {
boolean result = false;
switch (position) {
case SwingConstants.LEADING:
case SwingConstants.TRAILING:
case SwingConstants.EAST:
case SwingConstants.WEST:
result = true;
break;
default:
result = false;
}
return result;
}
/**
* {@inheritDoc}
*/
public Insets getBorderInsets(Component c) {
int horizontalInset = icon.getIconWidth() + (2 * padding);
int iconPosition = bidiDecodeLeadingTrailing(c.getComponentOrientation(), this.iconPosition);
if (iconPosition == SwingConstants.EAST) {
return new Insets(0, 0, 0, horizontalInset);
}
return new Insets(0, horizontalInset, 0, 0);
}
/**
* Sets the icon for this border.
*
* @param validIcon
* the icon to set. This may be {@code null} to represent an
* empty icon.
* @see #EMPTY_ICON
*/
public void setIcon(Icon validIcon) {
this.icon = validIcon == null ? EMPTY_ICON : validIcon;
}
/**
* This border is not opaque.
*
* @return always returns {@code false}
*/
public boolean isBorderOpaque() {
return false;
}
/**
* {@inheritDoc}
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height) {
int iconPosition = bidiDecodeLeadingTrailing(c.getComponentOrientation(), this.iconPosition);
if (iconPosition == SwingConstants.NORTH_EAST) {
iconBounds.y = y + padding;
iconBounds.x = x + width - padding - icon.getIconWidth();
} else if (iconPosition == SwingConstants.EAST) { // EAST
iconBounds.y = y
+ ((height - icon.getIconHeight()) / 2);
iconBounds.x = x + width - padding - icon.getIconWidth();
} else if (iconPosition == SwingConstants.WEST) {
iconBounds.y = y
+ ((height - icon.getIconHeight()) / 2);
iconBounds.x = x + padding;
}
iconBounds.width = icon.getIconWidth();
iconBounds.height = icon.getIconHeight();
icon.paintIcon(c, g, iconBounds.x, iconBounds.y);
}
/**
* Returns EAST or WEST depending on the ComponentOrientation and
* the given postion LEADING/TRAILING this method has no effect for other
* position values
*/
private int bidiDecodeLeadingTrailing(ComponentOrientation c, int position) {
if(position == SwingConstants.TRAILING) {
if(!c.isLeftToRight()) {
return SwingConstants.WEST;
}
return SwingConstants.EAST;
}
if(position == SwingConstants.LEADING) {
if(c.isLeftToRight()) {
return SwingConstants.WEST;
}
return SwingConstants.EAST;
}
return position;
}
/**
* Gets the padding surrounding the icon.
*
* @return the padding for the icon. This value is guaranteed to be
* nonnegative.
*/
public int getPadding() {
return padding;
}
/**
* Sets the padding around the icon.
*
* @param padding
* the padding to set. If {@code padding < 0}, then
* {@code padding} will be set to {@code 0}.
*/
public void setPadding(int padding) {
this.padding = padding < 0 ? 0 : padding;
}
/**
* Returns the position to place the icon (relative to the component contents).
*
* @return one of the following {@code SwingConstants}:
*
* - {@code LEADING}
* - {@code TRAILING}
* - {@code EAST}
* - {@code WEST}
*
*/
public int getIconPosition() {
return iconPosition;
}
/**
* Sets the position to place the icon (relative to the component contents).
*
* @param iconPosition must be one of the following {@code SwingConstants}:
*
* - {@code LEADING}
* - {@code TRAILING}
* - {@code EAST}
* - {@code WEST}
*
* @throws IllegalArgumentException
* if {@code iconPosition} is not a valid position.
*/
public void setIconPosition(int iconPosition) {
if (!isValidPosition(iconPosition)) {
throw new IllegalArgumentException("Invalid icon position");
}
this.iconPosition = iconPosition;
}
}