org.wings.SAbstractIconTextCompound Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2000,2005 wingS development team.
*
* This file is part of wingS (http://wingsframework.org).
*
* wingS 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.
*
* Please see COPYING for the complete licence.
*/
package org.wings;
import org.wings.plaf.ButtonCG;
import org.wings.plaf.CheckBoxCG;
import org.wings.plaf.ClickableCG;
import org.wings.plaf.RadioButtonCG;
import org.wings.plaf.ToggleButtonCG;
import org.wings.style.Selector;
import org.wings.style.CSSStyleSheet;
import org.wings.style.CSSAttributeSet;
import org.wings.style.CSSProperty;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
/**
* Base class for elements with icon and text like {@link SAbstractButton} and {@link SClickable}.
*
* It supports 7 different icon states.
*
* @author Armin Haaf
*/
public abstract class SAbstractIconTextCompound
extends SComponent
implements ItemSelectable,ChangeListener {
public static final int ICON_COUNT = 7;
public static final int DISABLED_ICON = 0;
public static final int DISABLED_SELECTED_ICON = 1;
public static final int ENABLED_ICON = 2;
public static final int SELECTED_ICON = 3;
public static final int ROLLOVER_ICON = 4;
public static final int ROLLOVER_SELECTED_ICON = 5;
public static final int PRESSED_ICON = 6;
/**
* A Pseudo selector for buttons in selected state
* Refer to {@link SComponent#setAttribute(org.wings.style.Selector, org.wings.style.CSSProperty, String)}
*/
public static final Selector SELECTOR_SELECTED = new Selector("selected");
private SButtonModel model;
/**
* The button model's changeListener
.
*/
protected ChangeListener changeListener = null;
protected transient ChangeEvent changeEvent = null;
/**
* the text the button is showing
*/
private String text;
/**
* The icon to be displayed
*/
private SIcon icon;
private SIcon disabledIcon;
private SIcon selectedIcon;
private SIcon pressedIcon;
private SIcon disabledSelectedIcon;
private SIcon rolloverIcon;
private SIcon rolloverSelectedIcon;
private int verticalTextPosition = SConstants.CENTER;
private int horizontalTextPosition = SConstants.RIGHT;
private int iconTextGap = 4;
private boolean delayEvents = false;
private boolean delayedEvent = false;
/**
* Create a button with given text.
*
* @param text the button text
*/
public SAbstractIconTextCompound(String text) {
setText(text);
model = new SDefaultButtonModel();
}
/**
* Creates a new submit button
*/
public SAbstractIconTextCompound() {
model = new SDefaultButtonModel();
}
public SButtonModel getModel() {
return model;
}
public void setModel(SButtonModel model) {
if (model == null)
throw new IllegalArgumentException("null not allowed");
SButtonModel oldVal = this.model;
this.model = model;
if (oldVal != null)
oldVal.addChangeListener(this);
model.addChangeListener(this);
reloadIfChange(this.model, model);
propertyChangeSupport.firePropertyChange("model", oldVal, this.model);
}
/**
* Gets called by the {@link SButtonModel} whenever the state change
*
* {@inheritDoc}
*/
@Override
public void stateChanged(ChangeEvent e) {
if(isUpdatePossible()) {
if(!SButton.class.isAssignableFrom(getClass()))
reload();
}
}
/**
* Returns the selected items or null if no items are selected.
*/
@Override
public Object[] getSelectedObjects() {
return model.isSelected() ? new Object[]{this} : null;
}
/**
* Returns an array of all the ItemListener
s added
* to this SAbstractIconTextCompound with addItemListener().
*
* @return all of the ItemListener
s added or an empty
* array if no listeners have been added
*/
public ItemListener[] getItemListeners() {
return (ItemListener[]) (getListeners(ItemListener.class));
}
/**
* Adds a ItemListener to the button.
*
* @see #removeItemListener(ItemListener)
*/
@Override
public void addItemListener(ItemListener il) {
addEventListener(ItemListener.class, il);
}
/**
* Remove the given itemListener from list of
* item listeners.
*
* @see #addItemListener(ItemListener)
*/
@Override
public void removeItemListener(ItemListener il) {
removeEventListener(ItemListener.class, il);
}
/**
* Returns an array of all the ChangeListener
s added
* to this SAbstractIconTextCompound with addChangeListener().
*
* @return all of the ChangeListener
s added or an empty
* array if no listeners have been added
*/
public ChangeListener[] getChangeListeners() {
return (ChangeListener[]) (getListeners(ChangeListener.class));
}
/**
* Adds a ChangeListener
to the button.
*
* @param l the listener to be added
*/
public void addChangeListener(ChangeListener l) {
addEventListener(ChangeListener.class, l);
}
/**
* Removes a ChangeListener from the button.
*
* @param l the listener to be removed
*/
public void removeChangeListener(ChangeListener l) {
removeEventListener(ChangeListener.class, l);
}
/**
* Notifies all listeners that have registered interest for
* notification on this event type. The event instance
* is lazily created using the parameters passed into
* the fire method.
*
* @see EventListenerList
*/
protected void fireStateChanged() {
// Guaranteed to return a non-null array
Object[] listeners = getListenerList();
// 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] == ChangeListener.class) {
// Lazily create the event:
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
}
}
}
public void setHorizontalTextPosition(int textPosition) {
int oldVal = this.horizontalTextPosition;
reloadIfChange(this.horizontalTextPosition, textPosition);
horizontalTextPosition = textPosition;
propertyChangeSupport.firePropertyChange("horizontalTextPosition", oldVal, this.horizontalTextPosition);
}
public int getHorizontalTextPosition() {
return horizontalTextPosition;
}
public void setVerticalTextPosition(int textPosition) {
int oldVal = this.verticalTextPosition;
reloadIfChange(this.verticalTextPosition, textPosition);
verticalTextPosition = textPosition;
propertyChangeSupport.firePropertyChange("verticalTextPosition", oldVal, this.verticalTextPosition);
}
public int getVerticalTextPosition() {
return verticalTextPosition;
}
public void setIconTextGap(int gap) {
int oldVal = this.iconTextGap;
reloadIfChange(this.iconTextGap, gap);
iconTextGap = gap;
propertyChangeSupport.firePropertyChange("iconTextGap", oldVal, this.iconTextGap);
}
public int getIconTextGap() {
return iconTextGap;
}
/**
* Sets the icon for the compound.
*
* @param i the icon.
*/
public void setIcon(SIcon i) {
SIcon oldVal = this.icon;
if (isDifferent(icon, i)) {
// do reload if previous icon was null
if (isUpdatePossible() && icon != null) {
if (SButton.class.isAssignableFrom(getClass()))
update(((ButtonCG) getCG()).getIconUpdate((SButton) this, i));
else if (SCheckBox.class.isAssignableFrom(getClass()))
update(((CheckBoxCG) getCG()).getIconUpdate((SCheckBox) this, i));
else if (SRadioButton.class.isAssignableFrom(getClass()))
update(((RadioButtonCG) getCG()).getIconUpdate((SRadioButton) this, i));
else if (SToggleButton.class.isAssignableFrom(getClass()))
update(((ToggleButtonCG) getCG()).getIconUpdate((SToggleButton) this, i));
else if (SClickable.class.isAssignableFrom(getClass()))
update(((ClickableCG) getCG()).getIconUpdate((SClickable) this, i));
else
reload();
}
else {
reload();
}
icon = i;
}
propertyChangeSupport.firePropertyChange("icon", oldVal, this.icon);
}
/**
* Returns the icon of the Compound.
*
* @see #setIcon(SIcon)
*/
public SIcon getIcon() {
return icon;
}
/**
* Sets the icon that is displayed when the compound is pressed with the mouse.
*
* @param icon to be shown when mouse button is pressed.
*/
public void setPressedIcon(SIcon icon) {
SIcon oldVal = this.pressedIcon;
reloadIfChange(pressedIcon, icon);
pressedIcon = icon;
propertyChangeSupport.firePropertyChange("pressedIcon", oldVal, this.pressedIcon);
}
/**
* Returns the icon that is displayed when a compound is pressed with the mouse.
*
* @see #setPressedIcon(SIcon)
*/
public SIcon getPressedIcon() {
return pressedIcon;
}
/**
* Sets the icon that is displayed as rollOver effect (meaning the icon
* shown when the mouse is just positioned over the compound).
*
* @param icon rollOver icon for unselected compound.
*/
public void setRolloverIcon(SIcon icon) {
SIcon oldVal = this.rolloverIcon;
reloadIfChange(rolloverIcon, icon);
rolloverIcon = icon;
propertyChangeSupport.firePropertyChange("rolloverIcon", oldVal, this.rolloverIcon);
}
/**
* Returns the icon that is displayed as rollOver effect (meaning the icon
* shown when the mouse is just positioned over the compound).
*
* @see #setRolloverIcon(SIcon)
*/
public SIcon getRolloverIcon() {
return rolloverIcon;
}
/**
* Sets the icon that is displayed as rollover effect of a selected compound
* (meaning the icon shown when the mouse is just positioned over the selected compound).
*
* @param icon rollOver icon for selected compound.
*/
public void setRolloverSelectedIcon(SIcon icon) {
SIcon oldVal = this.rolloverSelectedIcon;
reloadIfChange(rolloverSelectedIcon, icon);
rolloverSelectedIcon = icon;
propertyChangeSupport.firePropertyChange("rolloverSelectedIcon", oldVal, this.rolloverSelectedIcon);
}
/**
* Returns the the rollOver icon of a selected compound.
*
* @see #setRolloverSelectedIcon(SIcon)
*/
public SIcon getRolloverSelectedIcon() {
return rolloverSelectedIcon;
}
/**
* Sets the icon that is displayed when a compound is selected.
*
* @param icon to be shown for a selected compound.
*/
public void setSelectedIcon(SIcon icon) {
SIcon oldVal = this.selectedIcon;
reloadIfChange(selectedIcon, icon);
selectedIcon = icon;
propertyChangeSupport.firePropertyChange("selectedIcon", oldVal, this.selectedIcon);
}
/**
* Returns the icon of a selected compound.
*
* @see #setSelectedIcon(SIcon)
*/
public SIcon getSelectedIcon() {
return selectedIcon;
}
/**
* Sets the Icon that is displayed when a selected compound is disabled .
*
* @param icon to be shown for a selected compound that is disabled.
*/
public void setDisabledSelectedIcon(SIcon icon) {
SIcon oldVal = this.disabledSelectedIcon;
reloadIfChange(disabledSelectedIcon, icon);
disabledSelectedIcon = icon;
propertyChangeSupport.firePropertyChange("disabledSelectedIcon", oldVal, this.disabledSelectedIcon);
}
/**
* Returns the icon of a selected compound that is disabled.
*
* @see #setDisabledSelectedIcon(SIcon)
*/
public SIcon getDisabledSelectedIcon() {
return disabledSelectedIcon;
}
/**
* Sets the icon that is displayed when a compound is disabled.
*
* @param icon to be shown for a disabled compound.
*/
public void setDisabledIcon(SIcon icon) {
SIcon oldVal = this.disabledIcon;
reloadIfChange(disabledIcon, icon);
disabledIcon = icon;
propertyChangeSupport.firePropertyChange("disabledIcon", oldVal, this.disabledIcon);
}
/**
* Returns the the icon of a compound that is disabled.
*
* @see #setDisabledIcon(SIcon)
*/
public SIcon getDisabledIcon() {
// Creates disabled icon only for SImageIcons not for SURLIcons
/*
if(disabledIcon == null) {
if(icon != null && icon instanceof SImageIcon)
disabledIcon = new SImageIcon(GrayFilter.createDisabledImage(((SImageIcon)icon).getImage()));
}
*/
return disabledIcon;
}
/**
* Return the background color.
*
* @return the background color
*/
public Color getSelectionBackground() {
return dynamicStyles == null || dynamicStyles.get(SELECTOR_SELECTED) == null ? null : CSSStyleSheet.getBackground((CSSAttributeSet) dynamicStyles.get(SELECTOR_SELECTED));
}
/**
* Set the foreground color.
*
* @param color the new foreground color
*/
public void setSelectionBackground(Color color) {
Color oldVal = this.getSelectionBackground();
setAttribute(SELECTOR_SELECTED, CSSProperty.BACKGROUND_COLOR, CSSStyleSheet.getAttribute(color));
propertyChangeSupport.firePropertyChange("selectionBackground", oldVal, this.getSelectionBackground());
}
/**
* Return the foreground color.
*
* @return the foreground color
*/
public Color getSelectionForeground() {
return dynamicStyles == null || dynamicStyles.get(SELECTOR_SELECTED) == null ? null : CSSStyleSheet.getForeground((CSSAttributeSet) dynamicStyles.get(SELECTOR_SELECTED));
}
/**
* Set the foreground color.
*
* @param color the new foreground color
*/
public void setSelectionForeground(Color color) {
Color oldVal = this.getSelectionForeground();
setAttribute(SELECTOR_SELECTED, CSSProperty.COLOR, CSSStyleSheet.getAttribute(color));
propertyChangeSupport.firePropertyChange("selectionForeground", oldVal, this.getSelectionForeground());
}
/**
* Set the font.
*
* @param font the new font
*/
public void setSelectionFont(SFont font) {
SFont oldVal = this.getFont();
setAttributes(SELECTOR_SELECTED, CSSStyleSheet.getAttributes(font));
propertyChangeSupport.firePropertyChange("font", oldVal, this.getSelectionFont());
}
/**
* Return the font.
*
* @return the font
*/
public SFont getSelectionFont() {
return dynamicStyles == null || dynamicStyles.get(SELECTOR_SELECTED) == null ? null : CSSStyleSheet.getFont((CSSAttributeSet) dynamicStyles.get(SELECTOR_SELECTED));
}
/**
* Sets the label of the button.
*/
public void setText(String t) {
if (isDifferent(text, t)) {
String oldVal = this.text;
// do reload if previous text was null
if (isUpdatePossible() && text != null) {
if (SButton.class.isAssignableFrom(getClass()))
update(((ButtonCG) getCG()).getTextUpdate((SButton) this, t));
else if (SCheckBox.class.isAssignableFrom(getClass()))
update(((CheckBoxCG) getCG()).getTextUpdate((SCheckBox) this, t));
else if (SRadioButton.class.isAssignableFrom(getClass()))
update(((RadioButtonCG) getCG()).getTextUpdate((SRadioButton) this, t));
else if (SToggleButton.class.isAssignableFrom(getClass()))
update(((ToggleButtonCG) getCG()).getTextUpdate((SToggleButton) this, t));
else if (SClickable.class.isAssignableFrom(getClass()))
update(((ClickableCG) getCG()).getTextUpdate((SClickable) this, t));
else
reload();
}
else {
reload();
}
text = t;
propertyChangeSupport.firePropertyChange("text", oldVal, this.text);
}
}
/**
* Return the text of the button.
*
* @return the text
*/
public String getText() {
return text;
}
public boolean isSelected() {
return model.isSelected();
}
/**
* Toggle the selection. If the new selection
* is different to the old selection
* an {@link ItemEvent} is raised.
*/
public void setSelected(boolean selected) {
if (model.isSelected() != selected) {
boolean oldVal = model.isSelected();
model.setSelected(selected);
propertyChangeSupport.firePropertyChange("selected", oldVal, model.isSelected());
if (!delayEvents) {
fireStateChanged();
fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, this,
model.isSelected() ? ItemEvent.SELECTED : ItemEvent.DESELECTED));
delayedEvent = false;
}
else
delayedEvent = true;
reload();
}
}
/**
* Sets the proper icons for buttonstatus enabled resp. disabled.
*/
public void setIcons(SIcon... icons) {
setIcon(icons[ENABLED_ICON]);
setDisabledIcon(icons[DISABLED_ICON]);
setDisabledSelectedIcon(icons[DISABLED_SELECTED_ICON]);
setRolloverIcon(icons[ROLLOVER_ICON]);
setRolloverSelectedIcon(icons[ROLLOVER_SELECTED_ICON]);
setPressedIcon(icons[PRESSED_ICON]);
setSelectedIcon(icons[SELECTED_ICON]);
}
protected final void delayEvents(boolean b) {
delayEvents = b;
}
protected final boolean shouldDelayEvents() {
return delayEvents;
}
/**
* Reports a selection change.
*
* @param ie report this event to all listeners
* @see java.awt.event.ItemListener
* @see java.awt.ItemSelectable
*/
protected void fireItemStateChanged(ItemEvent ie) {
if (ie == null)
return;
// Guaranteed to return a non-null array
Object[] listeners = getListenerList();
// 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] == ItemListener.class) {
((ItemListener) listeners[i + 1]).itemStateChanged(ie);
}
}
}
public void fireIntermediateEvents() {}
@Override
public void fireFinalEvents() {
super.fireFinalEvents();
if (delayedEvent) {
fireStateChanged();
fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED, this,
model.isSelected() ? ItemEvent.SELECTED : ItemEvent.DESELECTED));
delayedEvent = false;
}
}
}