The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


Gooey Event Proxy

Posted by evanx on July 21, 2008 at 1:02 PM PDT

In the Gooey MvnC prequel, we consider an MVC-type separation for programming a Swing UI panel, and convention-over-configuration to automate events, threading and beans binding.

Now as an illustration of the above intent, we implement a minimalistic helper class to create dynamic proxies for event listeners wired to event handler methods in our controller.


Salient Samples

In our controller, we implement event handler methods as follows.

public class LoginController implements GEventController {
   LoginView view = new LoginView();
   LoginModel model = new LoginModel();
   GEventHelper eventHelper = new GEventHelper(this, view, model);
   ...   
   void usernameFocusLost() {
      ... // check that username is valid
   }
   
   void cancelActionPerformed() {
      ... // handle cancel button pressed
   }   
   
   SwingWorker okActionPerformed() {
      ... // worker for OK button pressed to login
   }      
}

Our helper creates dynamic proxies as event listeners registered on our components, as follows.

public class GEventHelper {
    protected GEventController controller;
    protected Map<Field, Component> components = new HashMap();
    protected Map<Component, GBeanProperty> bindings = new HashMap();

    public GEventHelper(GEventController controller, Component view, GBean model) {
        this.controller = controller;
        initComponents(view); // populate components map
        bind(model); // create bindings/listeners
        connectController();
    }
    ...
    public void connectController() {
        for (Component component : components.values()) {
            if (GInputComponentAdapterFactory.isInputComponent(component)) {
                GInputComponentAdapterFactory.create(component).addActionListener(
                        (ActionListener) createListenerProxy(component,
                        ActionListener.class));
                GInputComponentAdapterFactory.create(component).addFocusListener(
                        (FocusListener) createListenerProxy(component,
                        FocusListener.class));
                ... // other events
            }
        }
    }
    
    protected Object createListenerProxy(Component source, Class listenerType) {
        return Proxy.newProxyInstance(
                source.getClass().getClassLoader(),
                new Class[]{listenerType},
                new GEventProxy(controller, source));
    }
    ...
}

where our GEventProxy below will invoke methods in our controller eg. usernameFocusLost() when focusLost() is invoked on a proxy listener registered on a component named "username".

public class GEventProxy implements InvocationHandler {
   ...
   protected void invoke(Method method, Object[] args) {
        for (Method eventMethod : eventMethods.values()) {
            if (eventMethod.getName().equalsIgnoreCase(
                    component.getName() + method.getName())) {
                invokeHandler(eventMethod, args);
                break;
            }
        }
    }
}    


Related Topics >> Java Desktop      
Comments
Comments are listed in date ascending order (oldest first)