001    /*
002     * $Id: SwingPropertyChangeSupport.java,v 1.2 2006/04/20 00:14:17 gfx Exp $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    
022    package org.jdesktop.swingx.util;
023    
024    import java.beans.PropertyChangeSupport;
025    import java.beans.PropertyChangeEvent;
026    
027    import javax.swing.SwingUtilities;
028    
029    /**
030     * This subclass of {@code java.beans.PropertyChangeSupport} is almost
031     * identical in functionality. The only difference is if constructed with 
032     * {@code SwingPropertyChangeSupport(sourceBean, true)} it ensures
033     * listeners are only ever notified on the <i>Event Dispatch Thread</i>.
034     *
035     * @author Igor Kushnirskiy
036     * @version $Revision: 1.2 $ $Date: 2006/04/20 00:14:17 $
037     */
038    
039    public final class SwingPropertyChangeSupport extends PropertyChangeSupport {
040    
041        /**
042         * Constructs a SwingPropertyChangeSupport object.
043         *
044         * @param sourceBean  The bean to be given as the source for any
045         *        events.
046         * @throws NullPointerException if {@code sourceBean} is 
047         *         {@code null}
048         */
049        public SwingPropertyChangeSupport(Object sourceBean) {
050            this(sourceBean, false);
051        }
052    
053        /**
054         * Constructs a SwingPropertyChangeSupport object.
055         * 
056         * @param sourceBean the bean to be given as the source for any events
057         * @param notifyOnEDT whether to notify listeners on the <i>Event
058         *        Dispatch Thread</i> only
059         *
060         * @throws NullPointerException if {@code sourceBean} is 
061         *         {@code null}
062         * @since 1.6
063         */
064        public SwingPropertyChangeSupport(Object sourceBean, boolean notifyOnEDT) {
065            super(sourceBean);
066            this.notifyOnEDT = notifyOnEDT;
067        }
068    
069        /**
070         * {@inheritDoc}
071         *
072         * <p>
073         * If {@see #isNotifyOnEDT} is {@code true} and called off the
074         * <i>Event Dispatch Thread</i> this implementation uses 
075         * {@code SwingUtilities.invokeLater} to send out the notification
076         * on the <i>Event Dispatch Thread</i>. This ensures  listeners
077         * are only ever notified on the <i>Event Dispatch Thread</i>.
078         *
079         * @throws NullPointerException if {@code evt} is 
080         *         {@code null}
081         * @since 1.6
082         */
083        @Override
084        public void firePropertyChange(final PropertyChangeEvent evt) {
085            if (evt == null) {
086                throw new NullPointerException();
087            }
088            if (! isNotifyOnEDT()
089                || SwingUtilities.isEventDispatchThread()) {
090                super.firePropertyChange(evt);
091            } else {
092                SwingUtilities.invokeLater(
093                    new Runnable() {
094                        public void run() {
095                            firePropertyChange(evt);
096                        }
097                    });
098            }
099        }
100    
101        /**
102         * Returns {@code notifyOnEDT} property.
103         * 
104         * @return {@code notifyOnEDT} property
105         * @see #SwingPropertyChangeSupport(Object sourceBean, boolean notifyOnEDT)
106         * @since 1.6
107         */
108        public final boolean isNotifyOnEDT() {
109            return notifyOnEDT;
110        }
111    
112        // Serialization version ID
113        static final long serialVersionUID = 7162625831330845068L;
114    
115        /**
116         * whether to notify listeners on EDT
117         * 
118         * @serial 
119         * @since 1.6
120         */ 
121        private final boolean notifyOnEDT;
122    }