// Copyright (C) 2005 Mammoth Software LLC
//
// 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
//
// Contact the author at: info@mammothsoftware.com
package javax.swing.origamist;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.border.Border;
import javax.swing.border.CompoundBorder;
/**
* A button that uses a mouse listener to indicate rollover.
*
* @author m. bangham
* @author Martin Pecka - added Javadoc and some modifications.
* Copyright 2005 Mammoth Software LLC
*/
public class JRolloverButton extends JButton
{
/** If true, the size was explicitly set. */
protected boolean isSizeSet = false;
/** */
private static final long serialVersionUID = 3091885225750513834L;
/** The border of the component. */
protected Border compBorder = super.getBorder();
/** The outer border to be used when the button is rolled over. */
protected Border rolloverBorder = BorderFactory.createRaisedBevelBorder();
/**
* Create the rollover button with no icon.
*/
public JRolloverButton()
{
init();
initRolloverListener();
}
/**
* Creates the rollover button with the given icon and set its size to the given one.
*
* @param icon The icon to display.
* @param size The size of the button.
*/
public JRolloverButton(Icon icon, Dimension size)
{
this(icon, size, true);
}
/**
* Creates the rollover button with the given icon and set its size to the given one.
*
* If <code>isRollover</code> is false, the button will not behave as rollover.
*
* @param icon The icon to display.
* @param size The size of the button.
* @param isRollover Whether the button has to behave as rollover.
*/
public JRolloverButton(Icon icon, Dimension size, boolean isRollover)
{
super(icon);
init();
if (isRollover)
initRolloverListener();
if (size != null)
isSizeSet = true;
setFixedSize(size);
}
/**
* Create the rollover button with no icon and set its size to the given one.
*
* @param size The size of the button.
* @param isRollover Whether the button has to behave as rollover.
*/
public JRolloverButton(Dimension size, boolean isRollover)
{
this((Icon) null, size, isRollover);
}
/**
* Create the rollover button with icon loaded from the given action and set the action as the button's action. Also
* set the size to the given one.
*
* @param action The action to perform and which to take the icon from.
* @param size The size of the button.
*/
public JRolloverButton(Action action, Dimension size)
{
this((Icon) action.getValue(Action.SMALL_ICON), size);
// Note: using setAction(action) causes both icon and text
// to be displayed on toolbar.
addActionListener(action);
}
/**
* Creates the rollover button initialized by the given button.
*
* @param button The button to initialize this button from.
*/
public JRolloverButton(AbstractButton button)
{
this(button, button.getPreferredSize(), true);
isSizeSet = false;
}
/**
* Creates the rollover button initialized by the given button.
*
* If <code>isRollover</code> is false, the button will not behave as rollover.
*
* @param button The button to initialize this button from.
* @param isRollover Whether the button has to behave as rollover.
*/
public JRolloverButton(AbstractButton button, boolean isRollover)
{
this(button, button.getPreferredSize(), isRollover);
isSizeSet = false;
}
/**
* Creates the rollover button initialized by the given button and set its size to the given one.
*
* @param button The button to initialize this button from.
* @param size The size of the button.
*/
public JRolloverButton(AbstractButton button, Dimension size)
{
this(button, size, true);
}
/**
* Creates the rollover button initialized by the given button and set its size to the given one.
*
* If <code>isRollover</code> is false, the button will not behave as rollover.
*
* @param button The button to initialize this button from.
* @param size The size of the button.
* @param isRollover Whether the button has to behave as rollover.
*/
public JRolloverButton(AbstractButton button, Dimension size, boolean isRollover)
{
this(button.getIcon(), size, isRollover);
initFromButton(button);
}
/**
* Initialize the button.
*/
protected void init()
{
setRequestFocusEnabled(false);
setRolloverEnabled(true);
PropertyChangeListener l = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt)
{
if (!isSizeSet) {
setPreferredSize(null);
setFixedSize(getPreferredSize());
}
}
};
addPropertyChangeListener("text", l);
addPropertyChangeListener("icon", l);
}
/**
* Set some properties of this rollover button from the given JButton.
*
* @param button The button to initialize this button from.
*/
protected void initFromButton(AbstractButton button)
{
setIcon(button.getIcon());
setDisabledIcon(button.getDisabledIcon());
setPressedIcon(button.getPressedIcon());
setDisabledSelectedIcon(button.getDisabledSelectedIcon());
setSelectedIcon(button.getSelectedIcon());
setText(button.getText());
if (button.isBackgroundSet())
setBackground(button.getBackground());
if (button.isForegroundSet())
setForeground(button.getForeground());
setBorder(button.getBorder());
if (button.isCursorSet())
setCursor(button.getCursor());
setDisplayedMnemonicIndex(button.getDisplayedMnemonicIndex());
setEnabled(button.isEnabled());
if (button.isFontSet())
setFont(button.getFont());
setMnemonic(button.getMnemonic());
setToolTipText(button.getToolTipText());
setVisible(button.isVisible());
setOpaque(button.isOpaque());
}
/**
* Set the size of the button to the given one and don't allow resizing.
*
* @param size The size to set.
*/
protected void setFixedSize(Dimension size)
{
setPreferredSize(size);
setMaximumSize(size);
setMinimumSize(size);
}
/**
* Adds a mouse listener to this button.
*/
protected void initRolloverListener()
{
MouseListener l = new MouseAdapter() {
public void mouseEntered(MouseEvent e)
{
setRollover(true);
}
public void mouseExited(MouseEvent e)
{
setRollover(false);
}
};
addMouseListener(l);
}
/**
* Makes the button to appear as rolled over according to the given argument.
*
* @param rollover Whether the button should look rolled over.
*/
public void setRollover(boolean rollover)
{
if (rollover) {
/*
* Borders can have different insets - get the size and force it
* so the new rollover border doesn't change the button size.
*/
if (!(JRolloverButton.super.getBorder() instanceof RolloverBorder))
JRolloverButton.super.setBorder(new RolloverBorder(getRolloverBorder(), getBorder()));
getModel().setRollover(true);
} else {
if (JRolloverButton.super.getBorder() instanceof RolloverBorder)
JRolloverButton.super.setBorder(((RolloverBorder) JRolloverButton.super.getBorder()).getInsideBorder());
getModel().setRollover(false);
}
}
/**
* @return The border that is to be used when the mouse is over the button.
*/
protected Border getRolloverBorder()
{
return rolloverBorder;
}
/**
* @param rolloverBorder The border that is to be used when the mouse is over the button.
*/
public void setRolloverBorder(Border rolloverBorder)
{
this.rolloverBorder = rolloverBorder;
}
@Override
public void setBorder(Border border)
{
compBorder = border;
if (!(super.getBorder() instanceof CompoundBorder)) {
super.setBorder(border);
}
}
@Override
public Border getBorder()
{
return compBorder != null ? compBorder : super.getBorder();
}
@Override
public Insets getInsets()
{
return compBorder != null ? compBorder.getBorderInsets(this) : super.getInsets();
}
@Override
protected void paintBorder(Graphics g)
{
if (isBorderPainted()) {
if (super.getBorder() != null) {
super.getBorder().paintBorder(this, g, 0, 0, getWidth(), getHeight());
}
}
}
/**
* A simple tagging compound border to be able to differentiate between user-set compound borders and the inner set
* ones.
*
* @author Martin Pecka
*/
protected class RolloverBorder extends CompoundBorder
{
/** */
private static final long serialVersionUID = 5394741728171932908L;
/**
*
*/
public RolloverBorder()
{
super();
}
/**
* @param outsideBorder
* @param insideBorder
*/
public RolloverBorder(Border outsideBorder, Border insideBorder)
{
super(outsideBorder, insideBorder);
}
}
}