diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:03:55 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:03:55 -0800 |
commit | dd828f42a5c83b4270d4fbf6fce2da1878f1e84a (patch) | |
tree | fdd4b68fa1020f2b6426034c94823419a7236200 /awt-kernel | |
parent | fdb2704414a9ed92394ada0d1395e4db86889465 (diff) | |
download | libcore-dd828f42a5c83b4270d4fbf6fce2da1878f1e84a.zip libcore-dd828f42a5c83b4270d4fbf6fce2da1878f1e84a.tar.gz libcore-dd828f42a5c83b4270d4fbf6fce2da1878f1e84a.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'awt-kernel')
5 files changed, 782 insertions, 0 deletions
diff --git a/awt-kernel/src/main/java/java/beans/IndexedPropertyChangeEvent.java b/awt-kernel/src/main/java/java/beans/IndexedPropertyChangeEvent.java new file mode 100644 index 0000000..5bd4b2e --- /dev/null +++ b/awt-kernel/src/main/java/java/beans/IndexedPropertyChangeEvent.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package java.beans; + +/** + * A type of {@link PropertyChangeEvent} that indicates that an indexed property + * has changed. + * + * @since Android 1.0 + */ +public class IndexedPropertyChangeEvent extends PropertyChangeEvent { + + private static final long serialVersionUID = -320227448495806870L; + + private final int index; + + /** + * Creates a new property changed event with an indication of the property + * index. + * + * @param source + * the changed bean. + * @param propertyName + * the changed property, or <code>null</code> to indicate an + * unspecified set of the properties has changed. + * @param oldValue + * the previous value of the property, or <code>null</code> if + * the <code>propertyName</code> is <code>null</code> or the + * previous value is unknown. + * @param newValue + * the new value of the property, or <code>null</code> if the + * <code>propertyName</code> is <code>null</code> or the new + * value is unknown.. + * @param index + * the index of the property. + */ + public IndexedPropertyChangeEvent(Object source, String propertyName, + Object oldValue, Object newValue, int index) { + super(source, propertyName, oldValue, newValue); + this.index = index; + } + + /** + * Answer the index of the property that was changed in this event. + * + * @return the property element index. + */ + public int getIndex() { + return index; + } +} diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeEvent.java b/awt-kernel/src/main/java/java/beans/PropertyChangeEvent.java new file mode 100644 index 0000000..04caed8 --- /dev/null +++ b/awt-kernel/src/main/java/java/beans/PropertyChangeEvent.java @@ -0,0 +1,116 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.beans; + +import java.util.EventObject; + +/** + * An event that indicates that a constraint or a boundary of a property has + * changed. + * + * @since Android 1.0 + */ +public class PropertyChangeEvent extends EventObject { + + private static final long serialVersionUID = 7042693688939648123L; + + String propertyName; + + Object oldValue; + + Object newValue; + + Object propagationId; + + /** + * The constructor used to create a new {@code PropertyChangeEvent}. + * + * @param source + * the changed bean. + * @param propertyName + * the changed property, or <code>null</code> to indicate an + * unspecified set of the properties has changed. + * @param oldValue + * the previous value of the property, or <code>null</code> if + * the <code>propertyName</code> is <code>null</code> or the + * previous value is unknown. + * @param newValue + * the new value of the property, or <code>null</code> if the + * <code>propertyName</code> is <code>null</code> or the new + * value is unknown. + */ + public PropertyChangeEvent(Object source, String propertyName, + Object oldValue, Object newValue) { + super(source); + + this.propertyName = propertyName; + this.oldValue = oldValue; + this.newValue = newValue; + } + + /** + * Returns the name of the property that has changed. If an unspecified set + * of properties has changed it returns null. + * + * @return the name of the property that has changed, or null. + */ + public String getPropertyName() { + return propertyName; + } + + /** + * Sets the propagationId object. + * + * @see #getPropagationId() + */ + public void setPropagationId(Object propagationId) { + this.propagationId = propagationId; + } + + /** + * Returns the propagationId object. This is reserved for future use. Beans + * 1.0 demands that a listener receiving this property and then sending its + * own PropertyChangeEvent sets the received propagationId on the new + * PropertyChangeEvent's propagationId field. + * + * @return the propagationId object. + */ + public Object getPropagationId() { + return propagationId; + } + + /** + * Returns the old value that the property had. If the old value is unknown + * this method returns null. + * + * @return the old property value or null. + */ + public Object getOldValue() { + return oldValue; + } + + /** + * Returns the new value that the property now has. If the new value is + * unknown this method returns null. + * + * @return the old property value or null. + */ + public Object getNewValue() { + return newValue; + } +} diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeListener.java b/awt-kernel/src/main/java/java/beans/PropertyChangeListener.java new file mode 100644 index 0000000..2515792 --- /dev/null +++ b/awt-kernel/src/main/java/java/beans/PropertyChangeListener.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.beans; + +import java.util.EventListener; + +/** + * A PropertyChangeListener can subscribe with a event source. Whenever that + * source raises a PropertyChangeEvent this listener will get notified. + * + * @since Android 1.0 + */ +public interface PropertyChangeListener extends EventListener { + + /** + * The source bean calls this method when an event is raised. + * + * @param event + * the {@link PropertyChangeEvent} object which contains the name + * and the old and new value of the property that has changed. + */ + public void propertyChange(PropertyChangeEvent event); +} diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeListenerProxy.java b/awt-kernel/src/main/java/java/beans/PropertyChangeListenerProxy.java new file mode 100644 index 0000000..d27e4eb --- /dev/null +++ b/awt-kernel/src/main/java/java/beans/PropertyChangeListenerProxy.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.beans; + +import java.util.EventListenerProxy; + +/** + * The implementation of this listener proxy just delegates the received events + * to its listener. + * + * @since Android 1.0 + */ +public class PropertyChangeListenerProxy extends EventListenerProxy implements + PropertyChangeListener { + + String propertyName; + + /** + * Creates a new listener proxy that associates a listener with a property + * name. + * + * @param propertyName + * the name of the associated property. + * @param listener + * the listener to delegate incoming events to. + */ + public PropertyChangeListenerProxy(String propertyName, + PropertyChangeListener listener) { + super(listener); + this.propertyName = propertyName; + } + + /** + * Returns the name of the property associated with this listener proxy. + * + * @return the name of the associated property. + */ + public String getPropertyName() { + return propertyName; + } + + public void propertyChange(PropertyChangeEvent event) { + PropertyChangeListener listener = (PropertyChangeListener) getListener(); + listener.propertyChange(event); + } +} diff --git a/awt-kernel/src/main/java/java/beans/PropertyChangeSupport.java b/awt-kernel/src/main/java/java/beans/PropertyChangeSupport.java new file mode 100644 index 0000000..9225d95 --- /dev/null +++ b/awt-kernel/src/main/java/java/beans/PropertyChangeSupport.java @@ -0,0 +1,501 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package java.beans; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * This utility class + * + */ +public class PropertyChangeSupport implements Serializable { + + private static final long serialVersionUID = 6401253773779951803l; + + private transient Object sourceBean; + + private transient List<PropertyChangeListener> allPropertiesChangeListeners = + new ArrayList<PropertyChangeListener>(); + + private transient Map<String, List<PropertyChangeListener>> + selectedPropertiesChangeListeners = + new HashMap<String, List<PropertyChangeListener>>(); + + // fields for serialization compatibility + private Hashtable<String, List<PropertyChangeListener>> children; + + private Object source; + + private int propertyChangeSupportSerializedDataVersion = 1; + + /** + * Creates a new instance that uses the source bean as source for any event. + * + * @param sourceBean + * the bean used as source for all events. + */ + public PropertyChangeSupport(Object sourceBean) { + if (sourceBean == null) { + throw new NullPointerException(); + } + this.sourceBean = sourceBean; + } + + /** + * Fires a {@link PropertyChangeEvent} with the given name, old value and + * new value. As source the bean used to initialize this instance is used. + * If the old value and the new value are not null and equal the event will + * not be fired. + * + * @param propertyName + * the name of the property + * @param oldValue + * the old value of the property + * @param newValue + * the new value of the property + */ + public void firePropertyChange(String propertyName, Object oldValue, + Object newValue) { + PropertyChangeEvent event = createPropertyChangeEvent(propertyName, + oldValue, newValue); + doFirePropertyChange(event); + } + + /** + * Fires an {@link IndexedPropertyChangeEvent} with the given name, old + * value, new value and index. As source the bean used to initialize this + * instance is used. If the old value and the new value are not null and + * equal the event will not be fired. + * + * @param propertyName + * the name of the property + * @param index + * the index + * @param oldValue + * the old value of the property + * @param newValue + * the new value of the property + */ + public void fireIndexedPropertyChange(String propertyName, int index, + Object oldValue, Object newValue) { + + // nulls and equals check done in doFire... + doFirePropertyChange(new IndexedPropertyChangeEvent(sourceBean, + propertyName, oldValue, newValue, index)); + } + + /** + * Removes the listener from the specific property. This only happens if it + * was registered to this property. Nothing happens if it was not + * registered with this property or if the property name or the listener is + * null. + * + * @param propertyName + * the property name the listener is listening to + * @param listener + * the listener to remove + */ + public synchronized void removePropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + if ((propertyName != null) && (listener != null)) { + List<PropertyChangeListener> listeners = + selectedPropertiesChangeListeners.get(propertyName); + + if (listeners != null) { + listeners.remove(listener); + } + } + } + + /** + * Adds a listener to a specific property. Nothing happens if the property + * name or the listener is null. + * + * @param propertyName + * the name of the property + * @param listener + * the listener to register for the property with the given name + */ + public synchronized void addPropertyChangeListener(String propertyName, + PropertyChangeListener listener) { + if ((listener != null) && (propertyName != null)) { + List<PropertyChangeListener> listeners = + selectedPropertiesChangeListeners.get(propertyName); + + if (listeners == null) { + listeners = new ArrayList<PropertyChangeListener>(); + selectedPropertiesChangeListeners.put(propertyName, listeners); + } + + // RI compatibility + if (listener instanceof PropertyChangeListenerProxy) { + PropertyChangeListenerProxy proxy = + (PropertyChangeListenerProxy) listener; + + listeners.add(new PropertyChangeListenerProxy( + proxy.getPropertyName(), + (PropertyChangeListener) proxy.getListener())); + } else { + listeners.add(listener); + } + } + } + + /** + * Returns an array of listeners that registered to the property with the + * given name. If the property name is null an empty array is returned. + * + * @param propertyName + * the name of the property whose listeners should be returned + * @return the array of listeners to the property with the given name. + */ + public synchronized PropertyChangeListener[] getPropertyChangeListeners( + String propertyName) { + List<PropertyChangeListener> listeners = null; + + if (propertyName != null) { + listeners = selectedPropertiesChangeListeners.get(propertyName); + } + + return (listeners == null) ? new PropertyChangeListener[] {} + : listeners.toArray( + new PropertyChangeListener[listeners.size()]); + } + + /** + * Fires a property change of a boolean property with the given name. If the + * old value and the new value are not null and equal the event will not be + * fired. + * + * @param propertyName + * the property name + * @param oldValue + * the old value + * @param newValue + * the new value + */ + public void firePropertyChange(String propertyName, boolean oldValue, + boolean newValue) { + PropertyChangeEvent event = createPropertyChangeEvent(propertyName, + oldValue, newValue); + doFirePropertyChange(event); + } + + /** + * Fires a property change of a boolean property with the given name. If the + * old value and the new value are not null and equal the event will not be + * fired. + * + * @param propertyName + * the property name + * @param index + * the index of the changed property + * @param oldValue + * the old value + * @param newValue + * the new value + */ + public void fireIndexedPropertyChange(String propertyName, int index, + boolean oldValue, boolean newValue) { + + if (oldValue != newValue) { + fireIndexedPropertyChange(propertyName, index, Boolean + .valueOf(oldValue), Boolean.valueOf(newValue)); + } + } + + /** + * Fires a property change of an integer property with the given name. If + * the old value and the new value are not null and equal the event will not + * be fired. + * + * @param propertyName + * the property name + * @param oldValue + * the old value + * @param newValue + * the new value + */ + public void firePropertyChange(String propertyName, int oldValue, + int newValue) { + PropertyChangeEvent event = createPropertyChangeEvent(propertyName, + oldValue, newValue); + doFirePropertyChange(event); + } + + /** + * Fires a property change of an integer property with the given name. If + * the old value and the new value are not null and equal the event will not + * be fired. + * + * @param propertyName + * the property name + * @param index + * the index of the changed property + * @param oldValue + * the old value + * @param newValue + * the new value + */ + public void fireIndexedPropertyChange(String propertyName, int index, + int oldValue, int newValue) { + + if (oldValue != newValue) { + fireIndexedPropertyChange(propertyName, index, + new Integer(oldValue), new Integer(newValue)); + } + } + + /** + * Returns true if there are listeners registered to the property with the + * given name. + * + * @param propertyName + * the name of the property + * @return true if there are listeners registered to that property, false + * otherwise. + */ + public synchronized boolean hasListeners(String propertyName) { + boolean result = allPropertiesChangeListeners.size() > 0; + if (!result && (propertyName != null)) { + List<PropertyChangeListener> listeners = + selectedPropertiesChangeListeners.get(propertyName); + if (listeners != null) { + result = listeners.size() > 0; + } + } + return result; + } + + /** + * removes a property change listener that was registered to all properties. + * + * @param listener + * the listener to remove + */ + public synchronized void removePropertyChangeListener( + PropertyChangeListener listener) { + if (listener != null) { + if (listener instanceof PropertyChangeListenerProxy) { + String name = ((PropertyChangeListenerProxy) listener) + .getPropertyName(); + PropertyChangeListener lst = (PropertyChangeListener) + ((PropertyChangeListenerProxy) listener).getListener(); + + removePropertyChangeListener(name, lst); + } else { + allPropertiesChangeListeners.remove(listener); + } + } + } + + /** + * Registers a listener with all properties. + * + * @param listener + * the listener to register + */ + public synchronized void addPropertyChangeListener( + PropertyChangeListener listener) { + if (listener != null) { + if (listener instanceof PropertyChangeListenerProxy) { + String name = ((PropertyChangeListenerProxy) listener) + .getPropertyName(); + PropertyChangeListener lst = (PropertyChangeListener) + ((PropertyChangeListenerProxy) listener).getListener(); + addPropertyChangeListener(name, lst); + } else { + allPropertiesChangeListeners.add(listener); + } + } + } + + /** + * Returns an array with the listeners that registered to all properties. + * + * @return the array of listeners + */ + public synchronized PropertyChangeListener[] getPropertyChangeListeners() { + ArrayList<PropertyChangeListener> result = + new ArrayList<PropertyChangeListener>( + allPropertiesChangeListeners); + + for (String propertyName : selectedPropertiesChangeListeners.keySet()) { + List<PropertyChangeListener> selectedListeners = + selectedPropertiesChangeListeners.get(propertyName); + + if (selectedListeners != null) { + + for (PropertyChangeListener listener : selectedListeners) { + result.add(new PropertyChangeListenerProxy(propertyName, + listener)); + } + } + } + + return result.toArray(new PropertyChangeListener[result.size()]); + } + + private void writeObject(ObjectOutputStream oos) throws IOException { + List<PropertyChangeListener> allSerializedPropertiesChangeListeners = + new ArrayList<PropertyChangeListener>(); + + for (PropertyChangeListener pcl : allPropertiesChangeListeners) { + if (pcl instanceof Serializable) { + allSerializedPropertiesChangeListeners.add(pcl); + } + } + + Map<String, List<PropertyChangeListener>> + selectedSerializedPropertiesChangeListeners = + new HashMap<String, List<PropertyChangeListener>>(); + + for (String propertyName : selectedPropertiesChangeListeners.keySet()) { + List<PropertyChangeListener> keyValues = + selectedPropertiesChangeListeners.get(propertyName); + + if (keyValues != null) { + List<PropertyChangeListener> serializedPropertiesChangeListeners + = new ArrayList<PropertyChangeListener>(); + + for (PropertyChangeListener pcl : keyValues) { + if (pcl instanceof Serializable) { + serializedPropertiesChangeListeners.add(pcl); + } + } + + if (!serializedPropertiesChangeListeners.isEmpty()) { + selectedSerializedPropertiesChangeListeners.put( + propertyName, serializedPropertiesChangeListeners); + } + } + } + + children = new Hashtable<String, List<PropertyChangeListener>>( + selectedSerializedPropertiesChangeListeners); + children.put("", allSerializedPropertiesChangeListeners); //$NON-NLS-1$ + oos.writeObject(children); + + Object source = null; + if (sourceBean instanceof Serializable) { + source = sourceBean; + } + oos.writeObject(source); + + oos.writeInt(propertyChangeSupportSerializedDataVersion); + } + + @SuppressWarnings("unchecked") + private void readObject(ObjectInputStream ois) throws IOException, + ClassNotFoundException { + children = (Hashtable<String, List<PropertyChangeListener>>) ois + .readObject(); + + selectedPropertiesChangeListeners = new HashMap<String, List<PropertyChangeListener>>( + children); + allPropertiesChangeListeners = selectedPropertiesChangeListeners + .remove(""); //$NON-NLS-1$ + if (allPropertiesChangeListeners == null) { + allPropertiesChangeListeners = new ArrayList<PropertyChangeListener>(); + } + + sourceBean = ois.readObject(); + propertyChangeSupportSerializedDataVersion = ois.readInt(); + } + + /** + * Fires a property change event to all listeners of that property. + * + * @param event + * the event to fire + */ + public void firePropertyChange(PropertyChangeEvent event) { + doFirePropertyChange(event); + } + + private PropertyChangeEvent createPropertyChangeEvent(String propertyName, + Object oldValue, Object newValue) { + return new PropertyChangeEvent(sourceBean, propertyName, oldValue, + newValue); + } + + private PropertyChangeEvent createPropertyChangeEvent(String propertyName, + boolean oldValue, boolean newValue) { + return new PropertyChangeEvent(sourceBean, propertyName, oldValue, + newValue); + } + + private PropertyChangeEvent createPropertyChangeEvent(String propertyName, + int oldValue, int newValue) { + return new PropertyChangeEvent(sourceBean, propertyName, oldValue, + newValue); + } + + private void doFirePropertyChange(PropertyChangeEvent event) { + String propertyName = event.getPropertyName(); + Object oldValue = event.getOldValue(); + Object newValue = event.getNewValue(); + + if ((newValue != null) && (oldValue != null) + && newValue.equals(oldValue)) { + return; + } + + /* + * Copy the listeners collections so they can be modified while we fire + * events. + */ + + // Listeners to all property change events + PropertyChangeListener[] listensToAll; + // Listens to a given property change + PropertyChangeListener[] listensToOne = null; + synchronized (this) { + listensToAll = allPropertiesChangeListeners + .toArray(new PropertyChangeListener[allPropertiesChangeListeners + .size()]); + + List<PropertyChangeListener> listeners = selectedPropertiesChangeListeners + .get(propertyName); + if (listeners != null) { + listensToOne = listeners + .toArray(new PropertyChangeListener[listeners.size()]); + } + } + + // Fire the listeners + for (PropertyChangeListener listener : listensToAll) { + listener.propertyChange(event); + } + if (listensToOne != null) { + for (PropertyChangeListener listener : listensToOne) { + listener.propertyChange(event); + } + } + } + +} |