Path: blob/master/src/java.desktop/share/classes/javax/swing/DefaultButtonModel.java
41153 views
/*1* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/24package javax.swing;2526import java.awt.*;27import java.awt.event.*;28import java.awt.image.*;29import java.io.Serializable;30import java.util.EventListener;31import javax.swing.event.*;3233/**34* The default implementation of a <code>Button</code> component's data model.35* <p>36* <strong>Warning:</strong>37* Serialized objects of this class will not be compatible with38* future Swing releases. The current serialization support is39* appropriate for short term storage or RMI between applications running40* the same version of Swing. As of 1.4, support for long term storage41* of all JavaBeans42* has been added to the <code>java.beans</code> package.43* Please see {@link java.beans.XMLEncoder}.44*45* @author Jeff Dinkins46* @since 1.247*/48@SuppressWarnings("serial") // Same-version serialization only49public class DefaultButtonModel implements ButtonModel, Serializable {5051/** The bitmask used to store the state of the button. */52protected int stateMask = 0;5354/** The action command string fired by the button. */55protected String actionCommand = null;5657/** The button group that the button belongs to. */58protected ButtonGroup group = null;5960/** The button's mnemonic. */61protected int mnemonic = 0;6263/**64* Only one <code>ChangeEvent</code> is needed per button model65* instance since the event's only state is the source property.66* The source of events generated is always "this".67*/68protected transient ChangeEvent changeEvent = null;6970/** Stores the listeners on this model. */71protected EventListenerList listenerList = new EventListenerList();7273// controls the usage of the MenuItem.disabledAreNavigable UIDefaults74// property in the setArmed() method75private boolean menuItem = false;7677/**78* Constructs a <code>DefaultButtonModel</code>.79*80*/81public DefaultButtonModel() {82stateMask = 0;83setEnabled(true);84}8586/**87* Identifies the "armed" bit in the bitmask, which88* indicates partial commitment towards choosing/triggering89* the button.90*/91public static final int ARMED = 1 << 0;9293/**94* Identifies the "selected" bit in the bitmask, which95* indicates that the button has been selected. Only needed for96* certain types of buttons - such as radio button or check box.97*/98public static final int SELECTED = 1 << 1;99100/**101* Identifies the "pressed" bit in the bitmask, which102* indicates that the button is pressed.103*/104public static final int PRESSED = 1 << 2;105106/**107* Identifies the "enabled" bit in the bitmask, which108* indicates that the button can be selected by109* an input device (such as a mouse pointer).110*/111public static final int ENABLED = 1 << 3;112113/**114* Identifies the "rollover" bit in the bitmask, which115* indicates that the mouse is over the button.116*/117public static final int ROLLOVER = 1 << 4;118119/**120* {@inheritDoc}121*/122public void setActionCommand(String actionCommand) {123this.actionCommand = actionCommand;124}125126/**127* {@inheritDoc}128*/129public String getActionCommand() {130return actionCommand;131}132133/**134* {@inheritDoc}135*/136public boolean isArmed() {137return (stateMask & ARMED) != 0;138}139140/**141* {@inheritDoc}142*/143public boolean isSelected() {144return (stateMask & SELECTED) != 0;145}146147/**148* {@inheritDoc}149*/150public boolean isEnabled() {151return (stateMask & ENABLED) != 0;152}153154/**155* {@inheritDoc}156*/157public boolean isPressed() {158return (stateMask & PRESSED) != 0;159}160161/**162* {@inheritDoc}163*/164public boolean isRollover() {165return (stateMask & ROLLOVER) != 0;166}167168/**169* {@inheritDoc}170*/171public void setArmed(boolean b) {172if(isMenuItem() &&173UIManager.getBoolean("MenuItem.disabledAreNavigable")) {174if ((isArmed() == b)) {175return;176}177} else {178if ((isArmed() == b) || !isEnabled()) {179return;180}181}182183if (b) {184stateMask |= ARMED;185} else {186stateMask &= ~ARMED;187}188189fireStateChanged();190}191192/**193* {@inheritDoc}194*/195public void setEnabled(boolean b) {196if(isEnabled() == b) {197return;198}199200if (b) {201stateMask |= ENABLED;202} else {203stateMask &= ~ENABLED;204// unarm and unpress, just in case205stateMask &= ~ARMED;206stateMask &= ~PRESSED;207}208209210fireStateChanged();211}212213/**214* {@inheritDoc}215*/216public void setSelected(boolean b) {217if (this.isSelected() == b) {218return;219}220221if (b) {222stateMask |= SELECTED;223} else {224stateMask &= ~SELECTED;225}226227fireItemStateChanged(228new ItemEvent(this,229ItemEvent.ITEM_STATE_CHANGED,230this,231b ? ItemEvent.SELECTED : ItemEvent.DESELECTED));232233fireStateChanged();234235}236237238/**239* {@inheritDoc}240*/241@SuppressWarnings("deprecation")242public void setPressed(boolean b) {243if((isPressed() == b) || !isEnabled()) {244return;245}246247if (b) {248stateMask |= PRESSED;249} else {250stateMask &= ~PRESSED;251}252253if(!isPressed() && isArmed()) {254int modifiers = 0;255AWTEvent currentEvent = EventQueue.getCurrentEvent();256if (currentEvent instanceof InputEvent) {257modifiers = ((InputEvent)currentEvent).getModifiers();258} else if (currentEvent instanceof ActionEvent) {259modifiers = ((ActionEvent)currentEvent).getModifiers();260}261fireActionPerformed(262new ActionEvent(this, ActionEvent.ACTION_PERFORMED,263getActionCommand(),264EventQueue.getMostRecentEventTime(),265modifiers));266}267268fireStateChanged();269}270271/**272* {@inheritDoc}273*/274public void setRollover(boolean b) {275if((isRollover() == b) || !isEnabled()) {276return;277}278279if (b) {280stateMask |= ROLLOVER;281} else {282stateMask &= ~ROLLOVER;283}284285fireStateChanged();286}287288/**289* {@inheritDoc}290*/291public void setMnemonic(int key) {292mnemonic = key;293fireStateChanged();294}295296/**297* {@inheritDoc}298*/299public int getMnemonic() {300return mnemonic;301}302303/**304* {@inheritDoc}305*/306public void addChangeListener(ChangeListener l) {307listenerList.add(ChangeListener.class, l);308}309310/**311* {@inheritDoc}312*/313public void removeChangeListener(ChangeListener l) {314listenerList.remove(ChangeListener.class, l);315}316317/**318* Returns an array of all the change listeners319* registered on this <code>DefaultButtonModel</code>.320*321* @return all of this model's <code>ChangeListener</code>s322* or an empty323* array if no change listeners are currently registered324*325* @see #addChangeListener326* @see #removeChangeListener327*328* @since 1.4329*/330public ChangeListener[] getChangeListeners() {331return listenerList.getListeners(ChangeListener.class);332}333334/**335* Notifies all listeners that have registered interest for336* notification on this event type. The event instance337* is created lazily.338*339* @see EventListenerList340*/341protected void fireStateChanged() {342// Guaranteed to return a non-null array343Object[] listeners = listenerList.getListenerList();344// Process the listeners last to first, notifying345// those that are interested in this event346for (int i = listeners.length-2; i>=0; i-=2) {347if (listeners[i]==ChangeListener.class) {348// Lazily create the event:349if (changeEvent == null)350changeEvent = new ChangeEvent(this);351((ChangeListener)listeners[i+1]).stateChanged(changeEvent);352}353}354}355356/**357* {@inheritDoc}358*/359public void addActionListener(ActionListener l) {360listenerList.add(ActionListener.class, l);361}362363/**364* {@inheritDoc}365*/366public void removeActionListener(ActionListener l) {367listenerList.remove(ActionListener.class, l);368}369370/**371* Returns an array of all the action listeners372* registered on this <code>DefaultButtonModel</code>.373*374* @return all of this model's <code>ActionListener</code>s375* or an empty376* array if no action listeners are currently registered377*378* @see #addActionListener379* @see #removeActionListener380*381* @since 1.4382*/383public ActionListener[] getActionListeners() {384return listenerList.getListeners(ActionListener.class);385}386387/**388* Notifies all listeners that have registered interest for389* notification on this event type.390*391* @param e the <code>ActionEvent</code> to deliver to listeners392* @see EventListenerList393*/394protected void fireActionPerformed(ActionEvent e) {395// Guaranteed to return a non-null array396Object[] listeners = listenerList.getListenerList();397// Process the listeners last to first, notifying398// those that are interested in this event399for (int i = listeners.length-2; i>=0; i-=2) {400if (listeners[i]==ActionListener.class) {401// Lazily create the event:402// if (changeEvent == null)403// changeEvent = new ChangeEvent(this);404((ActionListener)listeners[i+1]).actionPerformed(e);405}406}407}408409/**410* {@inheritDoc}411*/412public void addItemListener(ItemListener l) {413listenerList.add(ItemListener.class, l);414}415416/**417* {@inheritDoc}418*/419public void removeItemListener(ItemListener l) {420listenerList.remove(ItemListener.class, l);421}422423/**424* Returns an array of all the item listeners425* registered on this <code>DefaultButtonModel</code>.426*427* @return all of this model's <code>ItemListener</code>s428* or an empty429* array if no item listeners are currently registered430*431* @see #addItemListener432* @see #removeItemListener433*434* @since 1.4435*/436public ItemListener[] getItemListeners() {437return listenerList.getListeners(ItemListener.class);438}439440/**441* Notifies all listeners that have registered interest for442* notification on this event type.443*444* @param e the <code>ItemEvent</code> to deliver to listeners445* @see EventListenerList446*/447protected void fireItemStateChanged(ItemEvent e) {448// Guaranteed to return a non-null array449Object[] listeners = listenerList.getListenerList();450// Process the listeners last to first, notifying451// those that are interested in this event452for (int i = listeners.length-2; i>=0; i-=2) {453if (listeners[i]==ItemListener.class) {454// Lazily create the event:455// if (changeEvent == null)456// changeEvent = new ChangeEvent(this);457((ItemListener)listeners[i+1]).itemStateChanged(e);458}459}460}461462/**463* Returns an array of all the objects currently registered as464* <code><em>Foo</em>Listener</code>s465* upon this model.466* <code><em>Foo</em>Listener</code>s467* are registered using the <code>add<em>Foo</em>Listener</code> method.468* <p>469* You can specify the <code>listenerType</code> argument470* with a class literal, such as <code><em>Foo</em>Listener.class</code>.471* For example, you can query a <code>DefaultButtonModel</code>472* instance <code>m</code>473* for its action listeners474* with the following code:475*476* <pre>ActionListener[] als = (ActionListener[])(m.getListeners(ActionListener.class));</pre>477*478* If no such listeners exist,479* this method returns an empty array.480*481* @param <T> the type of requested listeners482* @param listenerType the type of listeners requested;483* this parameter should specify an interface484* that descends from <code>java.util.EventListener</code>485* @return an array of all objects registered as486* <code><em>Foo</em>Listener</code>s487* on this model,488* or an empty array if no such489* listeners have been added490* @exception ClassCastException if <code>listenerType</code> doesn't491* specify a class or interface that implements492* <code>java.util.EventListener</code>493*494* @see #getActionListeners495* @see #getChangeListeners496* @see #getItemListeners497*498* @since 1.3499*/500public <T extends EventListener> T[] getListeners(Class<T> listenerType) {501return listenerList.getListeners(listenerType);502}503504/** Overridden to return <code>null</code>. */505public Object[] getSelectedObjects() {506return null;507}508509/**510* {@inheritDoc}511*/512public void setGroup(ButtonGroup group) {513this.group = group;514}515516/**517* Returns the group that the button belongs to.518* Normally used with radio buttons, which are mutually519* exclusive within their group.520*521* @return the <code>ButtonGroup</code> that the button belongs to522*523* @since 1.3524*/525public ButtonGroup getGroup() {526return group;527}528529boolean isMenuItem() {530return menuItem;531}532533void setMenuItem(boolean menuItem) {534this.menuItem = menuItem;535}536}537538539