Moving over to pivot-dev, as this is becoming more of a dev thread.

So I wanted to test your suggestion to see how the code would look - sort of
as a proof of concept.  See attached file for the source code and the
output.  It produces the following output.

The bottom line is: you're right - it's not too tough to do, and the code
isn't that messy :).  There's a different issue here though that would then
need to be discussed: is it ok to change WTKXSerializer to have a policy
that any attribute beginning with /on[A-Z]/ is to be taken as an event
listener?  It's not so much a parsing problem as a design one -- right now,
WTKXSerializer doesn't contain any such "if the attribute name is X, then
special case it" logic.  One could argue that adding such a special case
will encourage other special cases, and before you know it, the simplicity
of the design is gone, and it'll be hard to digest exactly how to use WTKX.

Now, on the other hand, we could say that the policy is to look for a setter
("setOnMouseClick", for instance), and only if one is not found (and the
attribute matches /on[A-Z]/) do we look for event handler methods.

Given how simple my test case was to write, I'm actually not that against
this (at least not as against it as I thought I'd be) :).  What do others
think?

-T

On Wed, Sep 2, 2009 at 4:38 PM, Noel Grandin <[email protected]> wrote:

> >
> > But how would it know where to look, and which interfaces constituted
> "listener" interfaces? I think Todd's >
> >
>
> In Pivot, anything method that returns a subtype of ListenerList is,
> by definition, a listener API.
> It's not hard to use reflection to scan for methods that match that
> pattern, and then scan the appropriate interface class to find the
> right method.
>
> IMNSHO, Todd's syntax looks pretty long-winded and awkward to use,
> especially if you're done some HTML programming.
>
> -- Noel.
>
onOwnerChanged (WindowListener)
onTitleChanged (WindowListener)
onIconChanged (WindowListener)
onContentChanged (WindowListener)
onActiveChanged (WindowListener)
onWindowMoved (WindowListener)
onMaximizedChanged (WindowListener)
onPreviewWindowOpen (WindowStateListener)
onWindowOpened (WindowStateListener)
onWindowOpenVetoed (WindowStateListener)
onPreviewWindowClose (WindowStateListener)
onWindowClosed (WindowStateListener)
onWindowCloseVetoed (WindowStateListener)
onActionMappingAdded (WindowActionMappingListener)
onActionMappingsRemoved (WindowActionMappingListener)
onKeyStrokeChanged (WindowActionMappingListener)
onActionChanged (WindowActionMappingListener)
onComponentInserted (ContainerListener)
onComponentsRemoved (ContainerListener)
onFocusTraversalPolicyChanged (ContainerListener)
onContextKeyChanged (ContainerListener)
onMouseDown (ContainerMouseListener)
onMouseMove (ContainerMouseListener)
onMouseUp (ContainerMouseListener)
onMouseWheel (ContainerMouseListener)
onParentChanged (ComponentListener)
onSizeChanged (ComponentListener)
onPreferredSizeChanged (ComponentListener)
onPreferredWidthLimitsChanged (ComponentListener)
onPreferredHeightLimitsChanged (ComponentListener)
onLocationChanged (ComponentListener)
onVisibleChanged (ComponentListener)
onCursorChanged (ComponentListener)
onTooltipTextChanged (ComponentListener)
onDragSourceChanged (ComponentListener)
onDropTargetChanged (ComponentListener)
onMenuHandlerChanged (ComponentListener)
onStyleUpdated (ComponentListener)
onEnabledChanged (ComponentStateListener)
onFocusedChanged (ComponentStateListener)
onDecoratorInserted (ComponentDecoratorListener)
onDecoratorUpdated (ComponentDecoratorListener)
onDecoratorsRemoved (ComponentDecoratorListener)
onMouseMove (ComponentMouseListener)
onMouseOut (ComponentMouseListener)
onMouseOver (ComponentMouseListener)
onMouseDown (ComponentMouseButtonListener)
onMouseUp (ComponentMouseButtonListener)
onMouseClick (ComponentMouseButtonListener)
onMouseWheel (ComponentMouseWheelListener)
onKeyReleased (ComponentKeyListener)
onKeyTyped (ComponentKeyListener)
onKeyPressed (ComponentKeyListener)
onValueAdded (ComponentDataListener)
onValueUpdated (ComponentDataListener)
onValueRemoved (ComponentDataListener)
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;

import org.apache.pivot.util.ListenerList;
import org.apache.pivot.wtk.Window;

public class ScanEventListenerMethods {
    public static final String ON_PREFIX = "on";

    public static void main(String[] args) throws Exception {
        Method[] methods = Window.class.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("...");
                    }

                    Method[] interfaceMethods = listenerInterface.getMethods();

                    for (int j = 0; j < interfaceMethods.length; j++) {
                        Method interfaceMethod = interfaceMethods[j];

                        String key = interfaceMethod.getName();
                        key = Character.toUpperCase(key.charAt(0)) + key.substring(1);
                        key = ON_PREFIX + key;

                        System.out.println(key + " (" + listenerInterface.getSimpleName() + ")");
                    }
                }
            }
        }
    }
}

Reply via email to