Merge from the pain train
[official-gcc.git] / libjava / javax / swing / DefaultButtonModel.java
blob0473f53bc211245b8308fb81f83901b6b3388802
1 /* DefaultButtonModel.java --
2 Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing;
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.event.ItemEvent;
44 import java.awt.event.ItemListener;
45 import java.awt.event.KeyEvent;
46 import java.io.Serializable;
47 import java.util.EventListener;
49 import javax.swing.event.ChangeEvent;
50 import javax.swing.event.ChangeListener;
51 import javax.swing.event.EventListenerList;
53 /**
54 * The purpose of this class is to model the dynamic state of an abstract
55 * button. The concrete button type holding this state may be a a "toggle"
56 * button (checkbox, radio button) or a "push" button (menu button, button).
57 * If the model is disabled, only the "selected" property can be changed. An
58 * attempt to change the "armed", "rollover" or "pressed" properties while
59 * the model is disabled will be blocked. Any successful (non-blocked) change
60 * to the model's properties will trigger the firing of a ChangeEvent. Any
61 * change to the "selected" property will trigger the firing of an ItemEvent
62 * in addition to ChangeEvent. This is true whether the model is enabled or
63 * not. One other state change is special: the transition from "enabled,
64 * armed and pressd" to "enabled, armed and not-pressed". This is considered
65 * the "trailing edge" of a successful mouse click, and therefore fires an
66 * ActionEvent in addition to a ChangeEvent. In all other respects this class
67 * is just a container of boolean flags.
69 * @author Graydon Hoare (graydon_at_redhat.com)
71 public class DefaultButtonModel implements ButtonModel, Serializable
73 /** DOCUMENT ME! */
74 private static final long serialVersionUID = -5342609566534980231L;
76 /**
77 * Indicates that the button is <em>partially</em> committed to being
78 * pressed, but not entirely. This usually happens when a user has pressed
79 * but not yet released the mouse button.
81 public static final int ARMED = 1;
83 /**
84 * State constant indicating that the button is enabled. Buttons cannot be
85 * pressed or selected unless they are enabled.
87 public static final int ENABLED = 8;
89 /**
90 * State constant indicating that the user is holding down the button. When
91 * this transitions from true to false, an ActionEvent may be fired,
92 * depending on the value of the "armed" property.
94 public static final int PRESSED = 4;
96 /**
97 * State constant indicating that the mouse is currently positioned over the
98 * button.
100 public static final int ROLLOVER = 16;
103 * State constant indicating that the button is selected. This constant is
104 * only meaningful for toggle-type buttons (radio buttons, checkboxes).
106 public static final int SELECTED = 2;
109 * Represents the "state properties" (armed, enabled, pressed, rollover and
110 * selected) by a bitwise combination of integer constants.
112 protected int stateMask = ENABLED;
115 * List of ItemListeners, ChangeListeners, and ActionListeners registered on
116 * this model.
118 protected EventListenerList listenerList = new EventListenerList();
121 /** The single ChangeEvent this model (re)uses to call its ChangeListeners. */
122 protected ChangeEvent changeEvent = new ChangeEvent(this);
125 * The group this model belongs to. Only one button in a group may be
126 * selected at any given time.
128 protected ButtonGroup group;
131 * The key code (one of {@link java.awt.event.KeyEvent} VK_) used to press
132 * this button via a keyboard interface.
134 protected int mnemonic = KeyEvent.VK_UNDEFINED;
137 * The string used as the "command" property of any ActionEvent this model
138 * sends.
140 protected String actionCommand;
143 * Creates a new DefaultButtonModel object.
145 public DefaultButtonModel()
150 * Return <code>null</code>. Use {@link AbstractButton} if you wish to
151 * interface with a button via an {@link ItemSelectable} interface.
153 * @return <code>null</code>
155 public Object[] getSelectedObjects()
157 return null;
161 * Returns a specified class of listeners.
163 * @param listenerType the type of listener to return
165 * @return array of listeners
167 public EventListener[] getListeners(Class listenerType)
169 return listenerList.getListeners(listenerType);
173 * Add an ActionListener to the model. Usually only called to subscribe an
174 * AbstractButton's listener to the model.
176 * @param l The listener to add
178 public void addActionListener(ActionListener l)
180 listenerList.add(ActionListener.class, l);
184 * Remove an ActionListener to the model. Usually only called to unsubscribe
185 * an AbstractButton's listener to the model.
187 * @param l The listener to remove
189 public void removeActionListener(ActionListener l)
191 listenerList.remove(ActionListener.class, l);
195 * Returns all registered <code>ActionListener</code> objects.
197 * @return array of <code>ActionListener</code> objects
199 public ActionListener[] getActionListeners()
201 return (ActionListener[]) listenerList.getListeners(ActionListener.class);
205 * Add an ItemListener to the model. Usually only called to subscribe an
206 * AbstractButton's listener to the model.
208 * @param l The listener to add
210 public void addItemListener(ItemListener l)
212 listenerList.add(ItemListener.class, l);
216 * Remove an ItemListener to the model. Usually only called to unsubscribe
217 * an AbstractButton's listener to the model.
219 * @param l The listener to remove
221 public void removeItemListener(ItemListener l)
223 listenerList.remove(ItemListener.class, l);
227 * Returns all registered <code>ItemListener</code> objects.
229 * @return array of <code>ItemListener</code> objects
231 public ItemListener[] getItemListeners()
233 return (ItemListener[]) listenerList.getListeners(ItemListener.class);
237 * Add a ChangeListener to the model. Usually only called to subscribe an
238 * AbstractButton's listener to the model.
240 * @param l The listener to add
242 public void addChangeListener(ChangeListener l)
244 listenerList.add(ChangeListener.class, l);
248 * Remove a ChangeListener to the model. Usually only called to unsubscribe
249 * an AbstractButton's listener to the model.
251 * @param l The listener to remove
253 public void removeChangeListener(ChangeListener l)
255 listenerList.remove(ChangeListener.class, l);
259 * Returns all registered <code>ChangeListener</code> objects.
261 * @return array of <code>ChangeListener</code> objects
263 public ChangeListener[] getChangeListeners()
265 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
269 * Inform each ItemListener in the {@link listenerList} that an ItemEvent
270 * has occurred. This happens in response to any change to the {@link
271 * stateMask} field.
273 * @param e The ItemEvent to fire
275 protected void fireItemStateChanged(ItemEvent e)
277 ItemListener[] ll = getItemListeners();
279 for (int i = 0; i < ll.length; i++)
280 ll[i].itemStateChanged(e);
284 * Inform each ActionListener in the {@link listenerList} that an
285 * ActionEvent has occurred. This happens in response to the any change to
286 * the {@link stateMask} field which makes the enabled, armed and pressed
287 * properties all simultaneously <code>true</code>.
289 * @param e The ActionEvent to fire
291 protected void fireActionPerformed(ActionEvent e)
293 ActionListener[] ll = getActionListeners();
295 for (int i = 0; i < ll.length; i++)
296 ll[i].actionPerformed(e);
300 * Inform each ChangeListener in the {@link listenerList} that a ChangeEvent
301 * has occurred. This happens in response to the any change to a property
302 * of the model.
304 protected void fireStateChanged()
306 ChangeListener[] ll = getChangeListeners();
308 for (int i = 0; i < ll.length; i++)
309 ll[i].stateChanged(changeEvent);
313 * Helper method to fire a ChangeEvent with the model as the event's source.
315 * @param stateflag DOCUMENT ME!
316 * @param b DOCUMENT ME!
318 private void changeState(int stateflag, boolean b)
320 int oldstate = stateMask;
321 int newstate;
323 if (b)
324 newstate = oldstate | stateflag;
325 else
326 newstate = oldstate & ~ stateflag;
328 if (oldstate == newstate)
329 return;
331 if ((stateflag != SELECTED) && (stateflag != ENABLED)
332 && (stateMask & ENABLED) == 0)
333 return;
335 stateMask = newstate;
337 fireStateChanged();
339 if ((oldstate & SELECTED) == 0 && (newstate & SELECTED) == SELECTED)
341 fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
342 null, ItemEvent.SELECTED));
343 if (group != null)
344 group.setSelected(this, true);
347 else if ((oldstate & SELECTED) == SELECTED && (newstate & SELECTED) == 0)
349 fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
350 null, ItemEvent.DESELECTED));
351 if (group != null)
352 group.setSelected(this, false);
355 else if (((oldstate & ARMED) == ARMED && (oldstate & PRESSED) == PRESSED)
356 && ((newstate & ARMED) == ARMED && (newstate & PRESSED) == 0))
357 fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
358 actionCommand));
362 * Get the value of the model's "armed" property.
364 * @return The current "armed" property
366 public boolean isArmed()
368 return (stateMask & ARMED) == ARMED;
372 * Set the value of the model's "armed" property.
374 * @param a The new "armed" property
376 public void setArmed(boolean a)
378 changeState(ARMED, a);
382 * Get the value of the model's "enabled" property.
384 * @return The current "enabled" property.
386 public boolean isEnabled()
388 return (stateMask & ENABLED) == ENABLED;
392 * Set the value of the model's "enabled" property.
394 * @param e The new "enabled" property
396 public void setEnabled(boolean e)
398 changeState(ENABLED, e);
402 * Set the value of the model's "pressed" property.
404 * @param p The new "pressed" property
406 public void setPressed(boolean p)
408 changeState(PRESSED, p);
412 * Get the value of the model's "pressed" property.
414 * @return The current "pressed" property
416 public boolean isPressed()
418 return (stateMask & PRESSED) == PRESSED;
422 * Set the value of the model's "rollover" property.
424 * @param r The new "rollover" property
426 public void setRollover(boolean r)
428 changeState(ROLLOVER, r);
432 * Set the value of the model's "selected" property.
434 * @param s The new "selected" property
436 public void setSelected(boolean s)
438 changeState(SELECTED, s);
442 * Get the value of the model's "selected" property.
444 * @return The current "selected" property
446 public boolean isSelected()
448 return (stateMask & SELECTED) == SELECTED;
452 * Get the value of the model's "rollover" property.
454 * @return The current "rollover" property
456 public boolean isRollover()
458 return (stateMask & ROLLOVER) == ROLLOVER;
462 * Get the value of the model's "mnemonic" property.
464 * @return The current "mnemonic" property
466 public int getMnemonic()
468 return mnemonic;
472 * Set the value of the model's "mnemonic" property.
474 * @param key The new "mnemonic" property
476 public void setMnemonic(int key)
478 if (mnemonic != key)
480 mnemonic = key;
481 fireStateChanged();
486 * Set the value of the model's "actionCommand" property. This property is
487 * used as the "command" property of the {@link ActionEvent} fired from the
488 * model.
490 * @param s The new "actionCommand" property.
492 public void setActionCommand(String s)
494 if (actionCommand != s)
496 actionCommand = s;
497 fireStateChanged();
502 * Returns the current value of the model's "actionCommand" property.
504 * @return The current "actionCommand" property
506 public String getActionCommand()
508 return actionCommand;
512 * Set the value of the model's "group" property. The model is said to be a
513 * member of the {@link ButtonGroup} held in its "group" property, and only
514 * one model in a given group can have their "selected" property be
515 * <code>true</code> at a time.
517 * @param g The new "group" property
519 public void setGroup(ButtonGroup g)
521 if (group != g)
523 group = g;
524 fireStateChanged();
529 * Returns the current value of the model's "group" property.
531 * @return The value of the "group" property
533 public ButtonGroup getGroup()
535 return group;