All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jdesktop.beansbinding.PropertyHelper Maven / Gradle / Ivy

/***********************************************************************************************************************
 *
 * BetterBeansBinding - keeping JavaBeans in sync
 * ==============================================
 *
 * Copyright (C) 2009 by Tidalwave s.a.s. (http://www.tidalwave.it)
 * http://betterbeansbinding.kenai.com
 *
 * This is derived work from BeansBinding: http://beansbinding.dev.java.net
 * BeansBinding is copyrighted (C) by Sun Microsystems, Inc.
 *
 ***********************************************************************************************************************
 *
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ***********************************************************************************************************************
 *
 * $Id: PropertyHelper.java 63 2009-06-11 19:48:05Z fabriziogiudici $
 *
 **********************************************************************************************************************/
package org.jdesktop.beansbinding;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;

/**
 * An abstract subclass of {@code Property} that helps with the management of
 * {@code PropertyStateListeners} by implementing the methods for adding, removing,
 * and getting listeners. {@code PropertyHelper} can be constructed
 * to manage listeners for multiple source objects, or to ignore the source
 * object argument when dealing with listeners and associate them directly with
 * the {@code PropertyHelper} instance itself. This makes {@code PropertyHelper}
 * useful as a base for both property types described in the documentation for
 * {@code Property}.
 * 

* {@code PropertyHelper} also provides, by way of the protected methods * {@link #listeningStarted} and {@link #listeningStopped} a hook for subclasses * to know when it's time to start tracking changes to a particular source object. * * @param the type of source object that this {@code Property} operates on * @param the type of value that this {@code Property} represents * * @author Shannon Hickey */ public abstract class PropertyHelper extends Property { private final boolean ignoresSource; private Object listeners; /** * Create a {@code PropertyHelper} that manages listeners for multiple * source objects. */ public PropertyHelper() { this(false); } /** * Create a {@code PropertyHelper}, specifying whether it manages * listeners for multiple source objects, or ignores the source object * argument when dealing with listeners * * @param ignoresSource whether or not the source argument is ignored * when dealing with listeners */ public PropertyHelper(boolean ignoresSource) { this.ignoresSource = ignoresSource; } private List getListeners(S source, boolean create) { if (ignoresSource) { List list = (List) listeners; if ((list == null) && create) { list = new ArrayList(); listeners = list; } return list; } IdentityHashMap> map = (IdentityHashMap>) listeners; if (map == null) { if (create) { map = new IdentityHashMap>(); listeners = map; } else { return null; } } List list = map.get(source); if ((list == null) && create) { list = new ArrayList(); map.put(source, list); } return list; } /** * {@inheritDoc} * @throws UnsupportedOperationException {@inheritDoc} */ public abstract Class getWriteType(S source); /** * {@inheritDoc} * @throws UnsupportedOperationException {@inheritDoc} */ public abstract V getValue(S source); /** * {@inheritDoc} * @throws UnsupportedOperationException {@inheritDoc} */ public abstract void setValue(S source, V value); /** * {@inheritDoc} * @throws UnsupportedOperationException {@inheritDoc} */ public abstract boolean isReadable(S source); /** * {@inheritDoc} * @throws UnsupportedOperationException {@inheritDoc} */ public abstract boolean isWriteable(S source); /** * Called when this {@code PropertyHelper} changes from having * no listeners installed for the given source object to * having listeners installed for the given source object. This * is the ideal time for subclasses to install any listeners needed * to track change on the source object. * * @see #listeningStopped */ protected void listeningStarted(S source) { } /** * Called when this {@code PropertyHelper} changes from having * listeners installed for the given source object to * having no listeners installed for the given source object. This * is the ideal time for subclasses to remove any listeners that * they've installed to track changes on the source object. * * @see #listeningStopped */ protected void listeningStopped(S source) { } /** * {@inheritDoc} */ public final void addPropertyStateListener(S source, PropertyStateListener listener) { if (listener == null) { return; } List listeners = getListeners(source, true); boolean wasListening = (listeners.size() != 0); listeners.add(listener); if (!wasListening) { listeningStarted(ignoresSource ? null : source); } } /** * {@inheritDoc} */ public final void removePropertyStateListener(S source, PropertyStateListener listener) { if (listener == null) { return; } List listeners = getListeners(source, false); if (listeners == null) { return; } boolean wasListening = (listeners.size() != 0); listeners.remove(listener); if (wasListening && (listeners.size() == 0)) { listeningStopped(ignoresSource ? null : source); } } /** * {@inheritDoc} */ public final PropertyStateListener[] getPropertyStateListeners(S source) { List listeners = getListeners(source, false); if (listeners == null) { return new PropertyStateListener[0]; } PropertyStateListener[] ret = new PropertyStateListener[listeners.size()]; ret = listeners.toArray(ret); return ret; } /** * Notify listeners that the state of this property has changed, as * characterized by the given {@code PropertyStateEvent}. If this * {@code PropertyHelper} is managing listeners for multiple sources, only * the listeners associated with the object returned by the * {@code PropertyStateEvent's getSourceObject()} method are notified. * * @param pse the {@code PropertyStateEvent} characterizing the state change */ protected final void firePropertyStateChange(PropertyStateEvent pse) { List listeners = getListeners((S) pse.getSourceObject(), false); if (listeners == null) { return; } for (PropertyStateListener listener : listeners) { listener.propertyStateChanged(pse); } } /** * Returns whether or not there are any {@code PropertyStateListeners} * installed for the given source object. * * @param source the source object of interest * @return whether or not there are any {@code PropertyStateListeners} * installed for the given source object */ public final boolean isListening(S source) { List listeners = getListeners(source, false); return (listeners != null) && (listeners.size() != 0); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy