1. 被觀察者(PropertyChangeListeners are fired on the event dispatching thread.)
package org.jdesktop.application;<br />import java.beans.PropertyChangeEvent;<br />import java.beans.PropertyChangeListener;<br />import java.beans.PropertyChangeSupport;<br />import javax.swing.SwingUtilities;<br />/**<br /> * An encapsulation of the PropertyChangeSupport methods based on<br /> * java.beans.PropertyChangeSupport. PropertyChangeListeners are fired on the<br /> * event dispatching thread.<br /> *<br /> * <p><br /> * Note: this class is only public because the so-called "fix" for javadoc bug<br /> * <a<br /> * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4780441">4780441</a><br /> * still fails to correctly document public methods inherited from a package<br /> * private class.<br /> */<br />public class AbstractBean {<br />private final PropertyChangeSupport pcs;<br />public AbstractBean() {<br />pcs = new EDTPropertyChangeSupport(this);<br />}<br />/**<br /> * Add a PropertyChangeListener to the listener list. The listener is<br /> * registered for all properties and its {@code propertyChange} method will<br /> * run on the event dispatching thread.<br /> * <p><br /> * If {@code listener} is null, no exception is thrown and no action is<br /> * taken.<br /> *<br /> * @param listener<br /> * the PropertyChangeListener to be added.<br /> * @see #removePropertyChangeListener<br /> * @see java.beans.PropertyChangeSupport#addPropertyChangeListener<br /> */<br />public void addPropertyChangeListener(PropertyChangeListener listener) {<br />pcs.addPropertyChangeListener(listener);<br />}<br />/**<br /> * Remove a PropertyChangeListener from the listener list.<br /> * <p><br /> * If {@code listener} is null, no exception is thrown and no action is<br /> * taken.<br /> *<br /> * @param listener<br /> * the PropertyChangeListener to be removed.<br /> * @see #addPropertyChangeListener<br /> * @see java.beans.PropertyChangeSupport#removePropertyChangeListener<br /> */<br />public void removePropertyChangeListener(PropertyChangeListener listener) {<br />pcs.removePropertyChangeListener(listener);<br />}<br />/**<br /> * Add a PropertyChangeListener for a specific property. The listener will<br /> * be invoked only when a call on firePropertyChange names that specific<br /> * property. The same listener object may be added more than once. For each<br /> * property, the listener will be invoked the number of times it was added<br /> * for that property. If <code>propertyName</code> or <code>listener</code><br /> * is null, no exception is thrown and no action is taken.<br /> *<br /> * @param propertyName<br /> * The name of the property to listen on.<br /> * @param listener<br /> * the PropertyChangeListener to be added<br /> * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(String,<br /> * PropertyChangeListener)<br /> */<br />public void addPropertyChangeListener(String propertyName,<br />PropertyChangeListener listener) {<br />pcs.addPropertyChangeListener(propertyName, listener);<br />}<br />/**<br /> * Remove a PropertyChangeListener for a specific property. If<br /> * <code>listener</code> was added more than once to the same event source<br /> * for the specified property, it will be notified one less time after being<br /> * removed. If <code>propertyName</code> is null, no exception is thrown and<br /> * no action is taken. If <code>listener</code> is null, or was never added<br /> * for the specified property, no exception is thrown and no action is<br /> * taken.<br /> *<br /> * @param propertyName<br /> * The name of the property that was listened on.<br /> * @param listener<br /> * The PropertyChangeListener to be removed<br /> * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(String,<br /> * PropertyChangeListener)<br /> */<br />public synchronized void removePropertyChangeListener(String propertyName,<br />PropertyChangeListener listener) {<br />pcs.removePropertyChangeListener(propertyName, listener);<br />}<br />/**<br /> * An array of all of the {@code PropertyChangeListeners} added so far.<br /> *<br /> * @return all of the {@code PropertyChangeListeners} added so far.<br /> * @see java.beans.PropertyChangeSupport#getPropertyChangeListeners<br /> */<br />public PropertyChangeListener[] getPropertyChangeListeners() {<br />return pcs.getPropertyChangeListeners();<br />}<br />/**<br /> * Called whenever the value of a bound property is set.<br /> * <p><br /> * If oldValue is not equal to newValue, invoke the {@code propertyChange}<br /> * method on all of the {@code PropertyChangeListeners} added so far, on the<br /> * event dispatching thread.<br /> *<br /> * @see #addPropertyChangeListener<br /> * @see #removePropertyChangeListener<br /> * @see java.beans.PropertyChangeSupport#firePropertyChange(String, Object,<br /> * Object)<br /> */<br />protected void firePropertyChange(String propertyName, Object oldValue,<br />Object newValue) {<br />if (oldValue != null && newValue != null && oldValue.equals(newValue)) {<br />return;<br />}<br />pcs.firePropertyChange(propertyName, oldValue, newValue);<br />}<br />/**<br /> * Fire an existing PropertyChangeEvent<br /> * <p><br /> * If the event's oldValue property is not equal to newValue, invoke the<br /> * {@code propertyChange} method on all of the {@code<br /> * PropertyChangeListeners} added so far, on the event dispatching thread.<br /> *<br /> * @see #addPropertyChangeListener<br /> * @see #removePropertyChangeListener<br /> * @see java.beans.PropertyChangeSupport#firePropertyChange(PropertyChangeEvent<br /> * e)<br /> */<br />protected void firePropertyChange(PropertyChangeEvent e) {<br />pcs.firePropertyChange(e);<br />}<br />private static class EDTPropertyChangeSupport extends PropertyChangeSupport {<br />EDTPropertyChangeSupport(Object source) {<br />super(source);<br />}<br />public void firePropertyChange(final PropertyChangeEvent e) {<br />if (SwingUtilities.isEventDispatchThread()) {<br />super.firePropertyChange(e);<br />} else {<br />Runnable doFirePropertyChange = new Runnable() {<br />public void run() {<br />firePropertyChange(e);<br />}<br />};<br />SwingUtilities.invokeLater(doFirePropertyChange);<br />}<br />}<br />}<br />}<br />
2. 觀察者
/*<br /> * @(#)PropertyChangeListener.java1.18 05/11/17<br /> *<br /> * Copyright 2006 Sun Microsystems, Inc. All rights reserved.<br /> * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.<br /> */<br />package java.beans;<br />/**<br /> * A "PropertyChange" event gets fired whenever a bean changes a "bound"<br /> * property. You can register a PropertyChangeListener with a source<br /> * bean so as to be notified of any bound property updates.<br /> */<br />public interface PropertyChangeListener extends java.util.EventListener {<br /> /**<br /> * This method gets called when a bound property is changed.<br /> * @param evt A PropertyChangeEvent object describing the event source<br /> * and the property that has changed.<br /> */<br /> void propertyChange(PropertyChangeEvent evt);<br />}<br />