summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/DefaultButtonModel.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/DefaultButtonModel.java')
-rw-r--r--libjava/classpath/javax/swing/DefaultButtonModel.java578
1 files changed, 578 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/DefaultButtonModel.java b/libjava/classpath/javax/swing/DefaultButtonModel.java
new file mode 100644
index 000000000..d29a23ed3
--- /dev/null
+++ b/libjava/classpath/javax/swing/DefaultButtonModel.java
@@ -0,0 +1,578 @@
+/* DefaultButtonModel.java --
+ Copyright (C) 2002, 2004, 2006, Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.ItemSelectable;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
+import java.io.Serializable;
+import java.util.EventListener;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+
+/**
+ * The default implementation of {@link ButtonModel}.
+ * The purpose of this class is to model the dynamic state of an abstract
+ * button. The concrete button type holding this state may be a a "toggle"
+ * button (checkbox, radio button) or a "push" button (menu button, button).
+ * If the model is disabled, only the "selected" property can be changed. An
+ * attempt to change the "armed", "rollover" or "pressed" properties while
+ * the model is disabled will be blocked. Any successful (non-blocked) change
+ * to the model's properties will trigger the firing of a ChangeEvent. Any
+ * change to the "selected" property will trigger the firing of an ItemEvent
+ * in addition to ChangeEvent. This is true whether the model is enabled or
+ * not. One other state change is special: the transition from "enabled,
+ * armed and pressed" to "enabled, armed and not-pressed". This is considered
+ * the "trailing edge" of a successful mouse click, and therefore fires an
+ * ActionEvent in addition to a ChangeEvent. In all other respects this class
+ * is just a container of boolean flags.
+ *
+ * @author Graydon Hoare (graydon_at_redhat.com)
+ */
+public class DefaultButtonModel implements ButtonModel, Serializable
+{
+ /** DOCUMENT ME! */
+ private static final long serialVersionUID = -5342609566534980231L;
+
+ /**
+ * Indicates that the button is <em>partially</em> committed to being
+ * pressed, but not entirely. This usually happens when a user has pressed
+ * but not yet released the mouse button.
+ */
+ public static final int ARMED = 1;
+
+ /**
+ * State constant indicating that the button is enabled. Buttons cannot be
+ * pressed or selected unless they are enabled.
+ */
+ public static final int ENABLED = 8;
+
+ /**
+ * State constant indicating that the user is holding down the button. When
+ * this transitions from true to false, an ActionEvent may be fired,
+ * depending on the value of the "armed" property.
+ */
+ public static final int PRESSED = 4;
+
+ /**
+ * State constant indicating that the mouse is currently positioned over the
+ * button.
+ */
+ public static final int ROLLOVER = 16;
+
+ /**
+ * State constant indicating that the button is selected. This constant is
+ * only meaningful for toggle-type buttons (radio buttons, checkboxes).
+ */
+ public static final int SELECTED = 2;
+
+ /**
+ * Represents the "state properties" (armed, enabled, pressed, rollover and
+ * selected) by a bitwise combination of integer constants.
+ */
+ protected int stateMask = ENABLED;
+
+ /**
+ * List of ItemListeners, ChangeListeners, and ActionListeners registered on
+ * this model.
+ */
+ protected EventListenerList listenerList = new EventListenerList();
+
+ /** The single ChangeEvent this model (re)uses to call its ChangeListeners. */
+ protected ChangeEvent changeEvent = new ChangeEvent(this);
+
+ /**
+ * The group this model belongs to. Only one button in a group may be
+ * selected at any given time.
+ */
+ protected ButtonGroup group;
+
+ /**
+ * The key code (one of {@link java.awt.event.KeyEvent} VK_) used to press
+ * this button via a keyboard interface.
+ */
+ protected int mnemonic = KeyEvent.VK_UNDEFINED;
+
+ /**
+ * The string used as the "command" property of any ActionEvent this model
+ * sends.
+ */
+ protected String actionCommand;
+
+ /**
+ * Creates a new DefaultButtonModel object.
+ */
+ public DefaultButtonModel()
+ {
+ // Nothing to do here.
+ }
+
+ /**
+ * Return <code>null</code>. Use {@link AbstractButton} if you wish to
+ * interface with a button via an {@link ItemSelectable} interface.
+ *
+ * @return <code>null</code>
+ */
+ public Object[] getSelectedObjects()
+ {
+ return null;
+ }
+
+ /**
+ * Returns a specified class of listeners.
+ *
+ * @param listenerType the type of listener to return
+ *
+ * @return array of listeners
+ */
+ public <T extends EventListener> T[] getListeners(Class<T> listenerType)
+ {
+ return listenerList.getListeners(listenerType);
+ }
+
+ /**
+ * Add an ActionListener to the model. Usually only called to subscribe an
+ * AbstractButton's listener to the model.
+ *
+ * @param l The listener to add
+ */
+ public void addActionListener(ActionListener l)
+ {
+ listenerList.add(ActionListener.class, l);
+ }
+
+ /**
+ * Remove an ActionListener to the model. Usually only called to unsubscribe
+ * an AbstractButton's listener to the model.
+ *
+ * @param l The listener to remove
+ */
+ public void removeActionListener(ActionListener l)
+ {
+ listenerList.remove(ActionListener.class, l);
+ }
+
+ /**
+ * Returns all registered <code>ActionListener</code> objects.
+ *
+ * @return array of <code>ActionListener</code> objects
+ */
+ public ActionListener[] getActionListeners()
+ {
+ return (ActionListener[]) listenerList.getListeners(ActionListener.class);
+ }
+
+ /**
+ * Add an ItemListener to the model. Usually only called to subscribe an
+ * AbstractButton's listener to the model.
+ *
+ * @param l The listener to add
+ */
+ public void addItemListener(ItemListener l)
+ {
+ listenerList.add(ItemListener.class, l);
+ }
+
+ /**
+ * Remove an ItemListener to the model. Usually only called to unsubscribe
+ * an AbstractButton's listener to the model.
+ *
+ * @param l The listener to remove
+ */
+ public void removeItemListener(ItemListener l)
+ {
+ listenerList.remove(ItemListener.class, l);
+ }
+
+ /**
+ * Returns all registered <code>ItemListener</code> objects.
+ *
+ * @return array of <code>ItemListener</code> objects
+ */
+ public ItemListener[] getItemListeners()
+ {
+ return (ItemListener[]) listenerList.getListeners(ItemListener.class);
+ }
+
+ /**
+ * Add a ChangeListener to the model. Usually only called to subscribe an
+ * AbstractButton's listener to the model.
+ *
+ * @param l The listener to add
+ */
+ public void addChangeListener(ChangeListener l)
+ {
+ listenerList.add(ChangeListener.class, l);
+ }
+
+ /**
+ * Remove a ChangeListener to the model. Usually only called to unsubscribe
+ * an AbstractButton's listener to the model.
+ *
+ * @param l The listener to remove
+ */
+ public void removeChangeListener(ChangeListener l)
+ {
+ listenerList.remove(ChangeListener.class, l);
+ }
+
+ /**
+ * Returns all registered <code>ChangeListener</code> objects.
+ *
+ * @return array of <code>ChangeListener</code> objects
+ */
+ public ChangeListener[] getChangeListeners()
+ {
+ return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
+ }
+
+ /**
+ * Inform each ItemListener in the {@link #listenerList} that an ItemEvent
+ * has occurred. This happens in response to any change to the {@link
+ * #stateMask} field.
+ *
+ * @param e The ItemEvent to fire
+ */
+ protected void fireItemStateChanged(ItemEvent e)
+ {
+ ItemListener[] ll = getItemListeners();
+
+ for (int i = 0; i < ll.length; i++)
+ ll[i].itemStateChanged(e);
+ }
+
+ /**
+ * Inform each ActionListener in the {@link #listenerList} that an
+ * ActionEvent has occurred. This happens in response to the any change to
+ * the {@link #stateMask} field which makes the enabled, armed and pressed
+ * properties all simultaneously <code>true</code>.
+ *
+ * @param e The ActionEvent to fire
+ */
+ protected void fireActionPerformed(ActionEvent e)
+ {
+ ActionListener[] ll = getActionListeners();
+
+ for (int i = 0; i < ll.length; i++)
+ ll[i].actionPerformed(e);
+ }
+
+ /**
+ * Inform each ChangeListener in the {@link #listenerList} that a ChangeEvent
+ * has occurred. This happens in response to the any change to a property
+ * of the model.
+ */
+ protected void fireStateChanged()
+ {
+ ChangeListener[] ll = getChangeListeners();
+
+ for (int i = 0; i < ll.length; i++)
+ ll[i].stateChanged(changeEvent);
+ }
+
+ /**
+ * Get the value of the model's "armed" property.
+ *
+ * @return The current "armed" property
+ */
+ public boolean isArmed()
+ {
+ return (stateMask & ARMED) == ARMED;
+ }
+
+ /**
+ * Set the value of the model's "armed" property.
+ *
+ * @param a The new "armed" property
+ */
+ public void setArmed(boolean a)
+ {
+ // if this call does not represent a CHANGE in state, then return
+ if ((a && isArmed()) || (!a && !isArmed()))
+ return;
+
+ // cannot change ARMED state unless button is enabled
+ if (!isEnabled())
+ return;
+
+ // make the change
+ if (a)
+ stateMask = stateMask | ARMED;
+ else
+ stateMask = stateMask & (~ARMED);
+
+ // notify interested ChangeListeners
+ fireStateChanged();
+ }
+
+ /**
+ * Get the value of the model's "enabled" property.
+ *
+ * @return The current "enabled" property.
+ */
+ public boolean isEnabled()
+ {
+ return (stateMask & ENABLED) == ENABLED;
+ }
+
+ /**
+ * Set the value of the model's "enabled" property.
+ *
+ * @param e The new "enabled" property
+ */
+ public void setEnabled(boolean e)
+ {
+ // if this call does not represent a CHANGE in state, then return
+ if ((e && isEnabled()) || (!e && !isEnabled()))
+ return;
+
+ // make the change
+ if (e)
+ stateMask = stateMask | ENABLED;
+ else
+ stateMask = stateMask & (~ENABLED) & (~ARMED) & (~PRESSED);
+
+ // notify interested ChangeListeners
+ fireStateChanged();
+ }
+
+ /**
+ * Set the value of the model's "pressed" property.
+ *
+ * @param p The new "pressed" property
+ */
+ public void setPressed(boolean p)
+ {
+ // if this call does not represent a CHANGE in state, then return
+ if ((p && isPressed()) || (!p && !isPressed()))
+ return;
+
+ // cannot changed PRESSED state unless button is enabled
+ if (!isEnabled())
+ return;
+
+ // make the change
+ if (p)
+ stateMask = stateMask | PRESSED;
+ else
+ stateMask = stateMask & (~PRESSED);
+
+ // if button is armed and was released, fire action event
+ if (!p && isArmed())
+ fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
+ actionCommand));
+
+ // notify interested ChangeListeners
+ fireStateChanged();
+ }
+
+ /**
+ * Get the value of the model's "pressed" property.
+ *
+ * @return The current "pressed" property
+ */
+ public boolean isPressed()
+ {
+ return (stateMask & PRESSED) == PRESSED;
+ }
+
+ /**
+ * Set the value of the model's "rollover" property.
+ *
+ * @param r The new "rollover" property
+ */
+ public void setRollover(boolean r)
+ {
+ // if this call does not represent a CHANGE in state, then return
+ if (r == isRollover())
+ return;
+
+ // cannot set ROLLOVER property unless button is enabled
+ if (!isEnabled())
+ return;
+
+ // make the change
+ if (r)
+ stateMask = stateMask | ROLLOVER;
+ else
+ stateMask = stateMask & (~ROLLOVER);
+
+ // notify interested ChangeListeners
+ fireStateChanged();
+ }
+
+ /**
+ * Set the value of the model's "selected" property.
+ *
+ * @param s The new "selected" property
+ */
+ public void setSelected(boolean s)
+ {
+ // if this call does not represent a CHANGE in state, then return
+ if ((s && isSelected()) || (!s && !isSelected()))
+ return;
+
+ // make the change
+ if (s)
+ stateMask = stateMask | SELECTED;
+ else
+ stateMask = stateMask & (~SELECTED);
+
+ // notify interested ChangeListeners
+ fireStateChanged();
+
+ // fire ItemStateChanged events
+ if (s)
+ {
+ fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+ this, ItemEvent.SELECTED));
+ if (group != null)
+ group.setSelected(this, true);
+ }
+ else
+ {
+ fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
+ this, ItemEvent.DESELECTED));
+ if (group != null)
+ group.setSelected(this, false);
+ }
+ }
+
+ /**
+ * Get the value of the model's "selected" property.
+ *
+ * @return The current "selected" property
+ */
+ public boolean isSelected()
+ {
+ return (stateMask & SELECTED) == SELECTED;
+ }
+
+ /**
+ * Get the value of the model's "rollover" property.
+ *
+ * @return The current "rollover" property
+ */
+ public boolean isRollover()
+ {
+ return (stateMask & ROLLOVER) == ROLLOVER;
+ }
+
+ /**
+ * Get the value of the model's "mnemonic" property.
+ *
+ * @return The current "mnemonic" property
+ */
+ public int getMnemonic()
+ {
+ return mnemonic;
+ }
+
+ /**
+ * Set the value of the model's "mnemonic" property.
+ *
+ * @param key The new "mnemonic" property
+ */
+ public void setMnemonic(int key)
+ {
+ if (mnemonic != key)
+ {
+ mnemonic = key;
+ fireStateChanged();
+ }
+ }
+
+ /**
+ * Set the value of the model's "actionCommand" property. This property is
+ * used as the "command" property of the {@link ActionEvent} fired from the
+ * model.
+ *
+ * @param s The new "actionCommand" property.
+ */
+ public void setActionCommand(String s)
+ {
+ if (actionCommand != s)
+ {
+ actionCommand = s;
+ fireStateChanged();
+ }
+ }
+
+ /**
+ * Returns the current value of the model's "actionCommand" property.
+ *
+ * @return The current "actionCommand" property
+ */
+ public String getActionCommand()
+ {
+ return actionCommand;
+ }
+
+ /**
+ * Set the value of the model's "group" property. The model is said to be a
+ * member of the {@link ButtonGroup} held in its "group" property, and only
+ * one model in a given group can have their "selected" property be
+ * <code>true</code> at a time.
+ *
+ * @param g The new "group" property (<code>null</code> permitted).
+ *
+ * @see #getGroup()
+ */
+ public void setGroup(ButtonGroup g)
+ {
+ group = g;
+ }
+
+ /**
+ * Returns the current value of the model's "group" property.
+ *
+ * @return The value of the "group" property
+ *
+ * @see #setGroup(ButtonGroup)
+ */
+ public ButtonGroup getGroup()
+ {
+ return group;
+ }
+}