org.pushingpixels.flamingo.api.common.AbstractCommandButton Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of flamengo Show documentation
Show all versions of flamengo Show documentation
Flamingo Swing component suite
The newest version!
/*
* Copyright (c) 2005-2010 Flamingo Kirill Grouchnikov. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* o Neither the name of Flamingo Kirill Grouchnikov nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.pushingpixels.flamingo.api.common;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.*;
import javax.accessibility.AccessibleContext;
import javax.swing.ButtonModel;
import javax.swing.SwingConstants;
import javax.swing.event.*;
import org.pushingpixels.flamingo.api.common.icon.ResizableIcon;
import org.pushingpixels.flamingo.api.common.model.ActionButtonModel;
import org.pushingpixels.flamingo.internal.ui.common.CommandButtonUI;
/**
* Base class for command buttons.
*
* @author Kirill Grouchnikov
*/
public abstract class AbstractCommandButton extends
RichToolTipManager.JTrackableComponent {
/**
* Associated icon.
*
* @see #setIcon(ResizableIcon)
* @see #getIcon()
*/
protected ResizableIcon icon;
/**
* Associated disabled icon.
*
* @see #setDisabledIcon(ResizableIcon)
* @see #getDisabledIcon()
*/
protected ResizableIcon disabledIcon;
/**
* The button text.
*
* @see #setText(String)
* @see #getText()
*/
private String text;
/**
* The button action model.
*
* @see #getActionModel()
* @see #setActionModel(ActionButtonModel)
*/
protected ActionButtonModel actionModel;
/**
* Additional text. This is shown for {@link CommandButtonDisplayState#TILE}
* .
*
* @see #setExtraText(String)
* @see #getExtraText()
*/
protected String extraText;
/**
* Current display state of this
button.
*
* @see #setDisplayState(CommandButtonDisplayState)
* @see #getDisplayState()
*/
protected CommandButtonDisplayState displayState;
/**
* The dimension of the icon of the associated command button in the
* {@link CommandButtonDisplayState#FIT_TO_ICON} state.
*
* @see #getCustomDimension()
* @see #updateCustomDimension(int)
*/
protected int customDimension;
/**
* Indication whether this button is flat.
*
* @see #setFlat(boolean)
* @see #isFlat()
*/
protected boolean isFlat;
/**
* Horizontal alignment of the content.
*
* @see #setHorizontalAlignment(int)
* @see #getHorizontalAlignment()
*/
private int horizontalAlignment;
/**
* Scale factor for horizontal gaps.
*
* @see #setHGapScaleFactor(double)
* @see #getHGapScaleFactor()
*/
private double hgapScaleFactor;
/**
* Scale factor for vertical gaps.
*
* @see #setVGapScaleFactor(double)
* @see #getVGapScaleFactor()
*/
private double vgapScaleFactor;
/**
* Rich tooltip for the action area.
*
* @see #setActionRichTooltip(RichTooltip)
* @see #getRichTooltip(MouseEvent)
*/
private RichTooltip actionRichTooltip;
/**
* Location order kind for buttons placed in command button strips or for
* buttons that need the visuals of segmented strips.
*
* @see #setLocationOrderKind(CommandButtonLocationOrderKind)
* @see #getLocationOrderKind()
*/
private CommandButtonLocationOrderKind locationOrderKind;
/**
* Action handler for the button.
*/
protected ActionHandler actionHandler;
/**
* Key tip for the action area.
*
* @see #setActionKeyTip(String)
* @see #getActionKeyTip()
*/
protected String actionKeyTip;
/**
* Enumerates the available values for the location order kind. This is used
* for buttons placed in command button strips or for buttons that need the
* visuals of segmented strips.
*
* @author Kirill Grouchnikov
*/
public static enum CommandButtonLocationOrderKind {
/**
* Indicates that this button is the only button in the strip.
*/
ONLY,
/**
* Indicates that this button is the first button in the strip.
*/
FIRST,
/**
* Indicates that this button is in the middle of the strip.
*/
MIDDLE,
/**
* Indicates that this button is the last button in the strip.
*/
LAST
}
/**
* Creates a new command button.
*
* @param text
* Button title. May contain any number of words.
* @param icon
* Button icon.
*/
public AbstractCommandButton(String text, ResizableIcon icon) {
this.icon = icon;
this.customDimension = -1;
this.displayState = CommandButtonDisplayState.FIT_TO_ICON;
this.horizontalAlignment = SwingConstants.CENTER;
this.actionHandler = new ActionHandler();
this.isFlat = true;
this.hgapScaleFactor = 1.0;
this.vgapScaleFactor = 1.0;
this.setText(text);
this.setOpaque(false);
}
/**
* Sets the new UI delegate.
*
* @param ui
* New UI delegate.
*/
public void setUI(CommandButtonUI ui) {
super.setUI(ui);
}
/**
* Returns the UI delegate for this button.
*
* @return The UI delegate for this button.
*/
public CommandButtonUI getUI() {
return (CommandButtonUI) ui;
}
/**
* Sets new display state for this
button. Fires a
* displayState
property change event.
*
* @param state
* New display state.
* @see #getDisplayState()
*/
public void setDisplayState(CommandButtonDisplayState state) {
CommandButtonDisplayState old = this.displayState;
this.displayState = state;
this.firePropertyChange("displayState", old, this.displayState);
}
/**
* Returns the associated icon.
*
* @return The associated icon.
* @see #getDisabledIcon()
* @see #setIcon(ResizableIcon)
*/
public ResizableIcon getIcon() {
return icon;
}
/**
* Sets new icon for this button. Fires an icon
property change
* event.
*
* @param defaultIcon
* New default icon for this button.
* @see #setDisabledIcon(ResizableIcon)
* @see #getIcon()
*/
public void setIcon(ResizableIcon defaultIcon) {
ResizableIcon oldValue = this.icon;
this.icon = defaultIcon;
firePropertyChange("icon", oldValue, defaultIcon);
if (defaultIcon != oldValue) {
if (defaultIcon == null || oldValue == null
|| defaultIcon.getIconWidth() != oldValue.getIconWidth()
|| defaultIcon.getIconHeight() != oldValue.getIconHeight()) {
revalidate();
}
repaint();
}
}
/**
* Sets the disabled icon for this button.
*
* @param disabledIcon
* Disabled icon for this button.
* @see #setIcon(ResizableIcon)
* @see #getDisabledIcon()
*/
public void setDisabledIcon(ResizableIcon disabledIcon) {
this.disabledIcon = disabledIcon;
}
/**
* Returns the associated disabled icon.
*
* @return The associated disabled icon.
* @see #setDisabledIcon(ResizableIcon)
* @see #getIcon()
*/
public ResizableIcon getDisabledIcon() {
return disabledIcon;
}
/**
* Return the current display state of this
button.
*
* @return The current display state of this
button.
* @see #setDisplayState(CommandButtonDisplayState)
*/
public CommandButtonDisplayState getDisplayState() {
return displayState;
}
/**
* Returns the extra text of this button.
*
* @return Extra text of this button.
* @see #setExtraText(String)
*/
public String getExtraText() {
return this.extraText;
}
/**
* Sets the extra text for this button. Fires an extraText
* property change event.
*
* @param extraText
* Extra text for this button.
* @see #getExtraText()
*/
public void setExtraText(String extraText) {
String oldValue = this.extraText;
this.extraText = extraText;
firePropertyChange("extraText", oldValue, extraText);
if (accessibleContext != null) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
oldValue, extraText);
}
if (extraText == null || oldValue == null
|| !extraText.equals(oldValue)) {
revalidate();
repaint();
}
}
/**
* Returns the text of this button.
*
* @return The text of this button.
* @see #setText(String)
*/
public String getText() {
return this.text;
}
/**
* Sets the new text for this button. Fires a text
property
* change event.
*
* @param text
* The new text for this button.
* @see #getText()
*/
public void setText(String text) {
String oldValue = this.text;
this.text = text;
firePropertyChange("text", oldValue, text);
if (accessibleContext != null) {
accessibleContext.firePropertyChange(
AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY,
oldValue, text);
}
if (text == null || oldValue == null || !text.equals(oldValue)) {
revalidate();
repaint();
}
}
/**
* Updates the dimension of the icon of the associated command button in the
* {@link CommandButtonDisplayState#FIT_TO_ICON} state. Fires a
* customDimension
property change event.
*
* @param dimension
* New dimension of the icon of the associated command button in
* the {@link CommandButtonDisplayState#FIT_TO_ICON} state.
* @see #getCustomDimension()
*/
public void updateCustomDimension(int dimension) {
if (this.customDimension != dimension) {
int old = this.customDimension;
this.customDimension = dimension;
this.firePropertyChange("customDimension", old,
this.customDimension);
}
}
/**
* Returns the dimension of the icon of the associated command button in the
* {@link CommandButtonDisplayState#FIT_TO_ICON} state.
*
* @return The dimension of the icon of the associated command button in the
* {@link CommandButtonDisplayState#FIT_TO_ICON} state.
* @see #updateCustomDimension(int)
*/
public int getCustomDimension() {
return this.customDimension;
}
/**
* Returns indication whether this button has flat appearance.
*
* @return true
if this button has flat appearance,
* false
otherwise.
* @see #setFlat(boolean)
*/
public boolean isFlat() {
return this.isFlat;
}
/**
* Sets the flat appearance of this button. Fires a flat
* property change event.
*
* @param isFlat
* If true
, this button will have flat appearance,
* otherwise this button will not have flat appearance.
* @see #isFlat()
*/
public void setFlat(boolean isFlat) {
boolean old = this.isFlat;
this.isFlat = isFlat;
if (old != this.isFlat) {
this.firePropertyChange("flat", old, this.isFlat);
}
if (old != isFlat) {
repaint();
}
}
/**
* Returns the action model for this button.
*
* @return The action model for this button.
* @see #setActionModel(ActionButtonModel)
*/
public ActionButtonModel getActionModel() {
return this.actionModel;
}
/**
* Sets the new action model for this button. Fires an
* actionModel
property change event.
*
* @param newModel
* The new action model for this button.
* @see #getActionModel()
*/
public void setActionModel(ActionButtonModel newModel) {
ButtonModel oldModel = getActionModel();
if (oldModel != null) {
oldModel.removeChangeListener(this.actionHandler);
oldModel.removeActionListener(this.actionHandler);
}
actionModel = newModel;
if (newModel != null) {
newModel.addChangeListener(this.actionHandler);
newModel.addActionListener(this.actionHandler);
}
firePropertyChange("actionModel", oldModel, newModel);
if (newModel != oldModel) {
revalidate();
repaint();
}
}
/**
* Adds the specified action listener to this button.
*
* @param l
* Action listener to add.
* @see #removeActionListener(ActionListener)
*/
public void addActionListener(ActionListener l) {
this.listenerList.add(ActionListener.class, l);
}
/**
* Removes the specified action listener from this button.
*
* @param l
* Action listener to remove.
* @see #addActionListener(ActionListener)
*/
public void removeActionListener(ActionListener l) {
this.listenerList.remove(ActionListener.class, l);
}
/**
* Adds the specified change listener to this button.
*
* @param l
* Change listener to add.
* @see #removeChangeListener(ChangeListener)
*/
public void addChangeListener(ChangeListener l) {
this.listenerList.add(ChangeListener.class, l);
}
/**
* Removes the specified change listener from this button.
*
* @param l
* Change listener to remove.
* @see #addChangeListener(ChangeListener)
*/
public void removeChangeListener(ChangeListener l) {
this.listenerList.remove(ChangeListener.class, l);
}
/*
* (non-Javadoc)
*
* @see javax.swing.JComponent#setEnabled(boolean)
*/
@Override
public void setEnabled(boolean b) {
if (!b && actionModel.isRollover()) {
actionModel.setRollover(false);
}
super.setEnabled(b);
actionModel.setEnabled(b);
}
/**
* Default action handler for this button.
*
* @author Kirill Grouchnikov
*/
class ActionHandler implements ActionListener, ChangeListener {
public void stateChanged(ChangeEvent e) {
fireStateChanged();
repaint();
}
public void actionPerformed(ActionEvent event) {
fireActionPerformed(event);
}
}
/**
* Notifies all listeners that have registered interest for notification on
* this event type. The event instance is lazily created.
*
* @see EventListenerList
*/
protected void fireStateChanged() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
ChangeEvent ce = new ChangeEvent(this);
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ChangeListener.class) {
// Lazily create the event:
((ChangeListener) listeners[i + 1]).stateChanged(ce);
}
}
}
/**
* Notifies all listeners that have registered interest for notification on
* this event type. The event instance is lazily created using the
* event
parameter.
*
* @param event
* the ActionEvent
object
* @see EventListenerList
*/
protected void fireActionPerformed(ActionEvent event) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
ActionEvent e = null;
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length - 2; i >= 0; i -= 2) {
if (listeners[i] == ActionListener.class) {
// Lazily create the event:
if (e == null) {
String actionCommand = event.getActionCommand();
e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
actionCommand, event.getWhen(), event
.getModifiers());
}
((ActionListener) listeners[i + 1]).actionPerformed(e);
}
}
}
/**
* Sets new horizontal alignment for the content of this button. Fires a
* horizontalAlignment
property change event.
*
* @param alignment
* New horizontal alignment for the content of this button.
* @see #getHorizontalAlignment()
*/
public void setHorizontalAlignment(int alignment) {
if (alignment == this.horizontalAlignment)
return;
int oldValue = this.horizontalAlignment;
this.horizontalAlignment = alignment;
firePropertyChange("horizontalAlignment", oldValue,
this.horizontalAlignment);
repaint();
}
/**
* Returns the horizontal alignment for the content of this button.
*
* @return The horizontal alignment for the content of this button.
* @see #setHorizontalAlignment(int)
*/
public int getHorizontalAlignment() {
return this.horizontalAlignment;
}
/**
* Sets new horizontal gap scale factor for the content of this button.
* Fires an hgapScaleFactor
property change event.
*
* @param hgapScaleFactor
* New horizontal gap scale factor for the content of this
* button.
* @see #getHGapScaleFactor()
* @see #setVGapScaleFactor(double)
* @see #setGapScaleFactor(double)
*/
public void setHGapScaleFactor(double hgapScaleFactor) {
if (hgapScaleFactor == this.hgapScaleFactor)
return;
double oldValue = this.hgapScaleFactor;
this.hgapScaleFactor = hgapScaleFactor;
firePropertyChange("hgapScaleFactor", oldValue, this.hgapScaleFactor);
if (this.hgapScaleFactor != oldValue) {
revalidate();
repaint();
}
}
/**
* Sets new vertical gap scale factor for the content of this button. Fires
* a vgapScaleFactor
property change event.
*
* @param vgapScaleFactor
* New vertical gap scale factor for the content of this button.
* @see #getVGapScaleFactor()
* @see #setHGapScaleFactor(double)
* @see #setGapScaleFactor(double)
*/
public void setVGapScaleFactor(double vgapScaleFactor) {
if (vgapScaleFactor == this.vgapScaleFactor)
return;
double oldValue = this.vgapScaleFactor;
this.vgapScaleFactor = vgapScaleFactor;
firePropertyChange("vgapScaleFactor", oldValue, this.vgapScaleFactor);
if (this.vgapScaleFactor != oldValue) {
revalidate();
repaint();
}
}
/**
* Sets new gap scale factor for the content of this button.
*
* @param gapScaleFactor
* New gap scale factor for the content of this button.
* @see #getHGapScaleFactor()
* @see #getVGapScaleFactor()
*/
public void setGapScaleFactor(double gapScaleFactor) {
setHGapScaleFactor(gapScaleFactor);
setVGapScaleFactor(gapScaleFactor);
}
/**
* Returns the horizontal gap scale factor for the content of this button.
*
* @return The horizontal gap scale factor for the content of this button.
* @see #setHGapScaleFactor(double)
* @see #setGapScaleFactor(double)
* @see #getVGapScaleFactor()
*/
public double getHGapScaleFactor() {
return this.hgapScaleFactor;
}
/**
* Returns the vertical gap scale factor for the content of this button.
*
* @return The vertical gap scale factor for the content of this button.
* @see #setVGapScaleFactor(double)
* @see #setGapScaleFactor(double)
* @see #getHGapScaleFactor()
*/
public double getVGapScaleFactor() {
return this.vgapScaleFactor;
}
/**
* Programmatically perform an action "click". This does the same thing as
* if the user had pressed and released the action area of the button.
*/
public void doActionClick() {
Dimension size = getSize();
ButtonModel actionModel = this.getActionModel();
actionModel.setArmed(true);
actionModel.setPressed(true);
paintImmediately(new Rectangle(0, 0, size.width, size.height));
try {
Thread.sleep(100);
} catch (InterruptedException ie) {
}
actionModel.setPressed(false);
actionModel.setArmed(false);
}
boolean hasRichTooltips() {
return (this.actionRichTooltip != null);
}
/**
* Sets the rich tooltip for the action area of this button.
*
* @param richTooltip
* Rich tooltip for the action area of this button.
* @see #getRichTooltip(MouseEvent)
*/
public void setActionRichTooltip(RichTooltip richTooltip) {
this.actionRichTooltip = richTooltip;
RichToolTipManager richToolTipManager = RichToolTipManager
.sharedInstance();
if (this.hasRichTooltips()) {
richToolTipManager.registerComponent(this);
} else {
richToolTipManager.unregisterComponent(this);
}
}
/*
* (non-Javadoc)
*
* @seeorg.jvnet.flamingo.common.RichToolTipManager.JTrackableComponent#
* getRichTooltip(java.awt.event.MouseEvent)
*/
@Override
public RichTooltip getRichTooltip(MouseEvent mouseEvent) {
return this.actionRichTooltip;
}
/*
* (non-Javadoc)
*
* @see javax.swing.JComponent#setToolTipText(java.lang.String)
*/
@Override
public void setToolTipText(String text) {
throw new UnsupportedOperationException("Use rich tooltip APIs");
}
/**
* Returns the location order kind for buttons placed in command button
* strips or for buttons that need the visuals of segmented strips.
*
* @return The location order kind for buttons placed in command button
* strips or for buttons that need the visuals of segmented strips.
* @see #setLocationOrderKind(CommandButtonLocationOrderKind)
*/
public CommandButtonLocationOrderKind getLocationOrderKind() {
return this.locationOrderKind;
}
/**
* Sets the location order kind for buttons placed in command button strips
* or for buttons that need the visuals of segmented strips. Fires a
* locationOrderKind
property change event.
*
* @param locationOrderKind
* The location order kind for buttons placed in command button
* strips or for buttons that need the visuals of segmented
* strips.
* @see #getLocationOrderKind()
*/
public void setLocationOrderKind(
CommandButtonLocationOrderKind locationOrderKind) {
CommandButtonLocationOrderKind old = this.locationOrderKind;
if (old != locationOrderKind) {
this.locationOrderKind = locationOrderKind;
this.firePropertyChange("locationOrderKind", old,
this.locationOrderKind);
}
}
/**
* Returns the key tip for the action area of this button.
*
* @return The key tip for the action area of this button.
* @see #setActionKeyTip(String)
*/
public String getActionKeyTip() {
return this.actionKeyTip;
}
/**
* Sets the key tip for the action area of this button. Fires an
* actionKeyTip
property change event.
*
* @param actionKeyTip
* The key tip for the action area of this button.
* @see #getActionKeyTip()
*/
public void setActionKeyTip(String actionKeyTip) {
String old = this.actionKeyTip;
this.actionKeyTip = actionKeyTip;
this.firePropertyChange("actionKeyTip", old, this.actionKeyTip);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy