I thought about that, and maybe we could.  It seemed kinda heavy for most
bean dictionary use cases though.  We'd also need to make BeanDictionary
have a source property and fire source changed events as well (since the
caller will leak memory without calling BeanMonitor.setSource(null).

I'm not  averse to integrating the two, but I feel like we might want to
keep BeanDictionary lighter than BeanMonitor.  Other than that, I'm very
happy with how BeanMonitor came out.

-T

On Mon, Oct 26, 2009 at 9:53 AM, Greg Brown <[email protected]> wrote:

> Could we not put this functionality in BeanDictionary itself?
>
>
> On Oct 26, 2009, at 9:48 AM, [email protected] wrote:
>
>  Author: tvolkert
>> Date: Mon Oct 26 13:48:09 2009
>> New Revision: 829797
>>
>> URL: http://svn.apache.org/viewvc?rev=829797&view=rev
>> Log:
>> Added BeanMonitor, changed EventLogger tool to use it, hooked up events to
>> component inspector tool
>>
>> Added:
>>   incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitor.java
>>
>> incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitorListener.java
>> Modified:
>>
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java
>>
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/EventLogger.java
>>
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/component_inspector_skin.wtkx
>>
>> Added:
>> incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitor.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitor.java?rev=829797&view=auto
>>
>> ==============================================================================
>> --- incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitor.java
>> (added)
>> +++ incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitor.java
>> Mon Oct 26 13:48:09 2009
>> @@ -0,0 +1,364 @@
>> +/*
>> + * 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 org.apache.pivot.beans;
>> +
>> +import java.lang.reflect.InvocationHandler;
>> +import java.lang.reflect.InvocationTargetException;
>> +import java.lang.reflect.Method;
>> +import java.lang.reflect.Modifier;
>> +import java.lang.reflect.ParameterizedType;
>> +import java.lang.reflect.Proxy;
>> +import java.lang.reflect.Type;
>> +import java.util.Comparator;
>> +
>> +import org.apache.pivot.collections.ArrayList;
>> +import org.apache.pivot.collections.HashMap;
>> +import org.apache.pivot.collections.Sequence;
>> +import org.apache.pivot.collections.immutable.ImmutableList;
>> +import org.apache.pivot.util.ListenerList;
>> +import org.apache.pivot.util.ThreadUtilities;
>> +import org.apache.pivot.util.Vote;
>> +
>> +/**
>> + * Notifies listeners of events fired from a source bean.
>> + */
>> +public class BeanMonitor {
>> +    private static class EventComparator implements Comparator<Method> {
>> +        @Override
>> +        public int compare(Method event1, Method event2) {
>> +            int result = 0;
>> +
>> +            Class<?> listenerInterface1 = event1.getDeclaringClass();
>> +            Class<?> listenerInterface2 = event2.getDeclaringClass();
>> +
>> +            if (listenerInterface1 != listenerInterface2) {
>> +                result =
>> listenerInterface1.getName().compareTo(listenerInterface2.getName());
>> +            }
>> +
>> +            if (result == 0) {
>> +                result = event1.getName().compareTo(event2.getName());
>> +            }
>> +
>> +            return result;
>> +        }
>> +    }
>> +
>> +    private static class PropertyNameComparator implements
>> Comparator<String> {
>> +        @Override
>> +        public int compare(String propertyName1, String propertyName2) {
>> +            return propertyName1.compareTo(propertyName2);
>> +        }
>> +    }
>> +
>> +    private class MonitorInvocationHandler implements InvocationHandler {
>> +        @Override
>> +        public Object invoke(Object proxy, Method event, Object[]
>> arguments) throws Throwable {
>> +            beanMonitorListeners.eventFired(BeanMonitor.this, event,
>> arguments);
>> +
>> +            String eventName = event.getName();
>> +            if (eventName.endsWith(PROPERTY_CHANGE_SUFFIX)) {
>> +                String propertyName = eventName.substring(0,
>> eventName.length()
>> +                    - PROPERTY_CHANGE_SUFFIX.length());
>> +
>> +                if (notifyingProperties.indexOf(propertyName) >= 0) {
>> +
>>  beanMonitorListeners.propertyChanged(BeanMonitor.this, propertyName);
>> +                }
>> +            }
>> +
>> +            Object result = null;
>> +            Class<?> returnType = event.getReturnType();
>> +            if (returnType == Vote.class) {
>> +                result = Vote.APPROVE;
>> +            } else if (returnType == Boolean.TYPE) {
>> +                result = false;
>> +            }
>> +
>> +            return result;
>> +        }
>> +    }
>> +
>> +    private static class BeanMonitorListenerList extends
>> ListenerList<BeanMonitorListener>
>> +        implements BeanMonitorListener {
>> +        @Override
>> +        public void sourceChanged(BeanMonitor beanMonitor, Object
>> previousSource) {
>> +            for (BeanMonitorListener listener : this) {
>> +                listener.sourceChanged(beanMonitor, previousSource);
>> +            }
>> +        }
>> +
>> +        @Override
>> +        public void eventFired(BeanMonitor beanMonitor, Method event,
>> Object[] arguments) {
>> +            for (BeanMonitorListener listener : this) {
>> +                listener.eventFired(beanMonitor, event, arguments);
>> +            }
>> +        }
>> +
>> +        @Override
>> +        public void propertyChanged(BeanMonitor beanMonitor, String
>> propertyName) {
>> +            for (BeanMonitorListener listener : this) {
>> +                listener.propertyChanged(beanMonitor, propertyName);
>> +            }
>> +        }
>> +    }
>> +
>> +    private Object source = null;
>> +
>> +    private HashMap<Class<?>, Object> eventListenerProxies = new
>> HashMap<Class<?>, Object>();
>> +    private MonitorInvocationHandler monitorInvocationHandler = new
>> MonitorInvocationHandler();
>> +
>> +    private ArrayList<Method> declaredEvents = new
>> ArrayList<Method>(eventComparator);
>> +    private ArrayList<String> notifyingProperties = new
>> ArrayList<String>(propertyNameComparator);
>> +
>> +    private BeanMonitorListenerList beanMonitorListeners = new
>> BeanMonitorListenerList();
>> +
>> +    private static EventComparator eventComparator = new
>> EventComparator();
>> +    private static PropertyNameComparator propertyNameComparator = new
>> PropertyNameComparator();
>> +
>> +    private static final String PROPERTY_CHANGE_SUFFIX = "Changed";
>> +
>> +    /**
>> +     * Creates a new bean monitor that is initially associated with no
>> source
>> +     * object.
>> +     */
>> +    public BeanMonitor() {
>> +        this(null);
>> +    }
>> +
>> +    /**
>> +     * Creates a new bean monitor that will monitor the specified source
>> +     * object.
>> +     * <p>
>> +     * <b>NOTE</b>: failing to clear the source of a bean monitor may
>> result in
>> +     * memory leaks, as the source object will maintain references to the
>> bean
>> +     * monitor as long as the source is set.
>> +     */
>> +    public BeanMonitor(Object source) {
>> +        setSource(source);
>> +    }
>> +
>> +    /**
>> +     * Gets the source of the bean monitor.
>> +     *
>> +     * @return
>> +     * The source object, or <tt>null</tt> if no source has been set.
>> +     */
>> +    public Object getSource() {
>> +        return source;
>> +    }
>> +
>> +    /**
>> +     * Sets the source of the bean monitor.
>> +     * <p>
>> +     * <b>NOTE</b>: failing to clear the source of a bean monitor may
>> result in
>> +     * memory leaks, as the source object will maintain references to the
>> bean
>> +     * monitor as long as the source is set.
>> +     *
>> +     * @param source
>> +     * The source object, or <tt>null</tt> to clear the source.
>> +     */
>> +    public void setSource(Object source) {
>> +        Object previousSource = this.source;
>> +
>> +        if (source != previousSource) {
>> +            this.source = source;
>> +
>> +            if (previousSource != null) {
>> +                unregisterEventListeners(previousSource);
>> +            }
>> +
>> +            declaredEvents.clear();
>> +            notifyingProperties.clear();
>> +
>> +            if (source != null) {
>> +                registerEventListeners(source);
>> +            }
>> +
>> +            beanMonitorListeners.sourceChanged(this, previousSource);
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Gets the list of events that the source bean may fire.
>> +     *
>> +     * @return
>> +     * The event listener methods that the source bean may invoke.
>> +     */
>> +    public Sequence<Method> getDeclaredEvents() {
>> +        return new ImmutableList<Method>(declaredEvents);
>> +    }
>> +
>> +    /**
>> +     * Gets the list of source bean property names for which property
>> change
>> +     * events will be fired.
>> +     *
>> +     * @return
>> +     * The property names that fire change events.
>> +     */
>> +    public Sequence<String> getNotifyingProperties() {
>> +        return new ImmutableList<String>(notifyingProperties);
>> +    }
>> +
>> +    /**
>> +     * Tells whether or not the specified property fires change events.
>> +     *
>> +     * @return
>> +     * <tt>true</tt> if the property fires change events; <tt>false</tt>
>> +     * otherwise.
>> +     */
>> +    public boolean isNotifyingProperty(String propertyName) {
>> +        return (notifyingProperties.indexOf(propertyName) >= 0);
>> +    }
>> +
>> +    /**
>> +     * Registers event listeners on a bean.
>> +     */
>> +    private void registerEventListeners(Object bean) {
>> +        BeanDictionary beanDictionary = new BeanDictionary(bean);
>> +        Method[] methods = bean.getClass().getMethods();
>> +
>> +        for (int i = 0; i < methods.length; i++) {
>> +            Method method = methods[i];
>> +
>> +            if
>> (ListenerList.class.isAssignableFrom(method.getReturnType())
>> +                && (method.getModifiers() & Modifier.STATIC) == 0) {
>> +                ParameterizedType genericType =
>> (ParameterizedType)method.getGenericReturnType();
>> +                Type[] typeArguments =
>> genericType.getActualTypeArguments();
>> +
>> +                if (typeArguments.length == 1) {
>> +                    Class<?> listenerInterface =
>> (Class<?>)typeArguments[0];
>> +
>> +                    if (!listenerInterface.isInterface()) {
>> +                        throw new
>> RuntimeException(listenerInterface.getName()
>> +                            + " is not an interface.");
>> +                    }
>> +
>> +                    Method[] interfaceMethods =
>> listenerInterface.getMethods();
>> +                    for (int j = 0; j < interfaceMethods.length; j++) {
>> +                        Method interfaceMethod = interfaceMethods[j];
>> +                        String interfaceMethodName =
>> interfaceMethod.getName();
>> +
>> +                        declaredEvents.add(interfaceMethod);
>> +
>> +                        if
>> (interfaceMethodName.endsWith(PROPERTY_CHANGE_SUFFIX)) {
>> +                            String propertyName =
>> interfaceMethodName.substring(0,
>> +                                interfaceMethodName.length() -
>> PROPERTY_CHANGE_SUFFIX.length());
>> +
>> +                            if (beanDictionary.containsKey(propertyName))
>> {
>> +                                notifyingProperties.add(propertyName);
>> +                            }
>> +                        }
>> +                    }
>> +
>> +                    // Get the listener list
>> +                    Object listenerList;
>> +                    try {
>> +                        listenerList = method.invoke(bean);
>> +                    } catch (InvocationTargetException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    } catch (IllegalAccessException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    }
>> +
>> +                    // Get the listener for this interface
>> +                    Object listener =
>> eventListenerProxies.get(listenerInterface);
>> +                    if (listener == null) {
>> +                        listener =
>> Proxy.newProxyInstance(ThreadUtilities.getClassLoader(),
>> +                            new Class[]{listenerInterface},
>> monitorInvocationHandler);
>> +                        eventListenerProxies.put(listenerInterface,
>> listener);
>> +                    }
>> +
>> +                    // Add the listener
>> +                    Class<?> listenerListClass = listenerList.getClass();
>> +                    Method addMethod;
>> +                    try {
>> +                        addMethod = listenerListClass.getMethod("add",
>> +                            new Class<?>[] {Object.class});
>> +                    } catch (NoSuchMethodException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    }
>> +
>> +                    try {
>> +                        addMethod.invoke(listenerList, new Object[]
>> {listener});
>> +                    } catch (IllegalAccessException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    } catch (InvocationTargetException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    }
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Un-registers event listeners on a bean.
>> +     */
>> +    private void unregisterEventListeners(Object bean) {
>> +        Method[] methods = bean.getClass().getMethods();
>> +
>> +        for (int i = 0; i < methods.length; i++) {
>> +            Method method = methods[i];
>> +
>> +            if
>> (ListenerList.class.isAssignableFrom(method.getReturnType())
>> +                && (method.getModifiers() & Modifier.STATIC) == 0) {
>> +                ParameterizedType genericType =
>> (ParameterizedType)method.getGenericReturnType();
>> +                Type[] typeArguments =
>> genericType.getActualTypeArguments();
>> +
>> +                if (typeArguments.length == 1) {
>> +                    Class<?> listenerInterface =
>> (Class<?>)typeArguments[0];
>> +
>> +                    // Get the listener list
>> +                    Object listenerList;
>> +                    try {
>> +                        listenerList = method.invoke(bean);
>> +                    } catch (InvocationTargetException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    } catch (IllegalAccessException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    }
>> +
>> +                    // Get the listener for this interface
>> +                    Object listener =
>> eventListenerProxies.get(listenerInterface);
>> +                    if (listener == null) {
>> +                        throw new IllegalStateException("Listener proxy
>> is null.");
>> +                    }
>> +
>> +                    // Remove the listener
>> +                    Class<?> listenerListClass = listenerList.getClass();
>> +                    Method removeMethod;
>> +                    try {
>> +                        removeMethod =
>> listenerListClass.getMethod("remove",
>> +                            new Class<?>[] {Object.class});
>> +                    } catch (NoSuchMethodException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    }
>> +
>> +                    try {
>> +                        removeMethod.invoke(listenerList, new Object[]
>> {listener});
>> +                    } catch (IllegalAccessException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    } catch (InvocationTargetException exception) {
>> +                        throw new RuntimeException(exception);
>> +                    }
>> +                }
>> +            }
>> +        }
>> +    }
>> +
>> +    public ListenerList<BeanMonitorListener> getBeanMonitorListeners() {
>> +        return beanMonitorListeners;
>> +    }
>> +}
>>
>> Added:
>> incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitorListener.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitorListener.java?rev=829797&view=auto
>>
>> ==============================================================================
>> ---
>> incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitorListener.java
>> (added)
>> +++
>> incubator/pivot/trunk/core/src/org/apache/pivot/beans/BeanMonitorListener.java
>> Mon Oct 26 13:48:09 2009
>> @@ -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 org.apache.pivot.beans;
>> +
>> +import java.lang.reflect.Method;
>> +
>> +/**
>> + * Bean monitor listener interface.
>> + */
>> +public interface BeanMonitorListener {
>> +    /**
>> +     * Bean monitor listener adapter.
>> +     */
>> +    public static class Adapter implements BeanMonitorListener {
>> +        @Override
>> +        public void sourceChanged(BeanMonitor beanMonitor, Object
>> previousSource) {
>> +        }
>> +
>> +        @Override
>> +        public void eventFired(BeanMonitor beanMonitor, Method event,
>> Object[] arguments) {
>> +        }
>> +
>> +        @Override
>> +        public void propertyChanged(BeanMonitor beanMonitor, String
>> propertyName) {
>> +        }
>> +    }
>> +
>> +    /**
>> +     * Called when a bean monitor's source has changed.
>> +     *
>> +     * @param beanMonitor
>> +     * @param previousSource
>> +     */
>> +    public void sourceChanged(BeanMonitor beanMonitor, Object
>> previousSource);
>> +
>> +    /**
>> +     * Called when an event has been fired by the bean monitor's source.
>> +     *
>> +     * @param beanMonitor
>> +     * @param event
>> +     * @param arguments
>> +     */
>> +    public void eventFired(BeanMonitor beanMonitor, Method event,
>> Object[] arguments);
>> +
>> +    /**
>> +     * Called when a property of the bean monitor's source has changed.
>> +     *
>> +     * @param beanMonitor
>> +     * @param propertyName
>> +     */
>> +    public void propertyChanged(BeanMonitor beanMonitor, String
>> propertyName);
>> +}
>>
>> Modified:
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java?rev=829797&r1=829796&r2=829797&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java
>> (original)
>> +++
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/ComponentInspectorSkin.java
>> Mon Oct 26 13:48:09 2009
>> @@ -21,11 +21,12 @@
>> import java.util.Comparator;
>>
>> import org.apache.pivot.beans.BeanDictionary;
>> +import org.apache.pivot.beans.BeanMonitor;
>> +import org.apache.pivot.beans.BeanMonitorListener;
>> import org.apache.pivot.collections.ArrayList;
>> import org.apache.pivot.collections.EnumList;
>> import org.apache.pivot.collections.HashMap;
>> import org.apache.pivot.collections.List;
>> -import org.apache.pivot.collections.Map;
>> import org.apache.pivot.serialization.SerializationException;
>> import org.apache.pivot.util.Resources;
>> import org.apache.pivot.wtk.BoxPane;
>> @@ -33,6 +34,7 @@
>> import org.apache.pivot.wtk.ButtonStateListener;
>> import org.apache.pivot.wtk.Checkbox;
>> import org.apache.pivot.wtk.Component;
>> +import org.apache.pivot.wtk.ComponentStateListener;
>> import org.apache.pivot.wtk.Dimensions;
>> import org.apache.pivot.wtk.FlowPane;
>> import org.apache.pivot.wtk.Form;
>> @@ -42,7 +44,6 @@
>> import org.apache.pivot.wtk.ListButtonSelectionListener;
>> import org.apache.pivot.wtk.Orientation;
>> import org.apache.pivot.wtk.Point;
>> -import org.apache.pivot.wtk.Rollup;
>> import org.apache.pivot.wtk.TextInput;
>> import org.apache.pivot.wtk.skin.ContainerSkin;
>> import org.apache.pivot.wtk.text.validation.IntValidator;
>> @@ -76,13 +77,41 @@
>>
>>    private Component content = null;
>>
>> -    @WTKX private BoxPane propertiesPane = null;
>> +    @WTKX private Form propertiesForm = null;
>>    @WTKX private BoxPane stylesPane = null;
>>
>> +    private BeanDictionary beanDictionary = null;
>> +    private BeanMonitor beanMonitor = new BeanMonitor();
>> +
>> +    private HashMap<String, Component> inspectorComponents = new
>> HashMap<String, Component>();
>> +
>>    private static PropertyNameComparator propertyNameComparator = new
>> PropertyNameComparator();
>>    private static PropertySourceTypeComparator
>> propertySourceTypeComparator =
>>        new PropertySourceTypeComparator();
>>
>> +    public ComponentInspectorSkin() {
>> +        beanMonitor.getBeanMonitorListeners().add(new
>> BeanMonitorListener.Adapter() {
>> +            @Override
>> +            public void propertyChanged(BeanMonitor beanMonitor, String
>> propertyName) {
>> +                Class<?> propertyType =
>> beanDictionary.getType(propertyName);
>> +
>> +                if (propertyType == Boolean.TYPE) {
>> +                    updateBooleanControl(propertyName);
>> +                } else if (propertyType == Integer.TYPE) {
>> +                    updateIntControl(propertyName);
>> +                } else if (propertyType.isEnum()) {
>> +                    updateEnumControl(propertyName);
>> +                } else if (propertyType == Point.class) {
>> +                    updatePointControl(propertyName);
>> +                } else if (propertyType == Dimensions.class) {
>> +                    updateDimensionsControl(propertyName);
>> +                } else if (propertyType == Limits.class) {
>> +                    updateLimitsControl(propertyName);
>> +                }
>> +            }
>> +        });
>> +    }
>> +
>>    @Override
>>    public void install(Component component) {
>>        super.install(component);
>> @@ -139,25 +168,26 @@
>>
>>    @Override
>>    public void sourceChanged(ComponentInspector componentInspector,
>> Component previousSource) {
>> -        propertiesPane.remove(0, propertiesPane.getLength());
>> +        Form.SectionSequence propertiesSections =
>> propertiesForm.getSections();
>> +        propertiesSections.remove(0, propertiesSections.getLength());
>> +
>>        stylesPane.remove(0, stylesPane.getLength());
>>
>>        Component source = componentInspector.getSource();
>>
>> +        beanDictionary = null;
>> +        beanMonitor.setSource(source);
>> +
>>        if (source != null) {
>> -            Class<?> sourceType = source.getClass();
>> -            BeanDictionary beanDictionary = new BeanDictionary(source);
>> +            beanDictionary = new BeanDictionary(source);
>>
>> -            Map<Class<?>, List<String>> propertyBuckets =
>> +            Class<?> sourceType = source.getClass();
>> +            HashMap<Class<?>, List<String>> propertyBuckets =
>>                new HashMap<Class<?>,
>> List<String>>(propertySourceTypeComparator);
>>
>>            for (String propertyName : beanDictionary) {
>> -                boolean readOnly =
>> beanDictionary.isReadOnly(propertyName);
>> -
>> -                if (!readOnly) {
>> -                    // TODO?
>> -                    // Class<?> propertyType =
>> beanDictionary.getType(propertyName);
>> -
>> +                if (beanMonitor.isNotifyingProperty(propertyName)
>> +                    && !beanDictionary.isReadOnly(propertyName)) {
>>                    Method method =
>> BeanDictionary.getGetterMethod(sourceType, propertyName);
>>                    Class<?> declaringClass = method.getDeclaringClass();
>>
>> @@ -172,47 +202,42 @@
>>            }
>>
>>            for (Class<?> declaringClass : propertyBuckets) {
>> -                Rollup rollup = new Rollup();
>> -                propertiesPane.add(rollup);
>> -                Label label = new Label(declaringClass.getSimpleName());
>> -                label.getStyles().put("color", 16);
>> -                label.getStyles().put("font", "{bold:true}");
>> -                rollup.setHeading(label);
>> -
>> -                Form form = new Form();
>> -                form.getStyles().put("rightAlignLabels", true);
>>                Form.Section section = new Form.Section();
>> -                form.getSections().add(section);
>> -                rollup.setContent(form);
>> +                section.setHeading(declaringClass.getSimpleName());
>> +                propertiesSections.add(section);
>>
>>                for (String propertyName :
>> propertyBuckets.get(declaringClass)) {
>> -                    addPropertyControl(propertyName, section,
>> beanDictionary);
>> +                    addPropertyControl(propertyName, section);
>>                }
>>            }
>>        }
>>    }
>>
>> -    private void addPropertyControl(String propertyName, Form.Section
>> section,
>> -        BeanDictionary beanDictionary) {
>> +    private void addPropertyControl(String propertyName, Form.Section
>> section) {
>>        Class<?> propertyType = beanDictionary.getType(propertyName);
>>
>> +        Component inspectorComponent = null;
>> +
>>        if (propertyType == Boolean.TYPE) {
>> -            addBooleanControl(propertyName, section, beanDictionary);
>> +            inspectorComponent = addBooleanControl(propertyName,
>> section);
>>        } else if (propertyType == Integer.TYPE) {
>> -            addIntControl(propertyName, section, beanDictionary);
>> +            inspectorComponent = addIntControl(propertyName, section);
>>        } else if (propertyType.isEnum()) {
>> -            addEnumControl(propertyName, section, beanDictionary);
>> +            inspectorComponent = addEnumControl(propertyName, section);
>>        } else if (propertyType == Point.class) {
>> -            addPointControl(propertyName, section, beanDictionary);
>> +            inspectorComponent = addPointControl(propertyName, section);
>>        } else if (propertyType == Dimensions.class) {
>> -            addDimensionsControl(propertyName, section, beanDictionary);
>> +            inspectorComponent = addDimensionsControl(propertyName,
>> section);
>>        } else if (propertyType == Limits.class) {
>> -            addLimitsControl(propertyName, section, beanDictionary);
>> +            inspectorComponent = addLimitsControl(propertyName, section);
>> +        }
>> +
>> +        if (inspectorComponent != null) {
>> +            inspectorComponents.put(propertyName, inspectorComponent);
>>        }
>>    }
>>
>> -    private void addBooleanControl(final String propertyName,
>> Form.Section section,
>> -        final BeanDictionary beanDictionary) {
>> +    private Component addBooleanControl(final String propertyName,
>> Form.Section section) {
>>        boolean propertyValue = (Boolean)beanDictionary.get(propertyName);
>>
>>        Checkbox checkbox = new Checkbox();
>> @@ -226,11 +251,20 @@
>>                beanDictionary.put(propertyName, button.isSelected());
>>            }
>>        });
>> +
>> +        return checkbox;
>>    }
>>
>> -    private void addIntControl(final String propertyName, Form.Section
>> section,
>> -        final BeanDictionary beanDictionary) {
>> -        /*
>> +    private void updateBooleanControl(String propertyName) {
>> +        Checkbox checkbox =
>> (Checkbox)inspectorComponents.get(propertyName);
>> +
>> +        if (checkbox != null) {
>> +            boolean propertyValue =
>> (Boolean)beanDictionary.get(propertyName);
>> +            checkbox.setSelected(propertyValue);
>> +        }
>> +    }
>> +
>> +    private Component addIntControl(final String propertyName,
>> Form.Section section) {
>>        int propertyValue = (Integer)beanDictionary.get(propertyName);
>>
>>        TextInput textInput = new TextInput();
>> @@ -244,21 +278,33 @@
>>        textInput.getComponentStateListeners().add(new
>> ComponentStateListener.Adapter() {
>>            @Override
>>            public void focusedChanged(Component component, Component
>> obverseComponent) {
>> -                TextInput textInput = (TextInput)component;
>> -                try {
>> -                    beanDictionary.put(propertyName,
>> Integer.parseInt(textInput.getText()));
>> -                } catch (Exception exception) {
>> -                    Object propertyValue =
>> beanDictionary.get(propertyName);
>> -                    textInput.setText(String.valueOf(propertyValue));
>> +                if (!component.isFocused()) {
>> +                    TextInput textInput = (TextInput)component;
>> +
>> +                    try {
>> +                        beanDictionary.put(propertyName,
>> Integer.parseInt(textInput.getText()));
>> +                    } catch (Exception exception) {
>> +                        Object propertyValue =
>> beanDictionary.get(propertyName);
>> +                        textInput.setText(String.valueOf(propertyValue));
>> +                    }
>>                }
>>            }
>>        });
>> -        */
>> +
>> +        return textInput;
>> +    }
>> +
>> +    private void updateIntControl(String propertyName) {
>> +        TextInput textInput =
>> (TextInput)inspectorComponents.get(propertyName);
>> +
>> +        if (textInput != null) {
>> +            int propertyValue =
>> (Integer)beanDictionary.get(propertyName);
>> +            textInput.setText(String.valueOf(propertyValue));
>> +        }
>>    }
>>
>>    @SuppressWarnings("unchecked")
>> -    private void addEnumControl(final String propertyName, Form.Section
>> section,
>> -        final BeanDictionary beanDictionary) {
>> +    private Component addEnumControl(final String propertyName,
>> Form.Section section) {
>>        Class<?> propertyType = beanDictionary.getType(propertyName);
>>        Enum<?> propertyValue = (Enum<?>)beanDictionary.get(propertyName);
>>
>> @@ -274,10 +320,20 @@
>>                beanDictionary.put(propertyName,
>> listButton.getSelectedItem());
>>            }
>>        });
>> +
>> +        return listButton;
>>    }
>>
>> -    private void addPointControl(final String propertyName, Form.Section
>> section,
>> -        final BeanDictionary beanDictionary) {
>> +    private void updateEnumControl(String propertyName) {
>> +        ListButton listButton =
>> (ListButton)inspectorComponents.get(propertyName);
>> +
>> +        if (listButton != null) {
>> +            Enum<?> propertyValue =
>> (Enum<?>)beanDictionary.get(propertyName);
>> +            listButton.setSelectedItem(propertyValue);
>> +        }
>> +    }
>> +
>> +    private Component addPointControl(final String propertyName,
>> Form.Section section) {
>>        Point point = (Point)beanDictionary.get(propertyName);
>>
>>        BoxPane boxPane = new BoxPane(Orientation.VERTICAL);
>> @@ -296,6 +352,23 @@
>>        textInput.setText(String.valueOf(point.x));
>>        flowPane.add(textInput);
>>
>> +        textInput.getComponentStateListeners().add(new
>> ComponentStateListener.Adapter() {
>> +            @Override
>> +            public void focusedChanged(Component component, Component
>> obverseComponent) {
>> +                if (!component.isFocused()) {
>> +                    TextInput textInput = (TextInput)component;
>> +                    Point point =
>> (Point)beanDictionary.get(propertyName);
>> +
>> +                    try {
>> +                        int x = Integer.parseInt(textInput.getText());
>> +                        beanDictionary.put(propertyName, new Point(x,
>> point.y));
>> +                    } catch (Exception exception) {
>> +                        textInput.setText(String.valueOf(point.x));
>> +                    }
>> +                }
>> +            }
>> +        });
>> +
>>        Label label = new Label("x");
>>        label.getStyles().put("font", "{italic:true}");
>>        flowPane.add(label);
>> @@ -312,13 +385,45 @@
>>        textInput.setText(String.valueOf(point.y));
>>        flowPane.add(textInput);
>>
>> +        textInput.getComponentStateListeners().add(new
>> ComponentStateListener.Adapter() {
>> +            @Override
>> +            public void focusedChanged(Component component, Component
>> obverseComponent) {
>> +                if (!component.isFocused()) {
>> +                    TextInput textInput = (TextInput)component;
>> +                    Point point =
>> (Point)beanDictionary.get(propertyName);
>> +
>> +                    try {
>> +                        int y = Integer.parseInt(textInput.getText());
>> +                        beanDictionary.put(propertyName, new
>> Point(point.x, y));
>> +                    } catch (Exception exception) {
>> +                        textInput.setText(String.valueOf(point.y));
>> +                    }
>> +                }
>> +            }
>> +        });
>> +
>>        label = new Label("y");
>>        label.getStyles().put("font", "{italic:true}");
>>        flowPane.add(label);
>> +
>> +        return boxPane;
>>    }
>>
>> -    private void addDimensionsControl(final String propertyName,
>> Form.Section section,
>> -        final BeanDictionary beanDictionary) {
>> +    private void updatePointControl(String propertyName) {
>> +        BoxPane boxPane = (BoxPane)inspectorComponents.get(propertyName);
>> +
>> +        if (boxPane != null) {
>> +            Point point = (Point)beanDictionary.get(propertyName);
>> +
>> +            TextInput xTextInput =
>> (TextInput)((FlowPane)boxPane.get(0)).get(0);
>> +            TextInput yTextInput =
>> (TextInput)((FlowPane)boxPane.get(1)).get(0);
>> +
>> +            xTextInput.setText(String.valueOf(point.x));
>> +            yTextInput.setText(String.valueOf(point.y));
>> +        }
>> +    }
>> +
>> +    private Component addDimensionsControl(final String propertyName,
>> Form.Section section) {
>>        Dimensions dimensions =
>> (Dimensions)beanDictionary.get(propertyName);
>>
>>        BoxPane boxPane = new BoxPane(Orientation.VERTICAL);
>> @@ -337,6 +442,23 @@
>>        textInput.setText(String.valueOf(dimensions.width));
>>        flowPane.add(textInput);
>>
>> +        textInput.getComponentStateListeners().add(new
>> ComponentStateListener.Adapter() {
>> +            @Override
>> +            public void focusedChanged(Component component, Component
>> obverseComponent) {
>> +                if (!component.isFocused()) {
>> +                    TextInput textInput = (TextInput)component;
>> +                    Dimensions dimensions =
>> (Dimensions)beanDictionary.get(propertyName);
>> +
>> +                    try {
>> +                        int width =
>> Integer.parseInt(textInput.getText());
>> +                        beanDictionary.put(propertyName, new
>> Dimensions(width, dimensions.height));
>> +                    } catch (Exception exception) {
>> +
>>  textInput.setText(String.valueOf(dimensions.width));
>> +                    }
>> +                }
>> +            }
>> +        });
>> +
>>        Label label = new Label("width");
>>        label.getStyles().put("font", "{italic:true}");
>>        flowPane.add(label);
>> @@ -353,13 +475,45 @@
>>        textInput.setText(String.valueOf(dimensions.height));
>>        flowPane.add(textInput);
>>
>> +        textInput.getComponentStateListeners().add(new
>> ComponentStateListener.Adapter() {
>> +            @Override
>> +            public void focusedChanged(Component component, Component
>> obverseComponent) {
>> +                if (!component.isFocused()) {
>> +                    TextInput textInput = (TextInput)component;
>> +                    Dimensions dimensions =
>> (Dimensions)beanDictionary.get(propertyName);
>> +
>> +                    try {
>> +                        int height =
>> Integer.parseInt(textInput.getText());
>> +                        beanDictionary.put(propertyName, new
>> Dimensions(dimensions.width, height));
>> +                    } catch (Exception exception) {
>> +
>>  textInput.setText(String.valueOf(dimensions.height));
>> +                    }
>> +                }
>> +            }
>> +        });
>> +
>>        label = new Label("height");
>>        label.getStyles().put("font", "{italic:true}");
>>        flowPane.add(label);
>> +
>> +        return boxPane;
>> +    }
>> +
>> +    private void updateDimensionsControl(String propertyName) {
>> +        BoxPane boxPane = (BoxPane)inspectorComponents.get(propertyName);
>> +
>> +        if (boxPane != null) {
>> +            Dimensions dimensions =
>> (Dimensions)beanDictionary.get(propertyName);
>> +
>> +            TextInput widthTextInput =
>> (TextInput)((FlowPane)boxPane.get(0)).get(0);
>> +            TextInput heightTextInput =
>> (TextInput)((FlowPane)boxPane.get(1)).get(0);
>> +
>> +            widthTextInput.setText(String.valueOf(dimensions.width));
>> +            heightTextInput.setText(String.valueOf(dimensions.height));
>> +        }
>>    }
>>
>> -    private void addLimitsControl(final String propertyName, Form.Section
>> section,
>> -        final BeanDictionary beanDictionary) {
>> +    private Component addLimitsControl(final String propertyName,
>> Form.Section section) {
>>        Limits limits = (Limits)beanDictionary.get(propertyName);
>>
>>        BoxPane boxPane = new BoxPane(Orientation.VERTICAL);
>> @@ -378,6 +532,23 @@
>>        textInput.setText(String.valueOf(limits.min));
>>        flowPane.add(textInput);
>>
>> +        textInput.getComponentStateListeners().add(new
>> ComponentStateListener.Adapter() {
>> +            @Override
>> +            public void focusedChanged(Component component, Component
>> obverseComponent) {
>> +                if (!component.isFocused()) {
>> +                    TextInput textInput = (TextInput)component;
>> +                    Limits limits =
>> (Limits)beanDictionary.get(propertyName);
>> +
>> +                    try {
>> +                        int min = Integer.parseInt(textInput.getText());
>> +                        beanDictionary.put(propertyName, new Limits(min,
>> limits.max));
>> +                    } catch (Exception exception) {
>> +                        textInput.setText(String.valueOf(limits.min));
>> +                    }
>> +                }
>> +            }
>> +        });
>> +
>>        Label label = new Label("min");
>>        label.getStyles().put("font", "{italic:true}");
>>        flowPane.add(label);
>> @@ -394,8 +565,41 @@
>>        textInput.setText(String.valueOf(limits.max));
>>        flowPane.add(textInput);
>>
>> +        textInput.getComponentStateListeners().add(new
>> ComponentStateListener.Adapter() {
>> +            @Override
>> +            public void focusedChanged(Component component, Component
>> obverseComponent) {
>> +                if (!component.isFocused()) {
>> +                    TextInput textInput = (TextInput)component;
>> +                    Limits limits =
>> (Limits)beanDictionary.get(propertyName);
>> +
>> +                    try {
>> +                        int max = Integer.parseInt(textInput.getText());
>> +                        beanDictionary.put(propertyName, new
>> Limits(limits.min, max));
>> +                    } catch (Exception exception) {
>> +                        textInput.setText(String.valueOf(limits.max));
>> +                    }
>> +                }
>> +            }
>> +        });
>> +
>>        label = new Label("max");
>>        label.getStyles().put("font", "{italic:true}");
>>        flowPane.add(label);
>> +
>> +        return boxPane;
>> +    }
>> +
>> +    private void updateLimitsControl(String propertyName) {
>> +        BoxPane boxPane = (BoxPane)inspectorComponents.get(propertyName);
>> +
>> +        if (boxPane != null) {
>> +            Limits limits = (Limits)beanDictionary.get(propertyName);
>> +
>> +            TextInput minTextInput =
>> (TextInput)((FlowPane)boxPane.get(0)).get(0);
>> +            TextInput maxTextInput =
>> (TextInput)((FlowPane)boxPane.get(1)).get(0);
>> +
>> +            minTextInput.setText(String.valueOf(limits.min));
>> +            maxTextInput.setText(String.valueOf(limits.max));
>> +        }
>>    }
>> }
>>
>> Modified:
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/EventLogger.java
>> URL:
>> http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/EventLogger.java?rev=829797&r1=829796&r2=829797&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/EventLogger.java
>> (original)
>> +++
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/EventLogger.java
>> Mon Oct 26 13:48:09 2009
>> @@ -16,68 +16,19 @@
>>  */
>> package org.apache.pivot.tools.wtk;
>>
>> -import java.lang.reflect.InvocationHandler;
>> -import java.lang.reflect.InvocationTargetException;
>> import java.lang.reflect.Method;
>> -import java.lang.reflect.Modifier;
>> -import java.lang.reflect.ParameterizedType;
>> -import java.lang.reflect.Proxy;
>> -import java.lang.reflect.Type;
>> -import java.util.Comparator;
>>
>> -import org.apache.pivot.collections.ArrayList;
>> +import org.apache.pivot.beans.BeanMonitor;
>> +import org.apache.pivot.beans.BeanMonitorListener;
>> import org.apache.pivot.collections.Group;
>> -import org.apache.pivot.collections.HashMap;
>> import org.apache.pivot.collections.HashSet;
>> import org.apache.pivot.collections.Sequence;
>> -import org.apache.pivot.collections.immutable.ImmutableList;
>> import org.apache.pivot.collections.immutable.ImmutableSet;
>> import org.apache.pivot.util.ListenerList;
>> -import org.apache.pivot.util.ThreadUtilities;
>> -import org.apache.pivot.util.Vote;
>> import org.apache.pivot.wtk.Component;
>> import org.apache.pivot.wtk.Container;
>>
>> public class EventLogger extends Container {
>> -    private static class EventComparator implements Comparator<Method> {
>> -        @Override
>> -        public int compare(Method event1, Method event2) {
>> -            int result = 0;
>> -
>> -            Class<?> listenerInterface1 = event1.getDeclaringClass();
>> -            Class<?> listenerInterface2 = event2.getDeclaringClass();
>> -
>> -            if (listenerInterface1 != listenerInterface2) {
>> -                result =
>> listenerInterface1.getName().compareTo(listenerInterface2.getName());
>> -            }
>> -
>> -            if (result == 0) {
>> -                result = event1.getName().compareTo(event2.getName());
>> -            }
>> -
>> -            return result;
>> -        }
>> -    }
>> -
>> -    private class LoggerInvocationHandler implements InvocationHandler {
>> -        @Override
>> -        public Object invoke(Object proxy, Method event, Object[]
>> arguments) throws Throwable {
>> -            if (includeEvents.contains(event)) {
>> -                eventLoggerListeners.eventFired(EventLogger.this, event,
>> arguments);
>> -            }
>> -
>> -            Object result = null;
>> -            Class<?> returnType = event.getReturnType();
>> -            if (returnType == Vote.class) {
>> -                result = Vote.APPROVE;
>> -            } else if (returnType == Boolean.TYPE) {
>> -                result = false;
>> -            }
>> -
>> -            return result;
>> -        }
>> -    }
>> -
>>    private static class EventLoggerListenerList extends
>> ListenerList<EventLoggerListener>
>>        implements EventLoggerListener {
>>        @Override
>> @@ -109,12 +60,21 @@
>>        }
>>    }
>>
>> -    private Component source = null;
>> +    private BeanMonitorListener beanMonitorHandler = new
>> BeanMonitorListener.Adapter() {
>> +        @Override
>> +        public void sourceChanged(BeanMonitor meanMonitor, Object
>> previousSource) {
>> +            eventLoggerListeners.sourceChanged(EventLogger.this,
>> (Component)previousSource);
>> +        }
>>
>> -    private HashMap<Class<?>, Object> eventListenerProxies = new
>> HashMap<Class<?>, Object>();
>> -    private LoggerInvocationHandler loggerInvocationHandler = new
>> LoggerInvocationHandler();
>> +        @Override
>> +        public void eventFired(BeanMonitor meanMonitor, Method event,
>> Object[] arguments) {
>> +            if (includeEvents.contains(event)) {
>> +                eventLoggerListeners.eventFired(EventLogger.this, event,
>> arguments);
>> +            }
>> +        }
>> +    };
>>
>> -    private ArrayList<Method> declaredEvents = new ArrayList<Method>(new
>> EventComparator());
>> +    private BeanMonitor beanMonitor = new BeanMonitor();
>>
>>    private HashSet<Method> includeEvents = new HashSet<Method>();
>>
>> @@ -125,34 +85,21 @@
>>    }
>>
>>    public EventLogger(Component source) {
>> +        beanMonitor.getBeanMonitorListeners().add(beanMonitorHandler);
>>        setSource(source);
>>        setSkin(new EventLoggerSkin());
>>    }
>>
>>    public Component getSource() {
>> -        return source;
>> +        return (Component)beanMonitor.getSource();
>>    }
>>
>>    public void setSource(Component source) {
>> -        Component previousSource = this.source;
>> -
>> -        if (source != previousSource) {
>> -            this.source = source;
>> -
>> -            if (previousSource != null) {
>> -                unregisterEventListeners(previousSource);
>> -            }
>> -
>> -            if (source != null) {
>> -                registerEventListeners(source);
>> -            }
>> -
>> -            eventLoggerListeners.sourceChanged(this, previousSource);
>> -        }
>> +        beanMonitor.setSource(source);
>>    }
>>
>>    public Sequence<Method> getDeclaredEvents() {
>> -        return new ImmutableList<Method>(declaredEvents);
>> +        return beanMonitor.getDeclaredEvents();
>>    }
>>
>>    public Group<Method> getIncludeEvents() {
>> @@ -177,79 +124,6 @@
>>        return includeEvents.contains(event);
>>    }
>>
>> -    private void registerEventListeners(Component source) {
>> -        declaredEvents.clear();
>> -
>> -        Method[] methods = source.getClass().getMethods();
>> -
>> -        for (int i = 0; i < methods.length; i++) {
>> -            Method method = methods[i];
>> -
>> -            if
>> (ListenerList.class.isAssignableFrom(method.getReturnType())
>> -                && (method.getModifiers() & Modifier.STATIC) == 0) {
>> -                ParameterizedType genericType =
>> (ParameterizedType)method.getGenericReturnType();
>> -                Type[] typeArguments =
>> genericType.getActualTypeArguments();
>> -
>> -                if (typeArguments.length == 1) {
>> -                    Class<?> listenerInterface =
>> (Class<?>)typeArguments[0];
>> -
>> -                    if (!listenerInterface.isInterface()) {
>> -                        throw new
>> RuntimeException(listenerInterface.getName()
>> -                            + " is not an interface.");
>> -                    }
>> -
>> -                    Method[] interfaceMethods =
>> listenerInterface.getMethods();
>> -                    for (int j = 0; j < interfaceMethods.length; j++) {
>> -                        Method interfaceMethod = interfaceMethods[j];
>> -                        declaredEvents.add(interfaceMethod);
>> -                    }
>> -
>> -                    // Get the listener list
>> -                    Object listenerList;
>> -                    try {
>> -                        listenerList = method.invoke(source);
>> -                    } catch (InvocationTargetException exception) {
>> -                        throw new RuntimeException(exception);
>> -                    } catch (IllegalAccessException exception) {
>> -                        throw new RuntimeException(exception);
>> -                    }
>> -
>> -                    // Get the listener for this interface
>> -                    Object listener =
>> eventListenerProxies.get(listenerInterface);
>> -                    if (listener == null) {
>> -                        listener =
>> Proxy.newProxyInstance(ThreadUtilities.getClassLoader(),
>> -                            new Class[]{listenerInterface},
>> loggerInvocationHandler);
>> -                        eventListenerProxies.put(listenerInterface,
>> listener);
>> -                    }
>> -
>> -                    // Add the listener
>> -                    Class<?> listenerListClass = listenerList.getClass();
>> -                    Method addMethod;
>> -                    try {
>> -                        addMethod = listenerListClass.getMethod("add",
>> -                            new Class<?>[] {Object.class});
>> -                    } catch (NoSuchMethodException exception) {
>> -                        throw new RuntimeException(exception);
>> -                    }
>> -
>> -                    try {
>> -                        addMethod.invoke(listenerList, new Object[]
>> {listener});
>> -                    } catch (IllegalAccessException exception) {
>> -                        throw new RuntimeException(exception);
>> -                    } catch (InvocationTargetException exception) {
>> -                        throw new RuntimeException(exception);
>> -                    }
>> -                }
>> -            }
>> -        }
>> -    }
>> -
>> -    private void unregisterEventListeners(Component source) {
>> -        declaredEvents.clear();
>> -
>> -        // TODO
>> -    }
>> -
>>    public ListenerList<EventLoggerListener> getEventLoggerListeners() {
>>        return eventLoggerListeners;
>>    }
>>
>> Modified:
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/component_inspector_skin.wtkx
>> URL:
>> http://svn.apache.org/viewvc/incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/component_inspector_skin.wtkx?rev=829797&r1=829796&r2=829797&view=diff
>>
>> ==============================================================================
>> ---
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/component_inspector_skin.wtkx
>> (original)
>> +++
>> incubator/pivot/trunk/tools/src/org/apache/pivot/tools/wtk/component_inspector_skin.wtkx
>> Mon Oct 26 13:48:09 2009
>> @@ -22,7 +22,10 @@
>>    <view>
>>        <BoxPane orientation="vertical" styles="{fill:true,
>> horizontalAlignment:'right'}">
>>            <Label text="%properties" styles="{padding:{left:10, top:5},
>> font:{bold:true}}"/>
>> -            <BoxPane wtkx:id="propertiesPane" orientation="vertical"
>> styles="{padding:{left:10}}"/>
>> +            <BoxPane orientation="vertical" styles="{padding:{left:10}}">
>> +                <Form wtkx:id="propertiesForm"
>> +                    styles="{rightAlignLabels:true,
>> showFirstSectionHeading:true}"/>
>> +            </BoxPane>
>>            <Separator/>
>>            <Label text="%styles" styles="{padding:{left:10},
>> font:{bold:true}}"/>
>>            <BoxPane wtkx:id="stylesPane" orientation="vertical"
>> styles="{padding:{left:10}}"/>
>>
>>
>>
>

Reply via email to