2015-05-05 Yvan Roux <yvan.roux@linaro.org>
[official-gcc.git] / libjava / classpath / javax / swing / DefaultButtonModel.java
blobd29a23ed373f93194066036c3a8552e6025499a4
1 /* DefaultButtonModel.java --
2 Copyright (C) 2002, 2004, 2006, 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., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 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.ItemSelectable;
42 import java.awt.event.ActionEvent;
43 import java.awt.event.ActionListener;
44 import java.awt.event.ItemEvent;
45 import java.awt.event.ItemListener;
46 import java.awt.event.KeyEvent;
47 import java.io.Serializable;
48 import java.util.EventListener;
50 import javax.swing.event.ChangeEvent;
51 import javax.swing.event.ChangeListener;
52 import javax.swing.event.EventListenerList;
54 /**
55 * The default implementation of {@link ButtonModel}.
56 * The purpose of this class is to model the dynamic state of an abstract
57 * button. The concrete button type holding this state may be a a "toggle"
58 * button (checkbox, radio button) or a "push" button (menu button, button).
59 * If the model is disabled, only the "selected" property can be changed. An
60 * attempt to change the "armed", "rollover" or "pressed" properties while
61 * the model is disabled will be blocked. Any successful (non-blocked) change
62 * to the model's properties will trigger the firing of a ChangeEvent. Any
63 * change to the "selected" property will trigger the firing of an ItemEvent
64 * in addition to ChangeEvent. This is true whether the model is enabled or
65 * not. One other state change is special: the transition from "enabled,
66 * armed and pressed" to "enabled, armed and not-pressed". This is considered
67 * the "trailing edge" of a successful mouse click, and therefore fires an
68 * ActionEvent in addition to a ChangeEvent. In all other respects this class
69 * is just a container of boolean flags.
71 * @author Graydon Hoare (graydon_at_redhat.com)
73 public class DefaultButtonModel implements ButtonModel, Serializable
75 /** DOCUMENT ME! */
76 private static final long serialVersionUID = -5342609566534980231L;
78 /**
79 * Indicates that the button is <em>partially</em> committed to being
80 * pressed, but not entirely. This usually happens when a user has pressed
81 * but not yet released the mouse button.
83 public static final int ARMED = 1;
85 /**
86 * State constant indicating that the button is enabled. Buttons cannot be
87 * pressed or selected unless they are enabled.
89 public static final int ENABLED = 8;
91 /**
92 * State constant indicating that the user is holding down the button. When
93 * this transitions from true to false, an ActionEvent may be fired,
94 * depending on the value of the "armed" property.
96 public static final int PRESSED = 4;
98 /**
99 * State constant indicating that the mouse is currently positioned over the
100 * button.
102 public static final int ROLLOVER = 16;
105 * State constant indicating that the button is selected. This constant is
106 * only meaningful for toggle-type buttons (radio buttons, checkboxes).
108 public static final int SELECTED = 2;
111 * Represents the "state properties" (armed, enabled, pressed, rollover and
112 * selected) by a bitwise combination of integer constants.
114 protected int stateMask = ENABLED;
117 * List of ItemListeners, ChangeListeners, and ActionListeners registered on
118 * this model.
120 protected EventListenerList listenerList = new EventListenerList();
122 /** The single ChangeEvent this model (re)uses to call its ChangeListeners. */
123 protected ChangeEvent changeEvent = new ChangeEvent(this);
126 * The group this model belongs to. Only one button in a group may be
127 * selected at any given time.
129 protected ButtonGroup group;
132 * The key code (one of {@link java.awt.event.KeyEvent} VK_) used to press
133 * this button via a keyboard interface.
135 protected int mnemonic = KeyEvent.VK_UNDEFINED;
138 * The string used as the "command" property of any ActionEvent this model
139 * sends.
141 protected String actionCommand;
144 * Creates a new DefaultButtonModel object.
146 public DefaultButtonModel()
148 // Nothing to do here.
152 * Return <code>null</code>. Use {@link AbstractButton} if you wish to
153 * interface with a button via an {@link ItemSelectable} interface.
155 * @return <code>null</code>
157 public Object[] getSelectedObjects()
159 return null;
163 * Returns a specified class of listeners.
165 * @param listenerType the type of listener to return
167 * @return array of listeners
169 public <T extends EventListener> T[] getListeners(Class<T> listenerType)
171 return listenerList.getListeners(listenerType);
175 * Add an ActionListener to the model. Usually only called to subscribe an
176 * AbstractButton's listener to the model.
178 * @param l The listener to add
180 public void addActionListener(ActionListener l)
182 listenerList.add(ActionListener.class, l);
186 * Remove an ActionListener to the model. Usually only called to unsubscribe
187 * an AbstractButton's listener to the model.
189 * @param l The listener to remove
191 public void removeActionListener(ActionListener l)
193 listenerList.remove(ActionListener.class, l);
197 * Returns all registered <code>ActionListener</code> objects.
199 * @return array of <code>ActionListener</code> objects
201 public ActionListener[] getActionListeners()
203 return (ActionListener[]) listenerList.getListeners(ActionListener.class);
207 * Add an ItemListener to the model. Usually only called to subscribe an
208 * AbstractButton's listener to the model.
210 * @param l The listener to add
212 public void addItemListener(ItemListener l)
214 listenerList.add(ItemListener.class, l);
218 * Remove an ItemListener to the model. Usually only called to unsubscribe
219 * an AbstractButton's listener to the model.
221 * @param l The listener to remove
223 public void removeItemListener(ItemListener l)
225 listenerList.remove(ItemListener.class, l);
229 * Returns all registered <code>ItemListener</code> objects.
231 * @return array of <code>ItemListener</code> objects
233 public ItemListener[] getItemListeners()
235 return (ItemListener[]) listenerList.getListeners(ItemListener.class);
239 * Add a ChangeListener to the model. Usually only called to subscribe an
240 * AbstractButton's listener to the model.
242 * @param l The listener to add
244 public void addChangeListener(ChangeListener l)
246 listenerList.add(ChangeListener.class, l);
250 * Remove a ChangeListener to the model. Usually only called to unsubscribe
251 * an AbstractButton's listener to the model.
253 * @param l The listener to remove
255 public void removeChangeListener(ChangeListener l)
257 listenerList.remove(ChangeListener.class, l);
261 * Returns all registered <code>ChangeListener</code> objects.
263 * @return array of <code>ChangeListener</code> objects
265 public ChangeListener[] getChangeListeners()
267 return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
271 * Inform each ItemListener in the {@link #listenerList} that an ItemEvent
272 * has occurred. This happens in response to any change to the {@link
273 * #stateMask} field.
275 * @param e The ItemEvent to fire
277 protected void fireItemStateChanged(ItemEvent e)
279 ItemListener[] ll = getItemListeners();
281 for (int i = 0; i < ll.length; i++)
282 ll[i].itemStateChanged(e);
286 * Inform each ActionListener in the {@link #listenerList} that an
287 * ActionEvent has occurred. This happens in response to the any change to
288 * the {@link #stateMask} field which makes the enabled, armed and pressed
289 * properties all simultaneously <code>true</code>.
291 * @param e The ActionEvent to fire
293 protected void fireActionPerformed(ActionEvent e)
295 ActionListener[] ll = getActionListeners();
297 for (int i = 0; i < ll.length; i++)
298 ll[i].actionPerformed(e);
302 * Inform each ChangeListener in the {@link #listenerList} that a ChangeEvent
303 * has occurred. This happens in response to the any change to a property
304 * of the model.
306 protected void fireStateChanged()
308 ChangeListener[] ll = getChangeListeners();
310 for (int i = 0; i < ll.length; i++)
311 ll[i].stateChanged(changeEvent);
315 * Get the value of the model's "armed" property.
317 * @return The current "armed" property
319 public boolean isArmed()
321 return (stateMask & ARMED) == ARMED;
325 * Set the value of the model's "armed" property.
327 * @param a The new "armed" property
329 public void setArmed(boolean a)
331 // if this call does not represent a CHANGE in state, then return
332 if ((a && isArmed()) || (!a && !isArmed()))
333 return;
335 // cannot change ARMED state unless button is enabled
336 if (!isEnabled())
337 return;
339 // make the change
340 if (a)
341 stateMask = stateMask | ARMED;
342 else
343 stateMask = stateMask & (~ARMED);
345 // notify interested ChangeListeners
346 fireStateChanged();
350 * Get the value of the model's "enabled" property.
352 * @return The current "enabled" property.
354 public boolean isEnabled()
356 return (stateMask & ENABLED) == ENABLED;
360 * Set the value of the model's "enabled" property.
362 * @param e The new "enabled" property
364 public void setEnabled(boolean e)
366 // if this call does not represent a CHANGE in state, then return
367 if ((e && isEnabled()) || (!e && !isEnabled()))
368 return;
370 // make the change
371 if (e)
372 stateMask = stateMask | ENABLED;
373 else
374 stateMask = stateMask & (~ENABLED) & (~ARMED) & (~PRESSED);
376 // notify interested ChangeListeners
377 fireStateChanged();
381 * Set the value of the model's "pressed" property.
383 * @param p The new "pressed" property
385 public void setPressed(boolean p)
387 // if this call does not represent a CHANGE in state, then return
388 if ((p && isPressed()) || (!p && !isPressed()))
389 return;
391 // cannot changed PRESSED state unless button is enabled
392 if (!isEnabled())
393 return;
395 // make the change
396 if (p)
397 stateMask = stateMask | PRESSED;
398 else
399 stateMask = stateMask & (~PRESSED);
401 // if button is armed and was released, fire action event
402 if (!p && isArmed())
403 fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
404 actionCommand));
406 // notify interested ChangeListeners
407 fireStateChanged();
411 * Get the value of the model's "pressed" property.
413 * @return The current "pressed" property
415 public boolean isPressed()
417 return (stateMask & PRESSED) == PRESSED;
421 * Set the value of the model's "rollover" property.
423 * @param r The new "rollover" property
425 public void setRollover(boolean r)
427 // if this call does not represent a CHANGE in state, then return
428 if (r == isRollover())
429 return;
431 // cannot set ROLLOVER property unless button is enabled
432 if (!isEnabled())
433 return;
435 // make the change
436 if (r)
437 stateMask = stateMask | ROLLOVER;
438 else
439 stateMask = stateMask & (~ROLLOVER);
441 // notify interested ChangeListeners
442 fireStateChanged();
446 * Set the value of the model's "selected" property.
448 * @param s The new "selected" property
450 public void setSelected(boolean s)
452 // if this call does not represent a CHANGE in state, then return
453 if ((s && isSelected()) || (!s && !isSelected()))
454 return;
456 // make the change
457 if (s)
458 stateMask = stateMask | SELECTED;
459 else
460 stateMask = stateMask & (~SELECTED);
462 // notify interested ChangeListeners
463 fireStateChanged();
465 // fire ItemStateChanged events
466 if (s)
468 fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
469 this, ItemEvent.SELECTED));
470 if (group != null)
471 group.setSelected(this, true);
473 else
475 fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
476 this, ItemEvent.DESELECTED));
477 if (group != null)
478 group.setSelected(this, false);
483 * Get the value of the model's "selected" property.
485 * @return The current "selected" property
487 public boolean isSelected()
489 return (stateMask & SELECTED) == SELECTED;
493 * Get the value of the model's "rollover" property.
495 * @return The current "rollover" property
497 public boolean isRollover()
499 return (stateMask & ROLLOVER) == ROLLOVER;
503 * Get the value of the model's "mnemonic" property.
505 * @return The current "mnemonic" property
507 public int getMnemonic()
509 return mnemonic;
513 * Set the value of the model's "mnemonic" property.
515 * @param key The new "mnemonic" property
517 public void setMnemonic(int key)
519 if (mnemonic != key)
521 mnemonic = key;
522 fireStateChanged();
527 * Set the value of the model's "actionCommand" property. This property is
528 * used as the "command" property of the {@link ActionEvent} fired from the
529 * model.
531 * @param s The new "actionCommand" property.
533 public void setActionCommand(String s)
535 if (actionCommand != s)
537 actionCommand = s;
538 fireStateChanged();
543 * Returns the current value of the model's "actionCommand" property.
545 * @return The current "actionCommand" property
547 public String getActionCommand()
549 return actionCommand;
553 * Set the value of the model's "group" property. The model is said to be a
554 * member of the {@link ButtonGroup} held in its "group" property, and only
555 * one model in a given group can have their "selected" property be
556 * <code>true</code> at a time.
558 * @param g The new "group" property (<code>null</code> permitted).
560 * @see #getGroup()
562 public void setGroup(ButtonGroup g)
564 group = g;
568 * Returns the current value of the model's "group" property.
570 * @return The value of the "group" property
572 * @see #setGroup(ButtonGroup)
574 public ButtonGroup getGroup()
576 return group;