]> source.dussan.org Git - vaadin-framework.git/commitdiff
Work in progress
authorArtur Signell <artur.signell@itmill.com>
Wed, 25 Nov 2009 14:33:16 +0000 (14:33 +0000)
committerArtur Signell <artur.signell@itmill.com>
Wed, 25 Nov 2009 14:33:16 +0000 (14:33 +0000)
svn changeset:10026/svn branch:event-framework-3234

27 files changed:
src/com/vaadin/event/ClientEventList.java [deleted file]
src/com/vaadin/event/EventRouter.java
src/com/vaadin/event/FieldEvents.java
src/com/vaadin/event/ItemClickEvent.java
src/com/vaadin/event/LayoutEvents.java [new file with mode: 0644]
src/com/vaadin/event/ListenerMethod.java
src/com/vaadin/event/MouseEvents.java
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
src/com/vaadin/terminal/gwt/client/ComponentDetail.java
src/com/vaadin/terminal/gwt/client/ComponentEventHandler.java [deleted file]
src/com/vaadin/terminal/gwt/client/EventListenerRegister.java [new file with mode: 0644]
src/com/vaadin/terminal/gwt/client/MouseEventDetails.java
src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java
src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java
src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java
src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java
src/com/vaadin/terminal/gwt/client/ui/VPanel.java
src/com/vaadin/terminal/gwt/client/ui/VTextField.java
src/com/vaadin/ui/AbsoluteLayout.java
src/com/vaadin/ui/AbstractComponent.java
src/com/vaadin/ui/AbstractOrderedLayout.java
src/com/vaadin/ui/Embedded.java
src/com/vaadin/ui/GridLayout.java
src/com/vaadin/ui/Panel.java
src/com/vaadin/ui/Table.java
src/com/vaadin/ui/TextField.java
src/com/vaadin/ui/Tree.java

diff --git a/src/com/vaadin/event/ClientEventList.java b/src/com/vaadin/event/ClientEventList.java
deleted file mode 100644 (file)
index e200808..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* \r
-@ITMillApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.event;\r
-\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-/**\r
- * \r
- * <code>ClientEventList</code> class used to store the registered events so a\r
- * list of the required client event identifiers (that the client-side should\r
- * listen for and send to the server-side) can be sent to the client-side via a\r
- * variable.\r
- * \r
- * @author davengo GmbH (Germany/Berlin, www.davengo.com)\r
- * @since 6.2\r
- * \r
- */\r
-public class ClientEventList {\r
-\r
-    /**\r
-     * the list containing the registered client events (as strings for\r
-     * client-side transfer)\r
-     * \r
-     * @since 6.2\r
-     */\r
-    private Map<String, Integer> clientEvents = null;\r
-\r
-    /**\r
-     * initializes the list if necessary\r
-     * \r
-     * @since 6.2\r
-     */\r
-    private void checkList() {\r
-        if (clientEvents == null) {\r
-            clientEvents = new HashMap<String, Integer>();\r
-        }\r
-    }\r
-\r
-    /**\r
-     * listens for the event <br>\r
-     * <br>\r
-     * increments the internal counter for the event by one\r
-     * \r
-     * @param eventIdentifier\r
-     *            the identifier of the event to listen for\r
-     * \r
-     * @return true, if the event is newly added to the list<br>\r
-     *         false, if the list already contained the event (the internal\r
-     *         counter was incremented)\r
-     * \r
-     * @since 6.2\r
-     */\r
-    public boolean listenEvent(String eventIdentifier) {\r
-        checkList();\r
-        if (!clientEvents.keySet().contains(eventIdentifier)) {\r
-            clientEvents.put(eventIdentifier, 1);\r
-            return true;\r
-        } else {\r
-            clientEvents.put(eventIdentifier,\r
-                    clientEvents.get(eventIdentifier) + 1);\r
-            return false;\r
-        }\r
-    }\r
-\r
-    /**\r
-     * unlistens for an event <br>\r
-     * <br>\r
-     * decrements the internal counter by one, if 0 is reached the event is\r
-     * removed from the event-list\r
-     * \r
-     * @param eventIdentifier\r
-     *            the identifier of the event to stop listening for\r
-     * @return true, if the event was removed from the list<br>\r
-     *         false, if the event is hold in list (the internal counter was\r
-     *         greater than zero)\r
-     */\r
-    public boolean unlistenEvent(String eventIdentifier) {\r
-        checkList();\r
-        if (clientEvents.keySet().contains(eventIdentifier)) {\r
-            clientEvents.put(eventIdentifier,\r
-                    clientEvents.get(eventIdentifier) - 1);\r
-            if (clientEvents.get(eventIdentifier) <= 0) {\r
-                clientEvents.remove(eventIdentifier);\r
-                return true;\r
-            }\r
-            return false;\r
-        }\r
-        return false;\r
-    }\r
-\r
-    /**\r
-     * @return a string array containing all registered events\r
-     * \r
-     * @since 6.2\r
-     */\r
-    public String[] getEvents() {\r
-        if (clientEvents == null) {\r
-            return new String[] {};\r
-        }\r
-        return clientEvents.keySet().toArray(new String[] {});\r
-    }\r
-\r
-}\r
index ca98c5e799fb2cae5972902aa476df00a6a67aaf..b12a2802627b66c56414a72ec24b006b35b68660 100644 (file)
@@ -26,7 +26,7 @@ public class EventRouter implements MethodEventSource {
     /**
      * List of registered listeners.
      */
-    private Set listenerList = null;
+    private Set<ListenerMethod> listenerList = null;
 
     /*
      * Registers a new listener with the specified activation method to listen
@@ -35,7 +35,7 @@ public class EventRouter implements MethodEventSource {
      */
     public void addListener(Class eventType, Object object, Method method) {
         if (listenerList == null) {
-            listenerList = new LinkedHashSet();
+            listenerList = new LinkedHashSet<ListenerMethod>();
         }
         listenerList.add(new ListenerMethod(eventType, object, method));
     }
@@ -47,7 +47,7 @@ public class EventRouter implements MethodEventSource {
      */
     public void addListener(Class eventType, Object object, String methodName) {
         if (listenerList == null) {
-            listenerList = new LinkedHashSet();
+            listenerList = new LinkedHashSet<ListenerMethod>();
         }
         listenerList.add(new ListenerMethod(eventType, object, methodName));
     }
@@ -59,9 +59,9 @@ public class EventRouter implements MethodEventSource {
      */
     public void removeListener(Class eventType, Object target) {
         if (listenerList != null) {
-            final Iterator i = listenerList.iterator();
+            final Iterator<ListenerMethod> i = listenerList.iterator();
             while (i.hasNext()) {
-                final ListenerMethod lm = (ListenerMethod) i.next();
+                final ListenerMethod lm = i.next();
                 if (lm.matches(eventType, target)) {
                     i.remove();
                     return;
@@ -77,9 +77,9 @@ public class EventRouter implements MethodEventSource {
      */
     public void removeListener(Class eventType, Object target, Method method) {
         if (listenerList != null) {
-            final Iterator i = listenerList.iterator();
+            final Iterator<ListenerMethod> i = listenerList.iterator();
             while (i.hasNext()) {
-                final ListenerMethod lm = (ListenerMethod) i.next();
+                final ListenerMethod lm = i.next();
                 if (lm.matches(eventType, target, method)) {
                     i.remove();
                     return;
@@ -109,9 +109,9 @@ public class EventRouter implements MethodEventSource {
 
         // Remove the listeners
         if (listenerList != null) {
-            final Iterator i = listenerList.iterator();
+            final Iterator<ListenerMethod> i = listenerList.iterator();
             while (i.hasNext()) {
-                final ListenerMethod lm = (ListenerMethod) i.next();
+                final ListenerMethod lm = i.next();
                 if (lm.matches(eventType, target, method)) {
                     i.remove();
                     return;
@@ -141,10 +141,21 @@ public class EventRouter implements MethodEventSource {
             // Send the event to all listeners. The listeners themselves
             // will filter out unwanted events.
 
-            final Iterator i = listenerList.iterator();
+            final Iterator<ListenerMethod> i = listenerList.iterator();
             while (i.hasNext()) {
-                ((ListenerMethod) i.next()).receiveEvent(event);
+                (i.next()).receiveEvent(event);
             }
         }
     }
+
+    public boolean hasListeners(Class<?> eventType) {
+        if (listenerList != null) {
+            for (ListenerMethod lm : listenerList) {
+                if (lm.isType(eventType)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
 }
index 3becb58aef01747e81f59e544c5d2accd72b9779..fc9f225b8f331c2bb68a3ae9266759d6e55df9a9 100644 (file)
@@ -83,41 +83,4 @@ public interface FieldEvents {
         public void blur(BlurEvent event);\r
     }\r
 \r
-    /**\r
-     * <code>ValueChangeEvent</code> class for holding additional event\r
-     * information. Fired when the value of a <code>Field</code> changes.\r
-     * \r
-     * @since 6.2\r
-     */\r
-    public class ValueChangeEvent extends Component.Event {\r
-\r
-        private static final long serialVersionUID = -7644184999481404162L;\r
-\r
-        public ValueChangeEvent(Component source) {\r
-            super(source);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * <code>ValueChangeListener</code> interface for listening for\r
-     * <code>ValueChangeEvent</code> fired by a <code>Field</code>.\r
-     * \r
-     * @see ValueChangeEvent\r
-     * @since 6.2\r
-     */\r
-    public interface ValueChangeListener extends ComponentEventListener {\r
-\r
-        public static final Method valueChangeMethod = ReflectTools.findMethod(\r
-                ValueChangeListener.class, "valueChange",\r
-                ValueChangeEvent.class);\r
-\r
-        /**\r
-         * Component value was changed\r
-         * \r
-         * @param event\r
-         *            Component change event.\r
-         */\r
-        public void valueChange(ValueChangeEvent event);\r
-    }\r
-\r
 }\r
index b69e8e4c92a441aaa7fb48b77514b9cb4e0b33db..4fe87d927e90f6495035451292b0b4f371a39b9a 100644 (file)
@@ -6,42 +6,29 @@ import java.lang.reflect.Method;
 import com.vaadin.data.Container;
 import com.vaadin.data.Item;
 import com.vaadin.data.Property;
+import com.vaadin.event.MouseEvents.ClickEvent;
 import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.ui.Component;
-import com.vaadin.ui.Component.Event;
 
 /**
  * 
  * Click event fired by a {@link Component} implementing
- * {@link com.vaadin.data.Container} interface. ItemClickEvents happens
- * on an {@link Item} rendered somehow on terminal. Event may also contain a
- * specific {@link Property} on which the click event happened.
- * 
- * ClickEvents are rather terminal dependent events. Correct values in event
- * details cannot be guaranteed.
- * 
- * EXPERIMENTAL FEATURE, user input is welcome
+ * {@link com.vaadin.data.Container} interface. ItemClickEvents happens on an
+ * {@link Item} rendered somehow on terminal. Event may also contain a specific
+ * {@link Property} on which the click event happened.
  * 
  * @since 5.3
  * 
- *        TODO extract generic super class/interfaces if we implement some other
- *        click events.
  */
 @SuppressWarnings("serial")
-public class ItemClickEvent extends Event implements Serializable {
-    public static final int BUTTON_LEFT = MouseEventDetails.BUTTON_LEFT;
-    public static final int BUTTON_MIDDLE = MouseEventDetails.BUTTON_MIDDLE;
-    public static final int BUTTON_RIGHT = MouseEventDetails.BUTTON_RIGHT;
-
-    private MouseEventDetails details;
+public class ItemClickEvent extends ClickEvent implements Serializable {
     private Item item;
     private Object itemId;
     private Object propertyId;
 
     public ItemClickEvent(Component source, Item item, Object itemId,
             Object propertyId, MouseEventDetails details) {
-        super(source);
-        this.details = details;
+        super(source, details);
         this.item = item;
         this.itemId = itemId;
         this.propertyId = propertyId;
@@ -77,38 +64,6 @@ public class ItemClickEvent extends Event implements Serializable {
         return propertyId;
     }
 
-    public int getButton() {
-        return details.getButton();
-    }
-
-    public int getClientX() {
-        return details.getClientX();
-    }
-
-    public int getClientY() {
-        return details.getClientY();
-    }
-
-    public boolean isDoubleClick() {
-        return details.isDoubleClick();
-    }
-
-    public boolean isAltKey() {
-        return details.isAltKey();
-    }
-
-    public boolean isCtrlKey() {
-        return details.isCtrlKey();
-    }
-
-    public boolean isMetaKey() {
-        return details.isMetaKey();
-    }
-
-    public boolean isShiftKey() {
-        return details.isShiftKey();
-    }
-
     public static final Method ITEM_CLICK_METHOD;
 
     static {
diff --git a/src/com/vaadin/event/LayoutEvents.java b/src/com/vaadin/event/LayoutEvents.java
new file mode 100644 (file)
index 0000000..025e9bb
--- /dev/null
@@ -0,0 +1,48 @@
+package com.vaadin.event;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
+import com.vaadin.tools.ReflectTools;
+import com.vaadin.ui.Component;
+
+public interface LayoutEvents {
+
+    public interface LayoutClickListener extends ComponentEventListener {
+
+        public static final Method clickMethod = ReflectTools.findMethod(
+                LayoutClickListener.class, "layoutClick",
+                LayoutClickEvent.class);
+
+        /**
+         * Layout has been clicked
+         * 
+         * @param event
+         *            Component click event.
+         */
+        public void layoutClick(LayoutClickEvent event);
+    }
+
+    /**
+     * An event fired when the layout has been clicked. The event contains
+     * information about the target layout (component) and the child component
+     * that was clicked. If no child component was found it is set to null.
+     * 
+     */
+    public static class LayoutClickEvent extends ClickEvent {
+
+        private Component childComponent;
+
+        public LayoutClickEvent(Component source,
+                MouseEventDetails mouseEventDetails, Component childComponent) {
+            super(source, mouseEventDetails);
+            this.childComponent = childComponent;
+        }
+
+        public Component getChildComponent() {
+            return childComponent;
+        }
+
+    }
+}
\ No newline at end of file
index 3efd4c70c7635068c5e219ecf85b02550082e106..b294dbf86d5e7614e6f438ea94e4783c48384e51 100644 (file)
@@ -638,4 +638,8 @@ public class ListenerMethod implements EventListener, Serializable {
         }
 
     }
+
+    public boolean isType(Class<?> eventType) {
+        return this.eventType == eventType;
+    }
 }
index bf417c1ebff1e7296f1ebf48c2e7bd679b1af735..09fcc85b592d38040dd10b033ea7c630684381b7 100644 (file)
@@ -6,43 +6,65 @@ package com.vaadin.event;
 
 import java.lang.reflect.Method;
 
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.tools.ReflectTools;
 import com.vaadin.ui.Component;
 
 public interface MouseEvents {
 
-    /**
-     * defines the clicked mouse button for ClickEvents
-     */
-    public enum MouseButton {
-        LEFT, RIGHT, MIDDLE
-    }
-
     /**
      * <code>ClickEvent</code> class for holding additional event information.
      * Fired when the user clicks on a <code>Component</code>.
      * 
+     * ClickEvents are rather terminal dependent events. Correct values in event
+     * details cannot be guaranteed.
+     * 
      * @since 6.2
      */
     public class ClickEvent extends Component.Event {
+        public static final int BUTTON_LEFT = MouseEventDetails.BUTTON_LEFT;
+        public static final int BUTTON_MIDDLE = MouseEventDetails.BUTTON_MIDDLE;
+        public static final int BUTTON_RIGHT = MouseEventDetails.BUTTON_RIGHT;
 
-        private MouseButton mouseButton;
+        private MouseEventDetails details;
 
         private static final long serialVersionUID = -7644184999481404162L;
 
-        public ClickEvent(Component source, String mouseButton) {
+        public ClickEvent(Component source, MouseEventDetails mouseEventDetails) {
             super(source);
-            if (mouseButton.equals("left")) {
-                this.mouseButton = MouseButton.LEFT;
-            } else if (mouseButton.equals("right")) {
-                this.mouseButton = MouseButton.RIGHT;
-            } else {
-                this.mouseButton = MouseButton.MIDDLE;
-            }
+            this.details = mouseEventDetails;
+        }
+
+        public int getButton() {
+            return details.getButton();
+        }
+
+        public int getClientX() {
+            return details.getClientX();
+        }
+
+        public int getClientY() {
+            return details.getClientY();
+        }
+
+        public boolean isDoubleClick() {
+            return details.isDoubleClick();
+        }
+
+        public boolean isAltKey() {
+            return details.isAltKey();
+        }
+
+        public boolean isCtrlKey() {
+            return details.isCtrlKey();
+        }
+
+        public boolean isMetaKey() {
+            return details.isMetaKey();
         }
 
-        public MouseButton getMouseButton() {
-            return mouseButton;
+        public boolean isShiftKey() {
+            return details.isShiftKey();
         }
 
     }
index 362e3eb8b1edbf45a6e207cde0bba678c6f3833a..9ee2b8842f54c0137f945a98991f35a6dca2623c 100755 (executable)
@@ -1115,7 +1115,7 @@ public class ApplicationConnection {
 
         // register the listened events by the server-side to the event-handler
         // of the component
-        componentDetail.getEventHandler().registerEventsFromUIDL(uidl);
+        componentDetail.registerEventListenersFromUIDL(uidl);
 
         // Visibility
         boolean visible = !uidl.getBooleanAttribute("invisible");
@@ -1785,16 +1785,19 @@ public class ApplicationConnection {
     }
 
     /**
-     * returns the event handler for the given paintable
+     * Checks if there is a registered server side listener for the event. The
+     * list of events which has server side listeners is updated automatically
+     * before the component is updated so the value is correct if called from
+     * updatedFromUIDL.
      * 
-     * @param paintable
-     * @return
+     * @param eventIdentifier
+     *            The identifier for the event
+     * @return true if at least one listener has been registered on server side
+     *         for the event identified by eventIdentifier.
      */
-    public ComponentEventHandler getEventHandler(Paintable paintable) {
-        ComponentDetail componentDetail = idToPaintableDetail
-                .get(getPid(paintable));
-
-        return componentDetail.getEventHandler();
+    public boolean hasEventListeners(Paintable paintable, String eventIdentifier) {
+        return idToPaintableDetail.get(getPid(paintable)).hasEventListeners(
+                eventIdentifier);
     }
 
 }
index 8f39733ef1d4221311b99ab94607963aadc2e7f3..2d7f28dd4bb53687f1d702fb9f5adc9d65923769 100644 (file)
@@ -7,7 +7,7 @@ import com.vaadin.terminal.gwt.client.RenderInformation.Size;
 
 class ComponentDetail {
 
-    private ComponentEventHandler eventHandler;
+    private EventListenerRegister eventListenerRegister = new EventListenerRegister();
     private Paintable component;
     private TooltipInfo tooltipInfo = new TooltipInfo();
     private String pid;
@@ -16,10 +16,6 @@ class ComponentDetail {
             Paintable component) {
         this.component = component;
         this.pid = pid;
-
-        // create the event handler for this component
-        this.eventHandler = new ComponentEventHandler(this, client);
-
     }
 
     /**
@@ -108,8 +104,12 @@ class ComponentDetail {
         }
     }
 
-    public ComponentEventHandler getEventHandler() {
-        return eventHandler;
+    void registerEventListenersFromUIDL(UIDL uidl) {
+        eventListenerRegister.registerEventListenersFromUIDL(uidl);
+    }
+
+    public boolean hasEventListeners(String eventIdentifier) {
+        return eventListenerRegister.hasEventListeners(eventIdentifier);
     }
 
 }
diff --git a/src/com/vaadin/terminal/gwt/client/ComponentEventHandler.java b/src/com/vaadin/terminal/gwt/client/ComponentEventHandler.java
deleted file mode 100644 (file)
index 2df8f9b..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* \r
-@ITMillApache2LicenseForJavaFiles@\r
- */\r
-\r
-package com.vaadin.terminal.gwt.client;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-/**\r
- * \r
- * class for event handlers used by ComponentEventHandler\r
- * \r
- * @author davengo GmbH (Germany/Berlin, www.davengo.com)\r
- * @since 6.2\r
- * \r
- */\r
-public class ComponentEventHandler {\r
-\r
-    public static final String HANDLER_LISTEN_ATTRIBUTE = "listenEvents";\r
-    public static final String HANDLER_TRIGGER_VARIABLE = "fireEvent";\r
-\r
-    private List<String> eventRegistrations;\r
-    private ComponentDetail detail;\r
-    private ApplicationConnection client;\r
-\r
-    /**\r
-     * creates a new <code>ComponentEventHandler</code> instance for the given\r
-     * <code>ComponentDetail</code> and <code>ApplicationConntection</code>\r
-     * instance.\r
-     * \r
-     * @param detail\r
-     *            the attached ComponentDetail\r
-     * @param client\r
-     *            the <code>ApplicationConnection</code> for sending events\r
-     * \r
-     * @see ApplicationConnection\r
-     * @see ComponentDetail\r
-     * @since 6.2\r
-     */\r
-    public ComponentEventHandler(ComponentDetail detail,\r
-            ApplicationConnection client) {\r
-        this.detail = detail;\r
-        this.client = client;\r
-        this.eventRegistrations = null;\r
-    }\r
-\r
-    /**\r
-     * Fires a event which is transmitted to the server and passed on the the\r
-     * components handleEvent method provided listeners have been registered on\r
-     * the server side.\r
-     * \r
-     * @param eventIdentifier\r
-     *            the unique identifier for the event\r
-     * @param parameters\r
-     *            the parameters for the event (can be null)\r
-     * @since 6.2\r
-     */\r
-    public void fireEvent(String eventIdentifier, String... parameters) {\r
-        fireEvent(eventIdentifier, false, parameters);\r
-    }\r
-\r
-    /**\r
-     * Fires a component event which is transmitted to the server and passed on\r
-     * the the components handleEvent method. The event is sent to the server\r
-     * even though there are no explicit listeners registered on the server\r
-     * side.\r
-     * \r
-     * @param eventIdentifier\r
-     *            the unique identifier for the event\r
-     * @param parameters\r
-     *            the parameters for the event (can be null)\r
-     * @since 6.2\r
-     */\r
-    public void fireComponentEvent(String eventIdentifier, String... parameters) {\r
-        fireEvent(eventIdentifier, true, parameters);\r
-    }\r
-\r
-    /**\r
-     * Transmit the event to the Server (Fires a event which is transmitted to\r
-     * the server and passed on the the components handleEvent method)\r
-     * \r
-     * @param eventIdentifier\r
-     *            the unique identifier for the event\r
-     * @param forceTransmission\r
-     *            enforce the transmission to the server\r
-     * @param parameters\r
-     *            the parameters for the event (can be null)\r
-     * @since 6.2\r
-     */\r
-    private void fireEvent(String eventIdentifier, boolean forceTransmission,\r
-            String... parameters) {\r
-\r
-        String[] event;\r
-\r
-        // filter events which are not listened on the server-side right here\r
-        boolean transmit = forceTransmission\r
-                || ((!(eventRegistrations == null)) && eventRegistrations\r
-                        .contains(eventIdentifier));\r
-\r
-        if (transmit) {\r
-            if (parameters != null) {\r
-                event = new String[parameters.length + 1];\r
-                event[0] = eventIdentifier;\r
-                for (int i = 0; i < parameters.length; i++) {\r
-                    event[i + 1] = parameters[i];\r
-                }\r
-            } else {\r
-                event = new String[] { eventIdentifier };\r
-            }\r
-\r
-            // transmit the event to the server-side\r
-            client.updateVariable(detail.getPid(), HANDLER_TRIGGER_VARIABLE,\r
-                    event, true);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * Registers the Events listened on the server-side from the UIDL\r
-     * \r
-     * @param componentUIDL\r
-     * @since 6.2\r
-     */\r
-    void registerEventsFromUIDL(UIDL componentUIDL) {\r
-\r
-        // read out the request event handlers\r
-        if (componentUIDL.hasAttribute(HANDLER_LISTEN_ATTRIBUTE)) {\r
-            String[] requestedEvents = componentUIDL\r
-                    .getStringArrayAttribute(HANDLER_LISTEN_ATTRIBUTE);\r
-\r
-            // create the eventRegistrations list if necessary\r
-            if ((requestedEvents.length > 0) && (eventRegistrations == null)) {\r
-                eventRegistrations = new ArrayList<String>();\r
-            }\r
-\r
-            // parse the requested event handlers\r
-            for (String reqEvent : requestedEvents) {\r
-\r
-                if (!eventRegistrations.contains(reqEvent)) {\r
-                    eventRegistrations.add(reqEvent);\r
-                }\r
-\r
-            }\r
-\r
-        }\r
-\r
-    }\r
-\r
-}\r
diff --git a/src/com/vaadin/terminal/gwt/client/EventListenerRegister.java b/src/com/vaadin/terminal/gwt/client/EventListenerRegister.java
new file mode 100644 (file)
index 0000000..63710c3
--- /dev/null
@@ -0,0 +1,70 @@
+/* \r
+@ITMillApache2LicenseForJavaFiles@\r
+ */\r
+\r
+package com.vaadin.terminal.gwt.client;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+/**\r
+ * \r
+ * EventListenerRegister is used internally for keeping track of which component\r
+ * events have registered listeners on the server-side.\r
+ * \r
+ * @author davengo GmbH (Germany/Berlin, www.davengo.com), IT Mill\r
+ * @since 6.2\r
+ * \r
+ */\r
+public class EventListenerRegister {\r
+\r
+    public static final String REGISTERED_EVENT_LISTENERS_ATTRIBUTE = "eventListeners";\r
+\r
+    private List<String> eventRegistrations;\r
+\r
+    EventListenerRegister() {\r
+    }\r
+\r
+    /**\r
+     * Checks if there is a registered server side listener for the event.\r
+     * \r
+     * @param eventIdentifier\r
+     *            The identifier for the event\r
+     * @return true if at least one listener has been registered on server side\r
+     *         for the event identified by eventIdentifier.\r
+     */\r
+    boolean hasEventListeners(String eventIdentifier) {\r
+        return ((!(eventRegistrations == null)) && eventRegistrations\r
+                .contains(eventIdentifier));\r
+    }\r
+\r
+    /**\r
+     * Stores the event listeners registered on server-side and passed along in\r
+     * the UIDL.\r
+     * \r
+     * @param componentUIDL\r
+     *            The UIDL for the component\r
+     * @since 6.2\r
+     */\r
+    void registerEventListenersFromUIDL(UIDL componentUIDL) {\r
+\r
+        // read out the request event handlers\r
+        if (componentUIDL.hasAttribute(REGISTERED_EVENT_LISTENERS_ATTRIBUTE)) {\r
+            String[] registeredListeners = componentUIDL\r
+                    .getStringArrayAttribute(REGISTERED_EVENT_LISTENERS_ATTRIBUTE);\r
+\r
+            if (registeredListeners == null || registeredListeners.length == 0) {\r
+                eventRegistrations = null;\r
+            } else {\r
+                eventRegistrations = new ArrayList<String>(\r
+                        registeredListeners.length);\r
+                for (String listener : registeredListeners) {\r
+                    eventRegistrations.add(listener);\r
+                }\r
+            }\r
+\r
+        }\r
+\r
+    }\r
+\r
+}\r
index 175dfd8ce2ece8c90be1e2e15aea80d9156c2974..abe332e6df21ee0b84a1b915f6b7bc3dd7eeeb1b 100644 (file)
@@ -1,6 +1,6 @@
 package com.vaadin.terminal.gwt.client;
 
-import com.google.gwt.user.client.DOM;
+import com.google.gwt.dom.client.NativeEvent;
 import com.google.gwt.user.client.Event;
 
 /**
@@ -50,15 +50,15 @@ public class MouseEventDetails {
         return shiftKey;
     }
 
-    public MouseEventDetails(Event evt) {
-        button = DOM.eventGetButton(evt);
-        clientX = DOM.eventGetClientX(evt);
-        clientY = DOM.eventGetClientY(evt);
-        altKey = DOM.eventGetAltKey(evt);
-        ctrlKey = DOM.eventGetCtrlKey(evt);
-        metaKey = DOM.eventGetMetaKey(evt);
-        shiftKey = DOM.eventGetShiftKey(evt);
-        type = DOM.eventGetType(evt);
+    public MouseEventDetails(NativeEvent evt) {
+        button = evt.getButton();
+        clientX = evt.getClientX();
+        clientY = evt.getClientY();
+        altKey = evt.getAltKey();
+        ctrlKey = evt.getCtrlKey();
+        metaKey = evt.getMetaKey();
+        shiftKey = evt.getShiftKey();
+        type = Event.getTypeInt(evt.getType());
     }
 
     private MouseEventDetails() {
@@ -66,12 +66,16 @@ public class MouseEventDetails {
 
     @Override
     public String toString() {
+        return serialize();
+    }
+
+    public String serialize() {
         return "" + button + DELIM + clientX + DELIM + clientY + DELIM + altKey
                 + DELIM + ctrlKey + DELIM + metaKey + DELIM + shiftKey + DELIM
                 + type;
     }
 
-    public static MouseEventDetails deSerialize(String serializedString) {
+    public static MouseEventDetails deserialize(String serializedString) {
         MouseEventDetails instance = new MouseEventDetails();
         String[] fields = serializedString.split(",");
 
@@ -86,6 +90,10 @@ public class MouseEventDetails {
         return instance;
     }
 
+    public Class<MouseEventDetails> getType() {
+        return MouseEventDetails.class;
+    }
+
     public boolean isDoubleClick() {
         return type == Event.ONDBLCLICK;
     }
index bd778c8d5ca64fb85e90ca23803f1a3246b85e63..ff26e4b0056f75d160e29993608164b93a348069 100644 (file)
@@ -10,6 +10,9 @@ import java.util.Map.Entry;
 import com.google.gwt.dom.client.DivElement;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Style;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.ui.ComplexPanel;
@@ -18,12 +21,14 @@ import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.Container;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.Paintable;
 import com.vaadin.terminal.gwt.client.RenderSpace;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.VCaption;
 
-public class VAbsoluteLayout extends ComplexPanel implements Container {
+public class VAbsoluteLayout extends ComplexPanel implements Container,
+        ClickHandler {
 
     /** Tag name for widget creation */
     public static final String TAGNAME = "absolutelayout";
@@ -31,6 +36,8 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
     /** Class name, prefix in styling */
     public static final String CLASSNAME = "v-absolutelayout";
 
+    public static final String CLICK_EVENT_IDENTIFIER = "click";
+
     private DivElement marginElement;
 
     protected final Element canvas = DOM.createDiv();
@@ -55,6 +62,7 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
         canvas.getStyle().setProperty("overflow", "hidden");
         marginElement.appendChild(canvas);
         getElement().appendChild(marginElement);
+        addDomHandler(this, ClickEvent.getType());
     }
 
     public RenderSpace getAllocatedSpace(Widget child) {
@@ -129,6 +137,8 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
             return;
         }
 
+        handleHandlerRegistration();
+
         HashSet<String> unrenderedPids = new HashSet<String>(
                 pidToComponentWrappper.keySet());
 
@@ -148,6 +158,26 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
         rendering = false;
     }
 
+    private HandlerRegistration clickHandlerRegistration;
+
+    private void handleHandlerRegistration() {
+        // Handle registering/unregistering of click handler depending on if
+        // server side listeners have been added or removed.
+        if (client.hasEventListeners(this, CLICK_EVENT_IDENTIFIER)) {
+            if (clickHandlerRegistration == null) {
+                clickHandlerRegistration = addDomHandler(this, ClickEvent
+                        .getType());
+            }
+        } else {
+            if (clickHandlerRegistration != null) {
+                clickHandlerRegistration.removeHandler();
+                clickHandlerRegistration = null;
+
+            }
+        }
+
+    }
+
     private AbsoluteWrapper getWrapper(ApplicationConnection client,
             UIDL componentUIDL) {
         AbsoluteWrapper wrapper = pidToComponentWrappper.get(componentUIDL
@@ -390,4 +420,34 @@ public class VAbsoluteLayout extends ComplexPanel implements Container {
         }
     }
 
+    public void onClick(ClickEvent event) {
+        // This is only called if there are click listeners registered on server
+        // side
+        Paintable childComponent = getChildComponent((Element) event
+                .getNativeEvent().getEventTarget().cast());
+        final MouseEventDetails details = new MouseEventDetails(event
+                .getNativeEvent());
+
+        Object[] parameters = new Object[] { details, childComponent };
+
+        client.updateVariable(client.getPid(this), CLICK_EVENT_IDENTIFIER,
+                parameters, true);
+    }
+
+    private Paintable getChildComponent(Element target) {
+        while (target != null && target != canvas) {
+            Paintable paintable = client.getPaintable(target);
+            if (paintable != null) {
+                String pid = client.getPid(paintable);
+                AbsoluteWrapper wrapper = pidToComponentWrappper.get(pid);
+                if (wrapper != null) {
+                    return paintable;
+                }
+            }
+            target = DOM.getParent(target);
+        }
+
+        return null;
+    }
+
 }
index 159ecafa531b0008fc98d8202f0cc45f6ff9c50d..2c00a68f9253ba8daac449d781224b39a63179f5 100644 (file)
@@ -13,18 +13,24 @@ import com.google.gwt.dom.client.ObjectElement;
 import com.google.gwt.dom.client.Style;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.MouseUpEvent;
+import com.google.gwt.event.dom.client.MouseUpHandler;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Event;
 import com.google.gwt.user.client.ui.HTML;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.Paintable;
 import com.vaadin.terminal.gwt.client.UIDL;
 import com.vaadin.terminal.gwt.client.Util;
 import com.vaadin.terminal.gwt.client.VTooltip;
 
-public class VEmbedded extends HTML implements Paintable, ClickHandler {
+public class VEmbedded extends HTML implements Paintable, ClickHandler,
+        MouseUpHandler {
+    public static final String CLICK_EVENT_IDENTIFIER = "click";
+
     private static String CLASSNAME = "v-embedded";
 
     private String height;
@@ -36,6 +42,7 @@ public class VEmbedded extends HTML implements Paintable, ClickHandler {
     public VEmbedded() {
         setStyleName(CLASSNAME);
         addClickHandler(this);
+        addMouseUpHandler(this);
     }
 
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
@@ -240,8 +247,29 @@ public class VEmbedded extends HTML implements Paintable, ClickHandler {
         client.handleTooltipEvent(event, this);
     }
 
+    private void fireClick(MouseEventDetails mouseDetails) {
+        client.updateVariable(client.getPid(this), CLICK_EVENT_IDENTIFIER,
+                mouseDetails.serialize(), true);
+    }
+
     public void onClick(ClickEvent event) {
-        client.getEventHandler(this).fireEvent("click", "left");
+        if (client.hasEventListeners(this, CLICK_EVENT_IDENTIFIER)) {
+            MouseEventDetails mouseDetails = new MouseEventDetails(event
+                    .getNativeEvent());
+            fireClick(mouseDetails);
+        }
     }
 
+    public void onMouseUp(MouseUpEvent event) {
+        if (client.hasEventListeners(this, CLICK_EVENT_IDENTIFIER)) {
+
+            MouseEventDetails mouseDetails = new MouseEventDetails(event
+                    .getNativeEvent());
+            if (mouseDetails.getButton() != MouseEventDetails.BUTTON_LEFT) {
+                // "Click" with right or middle button
+                fireClick(mouseDetails);
+
+            }
+        }
+    }
 }
index 366476bef0e059a18e93187b1430178aa8fd00b7..29f4c77769de1f2e61aea246ad109838e6aa5aa7 100644 (file)
@@ -23,6 +23,7 @@ import com.google.gwt.user.client.ui.SimplePanel;
 import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.Container;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.Paintable;
 import com.vaadin.terminal.gwt.client.RenderSpace;
 import com.vaadin.terminal.gwt.client.StyleConstants;
@@ -36,6 +37,8 @@ public class VGridLayout extends SimplePanel implements Paintable, Container,
 
     public static final String CLASSNAME = "v-gridlayout";
 
+    public static final String CLICK_EVENT_IDENTIFIER = "click";
+
     private DivElement margin = Document.get().createDivElement();
 
     private final AbsolutePanel canvas = new AbsolutePanel();
@@ -1029,25 +1032,34 @@ public class VGridLayout extends SimplePanel implements Paintable, Container,
     }
 
     public void onClick(ClickEvent event) {
-        String col = null;
-        String row = null;
+        // This is only called if there are click listeners registered on server
+        // side
+
+        Paintable childComponent = getChildComponent((Element) event
+                .getNativeEvent().getEventTarget().cast());
+        final MouseEventDetails details = new MouseEventDetails(event
+                .getNativeEvent());
+
+        Object[] parameters = new Object[] { details, childComponent };
+        client.updateVariable(client.getPid(this), CLICK_EVENT_IDENTIFIER,
+                parameters, true);
+
+    }
 
-        Element clickTarget = (Element) event.getNativeEvent().getEventTarget()
-                .cast();
+    private Paintable getChildComponent(Element element) {
         Element rootElement = getElement();
-        while (clickTarget != null && clickTarget != rootElement) {
-            Paintable paintable = client.getPaintable(clickTarget);
+        while (element != null && element != rootElement) {
+            Paintable paintable = client.getPaintable(element);
             if (paintable != null) {
                 Cell cell = paintableToCell.get(paintable);
-                row = String.valueOf(cell.row);
-                col = String.valueOf(cell.col);
-                break;
+                if (cell != null) {
+                    return paintable;
+                }
             }
-            clickTarget = DOM.getParent(clickTarget);
+            element = DOM.getParent(element);
         }
 
-        client.getEventHandler(this).fireEvent("click", "left", row, col);
-
+        return null;
     }
 
 }
index 10d7fe4d02844b48e5501d920a6dda96421fca2a..9c07d61196d2ba87a15b4d6eb5caca9f9486f309 100644 (file)
@@ -5,15 +5,14 @@ import java.util.Iterator;
 import java.util.Set;\r
 \r
 import com.google.gwt.core.client.JsArrayString;\r
-import com.google.gwt.dom.client.Node;\r
-import com.google.gwt.dom.client.NodeList;\r
 import com.google.gwt.event.dom.client.ClickEvent;\r
 import com.google.gwt.event.dom.client.ClickHandler;\r
-import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.event.shared.HandlerRegistration;\r
 import com.google.gwt.user.client.Element;\r
 import com.google.gwt.user.client.ui.Widget;\r
 import com.vaadin.terminal.gwt.client.ApplicationConnection;\r
 import com.vaadin.terminal.gwt.client.BrowserInfo;\r
+import com.vaadin.terminal.gwt.client.MouseEventDetails;\r
 import com.vaadin.terminal.gwt.client.Paintable;\r
 import com.vaadin.terminal.gwt.client.RenderSpace;\r
 import com.vaadin.terminal.gwt.client.UIDL;\r
@@ -28,6 +27,8 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler {
 \r
     public static final String CLASSNAME = "v-orderedlayout";\r
 \r
+    public static final String CLICK_EVENT_IDENTIFIER = "click";\r
+\r
     private int orientation;\r
 \r
     // Can be removed once OrderedLayout is removed\r
@@ -55,7 +56,6 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler {
     public VOrderedLayout() {\r
         this(CLASSNAME, ORIENTATION_VERTICAL);\r
         allowOrientationUpdate = true;\r
-        addDomHandler(this, ClickEvent.getType());\r
     }\r
 \r
     protected VOrderedLayout(String className, int orientation) {\r
@@ -67,8 +67,6 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler {
         STYLENAME_MARGIN_RIGHT = className + "-margin-right";\r
         STYLENAME_MARGIN_BOTTOM = className + "-margin-bottom";\r
         STYLENAME_MARGIN_LEFT = className + "-margin-left";\r
-\r
-        addDomHandler(this, ClickEvent.getType());\r
     }\r
 \r
     @Override\r
@@ -83,6 +81,8 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler {
             return;\r
         }\r
 \r
+        handleHandlerRegistration();\r
+\r
         if (allowOrientationUpdate) {\r
             handleOrientationUpdate(uidl);\r
         }\r
@@ -248,6 +248,26 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler {
         sizeHasChangedDuringRendering = false;\r
     }\r
 \r
+    private HandlerRegistration clickHandlerRegistration;\r
+\r
+    private void handleHandlerRegistration() {\r
+        // Handle registering/unregistering of click handler depending on if\r
+        // server side listeners have been added or removed.\r
+        if (client.hasEventListeners(this, CLICK_EVENT_IDENTIFIER)) {\r
+            if (clickHandlerRegistration == null) {\r
+                clickHandlerRegistration = addDomHandler(this, ClickEvent\r
+                        .getType());\r
+            }\r
+        } else {\r
+            if (clickHandlerRegistration != null) {\r
+                clickHandlerRegistration.removeHandler();\r
+                clickHandlerRegistration = null;\r
+\r
+            }\r
+        }\r
+\r
+    }\r
+\r
     private void layoutSizeMightHaveChanged() {\r
         Size oldSize = new Size(activeLayoutSize.getWidth(), activeLayoutSize\r
                 .getHeight());\r
@@ -924,50 +944,37 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler {
     }\r
 \r
     public void onClick(ClickEvent event) {\r
-        Integer childComponentId = getChildComponentId((Element) event\r
+        // This is only called if there are click listeners registered on server\r
+        // side\r
+\r
+        Paintable childComponent = getChildComponent((Element) event\r
                 .getNativeEvent().getEventTarget().cast());\r
-        String childComponentString = childComponentId.toString();\r
-        client.getEventHandler(this).fireEvent("click", "left",\r
-                childComponentString);\r
+        final MouseEventDetails details = new MouseEventDetails(event\r
+                .getNativeEvent());\r
 \r
+        Object[] parameters = new Object[] { details, childComponent };\r
+\r
+        client.updateVariable(client.getPid(this), CLICK_EVENT_IDENTIFIER,\r
+                parameters, true);\r
     }\r
 \r
     /**\r
-     * Returns the index of the child component which contains "element".\r
+     * Returns the child component which contains "element".\r
      * \r
      * @param element\r
      * @return\r
      */\r
-    private int getChildComponentId(Element element) {\r
+    private Paintable getChildComponent(Element element) {\r
         Element rootElement = getElement();\r
-        Element parent = DOM.getParent(element);\r
-        if (parent == null) {\r
-            return -1;\r
-        }\r
-        Element grandParent = DOM.getParent(parent);\r
-        if (grandParent == null) {\r
-            return -1;\r
-        }\r
-\r
-        while (grandParent != null && parent != rootElement) {\r
-            if (grandParent == rootElement) {\r
-                NodeList<Node> nodes = parent.getChildNodes();\r
-                int size = nodes.getLength();\r
-                for (int index = 0; index < size; index++) {\r
-                    if (nodes.getItem(index) == element) {\r
-                        return index;\r
-                    }\r
-                }\r
-\r
-                // This should not happen\r
-                return -1;\r
+        while (element != null && element != rootElement) {\r
+            Paintable paintable = client.getPaintable(element);\r
+            if (paintable != null\r
+                    && widgetToComponentContainer.containsKey(paintable)) {\r
+                return paintable;\r
             }\r
-\r
-            element = parent;\r
-            parent = grandParent;\r
-            grandParent = DOM.getParent(grandParent);\r
         }\r
-        return -1;\r
+\r
+        return null;\r
     }\r
 \r
 }\r
index 608a7fd9ab7b23ecc4636a363b4ac19db3944957..d2db9ce572d9ac79969d82e305b61f68c9a5d0b5 100644 (file)
@@ -10,6 +10,7 @@ import com.google.gwt.dom.client.DivElement;
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.event.dom.client.ClickEvent;
 import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Element;
 import com.google.gwt.user.client.Event;
@@ -18,6 +19,7 @@ import com.google.gwt.user.client.ui.Widget;
 import com.vaadin.terminal.gwt.client.ApplicationConnection;
 import com.vaadin.terminal.gwt.client.BrowserInfo;
 import com.vaadin.terminal.gwt.client.Container;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.Paintable;
 import com.vaadin.terminal.gwt.client.RenderInformation;
 import com.vaadin.terminal.gwt.client.RenderSpace;
@@ -26,6 +28,7 @@ import com.vaadin.terminal.gwt.client.Util;
 
 public class VPanel extends SimplePanel implements Container, ClickHandler {
 
+    public static final String CLICK_EVENT_IDENTIFIER = "click";
     public static final String CLASSNAME = "v-panel";
 
     ApplicationConnection client;
@@ -94,8 +97,6 @@ public class VPanel extends SimplePanel implements Container, ClickHandler {
         contentNode.getStyle().setProperty("position", "relative");
         getElement().getStyle().setProperty("overflow", "hidden");
 
-        addDomHandler(this, ClickEvent.getType());
-
     }
 
     @Override
@@ -110,6 +111,8 @@ public class VPanel extends SimplePanel implements Container, ClickHandler {
     public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
         rendering = true;
         if (!uidl.hasAttribute("cached")) {
+            handleHandlerRegistration();
+
             // Handle caption displaying and style names, prior generics.
             // Affects size
             // calculations
@@ -207,6 +210,26 @@ public class VPanel extends SimplePanel implements Container, ClickHandler {
 
     }
 
+    private HandlerRegistration clickHandlerRegistration;
+
+    private void handleHandlerRegistration() {
+        // Handle registering/unregistering of click handler depending on if
+        // server side listeners have been added or removed.
+        if (client.hasEventListeners(this, CLICK_EVENT_IDENTIFIER)) {
+            if (clickHandlerRegistration == null) {
+                clickHandlerRegistration = addDomHandler(this, ClickEvent
+                        .getType());
+            }
+        } else {
+            if (clickHandlerRegistration != null) {
+                clickHandlerRegistration.removeHandler();
+                clickHandlerRegistration = null;
+
+            }
+        }
+
+    }
+
     @Override
     public void setStyleName(String style) {
         if (!style.equals(previousStyleName)) {
@@ -524,6 +547,12 @@ public class VPanel extends SimplePanel implements Container, ClickHandler {
     }
 
     public void onClick(ClickEvent event) {
-        client.getEventHandler(this).fireEvent("click", "left");
+        // This is only called if there are click listeners registered on server
+        // side
+        MouseEventDetails details = new MouseEventDetails(event
+                .getNativeEvent());
+        client.updateVariable(client.getPid(this), CLICK_EVENT_IDENTIFIER,
+                details.serialize(), true);
     }
+
 }
index 860891f99fcabbef447757e386ef0fc7ddfd3003..5e5d0bf687d462b4b37c658669acbc37d42c7879 100644 (file)
@@ -54,6 +54,9 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
 
     private static final String CLASSNAME_PROMPT = "prompt";
     private static final String ATTR_INPUTPROMPT = "prompt";
+    public static final String FOCUS_EVENT_IDENTIFIER = "focus";
+    public static final String BLUR_EVENT_IDENTIFIER = "blur";
+
     private String inputPrompt = null;
     private boolean prompting = false;
 
@@ -195,7 +198,10 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
             }
         }
         focusedTextField = this;
-        client.getEventHandler(this).fireEvent("focus", (String[]) null);
+        if (client.hasEventListeners(this, FOCUS_EVENT_IDENTIFIER)) {
+            client.updateVariable(client.getPid(this), FOCUS_EVENT_IDENTIFIER,
+                    "", true);
+        }
     }
 
     public void onBlur(BlurEvent event) {
@@ -208,7 +214,10 @@ public class VTextField extends TextBoxBase implements Paintable, Field,
             addStyleDependentName(CLASSNAME_PROMPT);
         }
         onChange(null);
-        client.getEventHandler(this).fireEvent("blur", (String[]) null);
+        if (client.hasEventListeners(this, BLUR_EVENT_IDENTIFIER)) {
+            client.updateVariable(client.getPid(this), BLUR_EVENT_IDENTIFIER,
+                    "", true);
+        }
     }
 
     private void setPrompting(boolean prompting) {
index 8e382622cad2258886482ce60eff23d980b517a4..b2f0a5be7693abf441d8c9c9efac0d378e9ac87a 100644 (file)
@@ -10,8 +10,11 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Map;
 
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout;
 
 /**
@@ -23,6 +26,8 @@ import com.vaadin.terminal.gwt.client.ui.VAbsoluteLayout;
 @ClientWidget(VAbsoluteLayout.class)
 public class AbsoluteLayout extends AbstractLayout {
 
+    private static final String CLICK_EVENT = VAbsoluteLayout.CLICK_EVENT_IDENTIFIER;
+
     private Collection<Component> components = new LinkedHashSet<Component>();
     private Map<Component, ComponentPosition> componentToCoordinates = new HashMap<Component, ComponentPosition>();
 
@@ -353,4 +358,30 @@ public class AbsoluteLayout extends AbstractLayout {
 
     }
 
+    @Override
+    public void changeVariables(Object source, Map variables) {
+        super.changeVariables(source, variables);
+        if (variables.containsKey(CLICK_EVENT)) {
+            fireClick((Object[]) variables.get(CLICK_EVENT));
+        }
+
+    }
+
+    private void fireClick(Object[] parameters) {
+        MouseEventDetails mouseDetails = MouseEventDetails
+                .deserialize((String) parameters[0]);
+        Component childComponent = (Component) parameters[1];
+
+        fireEvent(new LayoutClickEvent(this, mouseDetails, childComponent));
+    }
+
+    public void addListener(LayoutClickListener listener) {
+        addListener(CLICK_EVENT, LayoutClickEvent.class, listener,
+                LayoutClickListener.clickMethod);
+    }
+
+    public void removeListener(LayoutClickListener listener) {
+        removeListener(CLICK_EVENT, LayoutClickEvent.class, listener);
+    }
+
 }
index ee07a560e4cba54611e0641e86bc3e4530bd9da0..c72701b8ac63e09d2a8e4d7527a451c5cc903795 100644 (file)
@@ -8,15 +8,16 @@ import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import com.vaadin.Application;
-import com.vaadin.event.ClientEventList;
 import com.vaadin.event.EventRouter;
 import com.vaadin.event.MethodEventSource;
 import com.vaadin.terminal.ErrorMessage;
@@ -24,7 +25,7 @@ import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
 import com.vaadin.terminal.Terminal;
-import com.vaadin.terminal.gwt.client.ComponentEventHandler;
+import com.vaadin.terminal.gwt.client.EventListenerRegister;
 import com.vaadin.terminal.gwt.server.ComponentSizeValidator;
 import com.vaadin.tools.ReflectTools;
 
@@ -96,10 +97,9 @@ public abstract class AbstractComponent implements Component, MethodEventSource
     private EventRouter eventRouter = null;
 
     /**
-     * The ClientEventList used for collecting client events which should be
-     * transmitted from the client to the server
+     * A set of event identifiers with registered listeners.
      */
-    private ClientEventList clientEvents = null;
+    private Set<String> eventIdentifiers = null;
 
     /**
      * The internal error message of the component.
@@ -688,20 +688,12 @@ public abstract class AbstractComponent implements Component, MethodEventSource
                     target.addAttribute("description", getDescription());
                 }
 
-                String[] trigger = new String[] {};
-                String[] events = new String[] {};
-                if (clientEvents != null) {
-                    events = clientEvents.getEvents();
+                if (eventIdentifiers != null) {
+                    target
+                            .addAttribute(
+                                    EventListenerRegister.REGISTERED_EVENT_LISTENERS_ATTRIBUTE,
+                                    eventIdentifiers.toArray());
                 }
-                if (events.length != 0) {
-                    target.addVariable(this,
-                            ComponentEventHandler.HANDLER_TRIGGER_VARIABLE,
-                            trigger);
-                    target.addAttribute(
-                            ComponentEventHandler.HANDLER_LISTEN_ATTRIBUTE,
-                            events);
-                }
-                // end of event variables
 
                 paintContent(target);
 
@@ -837,66 +829,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource
         }
     }
 
-    /**
-     * this method is executed when a event arrives from the event-api.<br>
-     * this should be overridden by components which intend to use the event-api
-     * mechanism for registering Events.
-     * 
-     * @param eventIdentifier
-     * @param parameters
-     */
-    protected void handleEvent(String eventIdentifier, String[] parameters) {
-        // implemented by subclasses
-    }
-
-    /**
-     * listens to the specified event type.<br>
-     * on changes of the registered event by the client-side component, the
-     * method handleEvent(String event, String[] parameters) will be invoked (as
-     * long as either a listener is registered at the component for the given
-     * event type or the forceTransmission flag has been set by the client-side
-     * component). <br>
-     * <br>
-     * <b>for every listener attached to this component this method has to be
-     * called once. the client-event list holds a counter on how-many listeners
-     * are listening for an event.</b><br>
-     * <br>
-     * this method should be executed by components which intend to use the
-     * event-api mechanism for listening on events.
-     * 
-     * @param eventIdentifier
-     * @since 6.2
-     */
-    private void listenEvent(String eventIdentifier) {
-        if (clientEvents == null) {
-            clientEvents = new ClientEventList();
-        }
-        final boolean repaint = clientEvents.listenEvent(eventIdentifier);
-        if (repaint)
-            requestRepaint();
-    }
-
-    /**
-     * stops listening to the specified event type. <br>
-     * <br>
-     * <b>for every listener detached from this component this method has to be
-     * called once. the client-event list holds a counter on how-many listeners
-     * are listening for an event.</b><br>
-     * <br>
-     * this method should be executed by components which intend to use the
-     * event-api mechanism for listening on events.
-     * 
-     * @param eventIdentifier
-     * @since 6.2
-     */
-    private void unlistenEvent(String eventIdentifier) {
-        if (clientEvents != null) {
-            final boolean repaint = clientEvents.unlistenEvent(eventIdentifier);
-            if (repaint)
-                requestRepaint();
-        }
-    }
-
     /* Component variable changes */
 
     /*
@@ -906,25 +838,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      */
     public void changeVariables(Object source, Map variables) {
 
-        // handle events when triggered
-        if (variables
-                .containsKey(ComponentEventHandler.HANDLER_TRIGGER_VARIABLE)) {
-            String[] firedEvent = (String[]) variables
-                    .get(ComponentEventHandler.HANDLER_TRIGGER_VARIABLE);
-
-            // detect vaadin events
-            String[] params = new String[firedEvent.length - 1];
-
-            for (int i = 0; i < params.length; i++) {
-                params[i] = firedEvent[i + 1];
-            }
-
-            String event = firedEvent[0];
-
-            handleEvent(event, params);
-
-        }
-
     }
 
     /* General event framework */
@@ -956,20 +869,28 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * @param eventType
      *            the type of the listened event. Events of this type or its
      *            subclasses activate the listener.
-     * @param object
+     * @param target
      *            the object instance who owns the activation method.
      * @param method
      *            the activation method.
      * 
      * @since 6.2
      */
-    protected void addEventListener(String eventIdentifier, Class<?> eventType,
-            Object object, Method method) {
+    protected void addListener(String eventIdentifier, Class<?> eventType,
+            Object target, Method method) {
         if (eventRouter == null) {
             eventRouter = new EventRouter();
         }
-        eventRouter.addListener(eventType, object, method);
-        listenEvent(eventIdentifier);
+        if (eventIdentifiers == null) {
+            eventIdentifiers = new HashSet<String>();
+        }
+        boolean needRepaint = !eventRouter.hasListeners(eventType);
+        eventRouter.addListener(eventType, target, method);
+
+        if (needRepaint) {
+            eventIdentifiers.add(eventIdentifier);
+            requestRepaint();
+        }
     }
 
     /**
@@ -1000,49 +921,15 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * 
      * @since 6.2
      */
-    protected void removeEventListener(String eventIdentifier,
-            Class<?> eventType, Object target) {
+    protected void removeListener(String eventIdentifier, Class<?> eventType,
+            Object target) {
         if (eventRouter != null) {
             eventRouter.removeListener(eventType, target);
+            if (!eventRouter.hasListeners(eventType)) {
+                eventIdentifiers.remove(eventIdentifier);
+                requestRepaint();
+            }
         }
-        unlistenEvent(eventIdentifier);
-    }
-
-    /**
-     * Removes one registered listener method. The given method owned by the
-     * given object will no longer be called when the specified events are
-     * generated by this component.
-     * 
-     * <p>
-     * This method additionally informs the event-api to stop routing events
-     * with the given eventIdentifier to the components handleEvent function
-     * call.
-     * </p>
-     * 
-     * <p>
-     * For more information on the inheritable event mechanism see the
-     * {@link com.vaadin.event com.vaadin.event package documentation}.
-     * </p>
-     * 
-     * @param eventIdentifier
-     *            the identifier of the event to stop listening for
-     * @param eventType
-     *            the exact event type the <code>object</code> listens to.
-     * @param target
-     *            target object that has registered to listen to events of type
-     *            <code>eventType</code> with one or more methods.
-     * @param method
-     *            the method owned by <code>target</code> that's registered to
-     *            listen to events of type <code>eventType</code>.
-     * 
-     * @since 6.2
-     */
-    protected void removeEventListener(String eventIdentifier, Class eventType,
-            Object target, Method method) {
-        if (eventRouter != null) {
-            eventRouter.removeListener(eventType, target, method);
-        }
-        unlistenEvent(eventIdentifier);
     }
 
     /**
@@ -1061,16 +948,16 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * @param eventType
      *            the type of the listened event. Events of this type or its
      *            subclasses activate the listener.
-     * @param object
+     * @param target
      *            the object instance who owns the activation method.
      * @param method
      *            the activation method.
      */
-    public void addListener(Class eventType, Object object, Method method) {
+    public void addListener(Class eventType, Object target, Method method) {
         if (eventRouter == null) {
             eventRouter = new EventRouter();
         }
-        eventRouter.addListener(eventType, object, method);
+        eventRouter.addListener(eventType, target, method);
     }
 
     /**
@@ -1102,16 +989,16 @@ public abstract class AbstractComponent implements Component, MethodEventSource
      * @param eventType
      *            the type of the listened event. Events of this type or its
      *            subclasses activate the listener.
-     * @param object
+     * @param target
      *            the object instance who owns the activation method.
      * @param methodName
      *            the name of the activation method.
      */
-    public void addListener(Class eventType, Object object, String methodName) {
+    public void addListener(Class eventType, Object target, String methodName) {
         if (eventRouter == null) {
             eventRouter = new EventRouter();
         }
-        eventRouter.addListener(eventType, object, methodName);
+        eventRouter.addListener(eventType, target, methodName);
     }
 
     /**
index ed2f70d4f050e81f887de040333e03d9c6f2aa8d..b3cfebc21292864598ef88c14e702a5aab9a7e79 100644 (file)
@@ -4,23 +4,25 @@
 
 package com.vaadin.ui;
 
-import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 
-import com.vaadin.event.ComponentEventListener;
-import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Sizeable;
-import com.vaadin.tools.ReflectTools;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
+import com.vaadin.terminal.gwt.client.ui.VOrderedLayout;
 
 @SuppressWarnings("serial")
 public abstract class AbstractOrderedLayout extends AbstractLayout implements
         Layout.AlignmentHandler, Layout.SpacingHandler {
 
+    private static final String CLICK_EVENT = VOrderedLayout.CLICK_EVENT_IDENTIFIER;
+
     private static final Alignment ALIGNMENT_DEFAULT = Alignment.TOP_LEFT;
 
     /**
@@ -311,67 +313,30 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
         AlignmentUtils.setComponentAlignment(this, component, alignment);
     }
 
-    public interface LayoutClickListener extends ComponentEventListener {
-
-        public static final Method clickMethod = ReflectTools.findMethod(
-                LayoutClickListener.class, "layoutClick",
-                LayoutClickEvent.class);
+    @Override
+    public void changeVariables(Object source, Map variables) {
+        super.changeVariables(source, variables);
+        if (variables.containsKey(CLICK_EVENT)) {
+            fireClick((Object[]) variables.get(CLICK_EVENT));
+        }
 
-        /**
-         * Layout has been clicked
-         * 
-         * @param event
-         *            Component click event.
-         */
-        public void layoutClick(LayoutClickEvent event);
     }
 
-    /**
-     * An event fired when the layout has been clicked. The event contains
-     * information about the target layout (component) and the child component
-     * that was clicked. If no child component was found it is set to null.
-     * 
-     */
-    public static class LayoutClickEvent extends ClickEvent {
-
-        private Component childComponent;
-
-        public LayoutClickEvent(Component source, String mouseButton,
-                Component childComponent) {
-            super(source, mouseButton);
-            this.childComponent = childComponent;
-        }
-
-        public Component getChildComponent() {
-            return childComponent;
-        }
+    private void fireClick(Object[] parameters) {
+        MouseEventDetails mouseDetails = MouseEventDetails
+                .deserialize((String) parameters[0]);
+        Component childComponent = (Component) parameters[1];
 
+        fireEvent(new LayoutClickEvent(this, mouseDetails, childComponent));
     }
 
     public void addListener(LayoutClickListener listener) {
-        addEventListener("click", LayoutClickEvent.class, listener,
+        addListener(CLICK_EVENT, LayoutClickEvent.class, listener,
                 LayoutClickListener.clickMethod);
     }
 
     public void removeListener(LayoutClickListener listener) {
-        removeEventListener("click", LayoutClickEvent.class, listener,
-                LayoutClickListener.clickMethod);
+        removeListener(CLICK_EVENT, LayoutClickEvent.class, listener);
     }
 
-    @Override
-    protected void handleEvent(String event, String[] parameters) {
-        if (event.equals("click")) {
-            String button = parameters[0];
-            String childComponentId = parameters[1];
-            Component childComponent = null;
-            try {
-                int id = Integer.parseInt(childComponentId);
-                childComponent = components.get(id);
-            } catch (Exception e) {
-                // TODO: handle exception
-            }
-
-            fireEvent(new LayoutClickEvent(this, button, childComponent));
-        }
-    }
 }
index be60b744aa6bba0854ab49a68682009be9e07bd0..c670de86a2c9bc5cf306e2d588a6f9d1f22ed4f3 100644 (file)
@@ -6,12 +6,14 @@ package com.vaadin.ui;
 
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.Map;
 
 import com.vaadin.event.MouseEvents.ClickEvent;
 import com.vaadin.event.MouseEvents.ClickListener;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Resource;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.VEmbedded;
 
 /**
@@ -26,6 +28,8 @@ import com.vaadin.terminal.gwt.client.ui.VEmbedded;
 @ClientWidget(VEmbedded.class)
 public class Embedded extends AbstractComponent {
 
+    private static final String CLICK_EVENT = VEmbedded.CLICK_EVENT_IDENTIFIER;
+
     /**
      * General object type.
      */
@@ -417,19 +421,28 @@ public class Embedded extends AbstractComponent {
     }
 
     public void addListener(ClickListener listener) {
-        addEventListener("click", ClickEvent.class, listener,
+        addListener(CLICK_EVENT, ClickEvent.class, listener,
                 ClickListener.clickMethod);
     }
 
     public void removeListener(ClickListener listener) {
-        removeEventListener("click", ClickEvent.class, listener,
-                ClickListener.clickMethod);
+        removeListener(CLICK_EVENT, ClickEvent.class, listener);
     }
 
     @Override
-    protected void handleEvent(String event, String[] parameters) {
-        if (event.equals("click")) {
-            fireEvent(new ClickEvent(this, parameters[0]));
+    public void changeVariables(Object source, Map variables) {
+        super.changeVariables(source, variables);
+        if (variables.containsKey(CLICK_EVENT)) {
+            fireClick(variables.get(CLICK_EVENT));
         }
+
     }
+
+    private void fireClick(Object parameters) {
+        MouseEventDetails mouseDetails = MouseEventDetails
+                .deserialize((String) parameters);
+
+        fireEvent(new ClickEvent(this, mouseDetails));
+    }
+
 }
index 510a8051d735571064b3dec922ffff05e5e5a323..530b5fc7dd4be98cb0afd4919bd4fbfad2036dbf 100644 (file)
@@ -12,11 +12,12 @@ import java.util.LinkedList;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import com.vaadin.event.LayoutEvents.LayoutClickEvent;
+import com.vaadin.event.LayoutEvents.LayoutClickListener;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.VGridLayout;
-import com.vaadin.ui.AbstractOrderedLayout.LayoutClickEvent;
-import com.vaadin.ui.AbstractOrderedLayout.LayoutClickListener;
 
 /**
  * <p>
@@ -43,6 +44,8 @@ import com.vaadin.ui.AbstractOrderedLayout.LayoutClickListener;
 public class GridLayout extends AbstractLayout implements
         Layout.AlignmentHandler, Layout.SpacingHandler {
 
+    private static final String CLICK_EVENT = VGridLayout.CLICK_EVENT_IDENTIFIER;
+
     /**
      * Initial grid columns.
      */
@@ -1301,34 +1304,30 @@ public class GridLayout extends AbstractLayout implements
         AlignmentUtils.setComponentAlignment(this, component, alignment);
     }
 
-    public void addListener(LayoutClickListener listener) {
-        addEventListener("click", LayoutClickEvent.class, listener,
-                LayoutClickListener.clickMethod);
-    }
+    @Override
+    public void changeVariables(Object source, Map variables) {
+        super.changeVariables(source, variables);
+        if (variables.containsKey(CLICK_EVENT)) {
+            fireClick((Object[]) variables.get(CLICK_EVENT));
+        }
 
-    public void removeListener(LayoutClickListener listener) {
-        removeEventListener("click", LayoutClickEvent.class, listener,
-                LayoutClickListener.clickMethod);
     }
 
-    @Override
-    protected void handleEvent(String event, String[] parameters) {
-        if (event.equals("click")) {
-            String button = parameters[0];
-            String childComponentRow = parameters[1];
-            String childComponentCol = parameters[2];
+    private void fireClick(Object[] parameters) {
+        MouseEventDetails mouseDetails = MouseEventDetails
+                .deserialize((String) parameters[0]);
+        Component childComponent = (Component) parameters[1];
 
-            Component childComponent = null;
-            try {
-                childComponent = getComponent(Integer
-                        .parseInt(childComponentCol), Integer
-                        .parseInt(childComponentRow));
-            } catch (Exception e) {
-                // TODO: handle exception
-            }
+        fireEvent(new LayoutClickEvent(this, mouseDetails, childComponent));
+    }
 
-            fireEvent(new LayoutClickEvent(this, button, childComponent));
-        }
+    public void addListener(LayoutClickListener listener) {
+        addListener(CLICK_EVENT, LayoutClickEvent.class, listener,
+                LayoutClickListener.clickMethod);
+    }
+
+    public void removeListener(LayoutClickListener listener) {
+        removeListener(CLICK_EVENT, LayoutClickEvent.class, listener);
     }
 
 }
index 2aaf697e85be10ccf0a54f0e20c385df36610c44..7148df9e046dc539ca98ccb1d9f56c7074a584db 100644 (file)
@@ -17,6 +17,7 @@ import com.vaadin.terminal.KeyMapper;
 import com.vaadin.terminal.PaintException;
 import com.vaadin.terminal.PaintTarget;
 import com.vaadin.terminal.Scrollable;
+import com.vaadin.terminal.gwt.client.MouseEventDetails;
 import com.vaadin.terminal.gwt.client.ui.VPanel;
 
 /**
@@ -33,6 +34,8 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
         ComponentContainer.ComponentAttachListener,
         ComponentContainer.ComponentDetachListener, Action.Container {
 
+    private static final String CLICK_EVENT = VPanel.CLICK_EVENT_IDENTIFIER;
+
     public static final String STYLE_LIGHT = "light";
 
     /**
@@ -327,6 +330,10 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
     public void changeVariables(Object source, Map variables) {
         super.changeVariables(source, variables);
 
+        if (variables.containsKey(CLICK_EVENT)) {
+            fireClick(variables.get(CLICK_EVENT));
+        }
+
         // Get new size
         final Integer newWidth = (Integer) variables.get("width");
         final Integer newHeight = (Integer) variables.get("height");
@@ -546,22 +553,25 @@ public class Panel extends AbstractComponentContainer implements Scrollable,
         }
     }
 
-    @Override
-    protected void handleEvent(String eventIdentifier, String[] parameters) {
-        if (eventIdentifier.equals("click")) {
-            fireEvent(new ClickEvent(this, parameters[0]));
-        }
-    }
-
     public void addListener(ClickListener listener) {
-        addEventListener("click", ClickEvent.class, listener,
+        addListener(CLICK_EVENT, ClickEvent.class, listener,
                 ClickListener.clickMethod);
     }
 
     public void removeListener(ClickListener listener) {
-        removeEventListener("click", ClickEvent.class, listener,
-                ClickListener.clickMethod);
+        removeListener(CLICK_EVENT, ClickEvent.class, listener);
+    }
 
+    /**
+     * Fire a click event to all click listeners.
+     * 
+     * @param object
+     *            The raw "value" of the variable change from the client side.
+     */
+    private void fireClick(Object object) {
+        MouseEventDetails mouseDetails = MouseEventDetails
+                .deserialize((String) object);
+        fireEvent(new ClickEvent(this, mouseDetails));
     }
 
 }
index 99e7cec3ded2bc2558b8b1d4360f6a837271689b..a79bb614b8e864ff0943155312c579db25eb9bbf 100644 (file)
@@ -1966,7 +1966,7 @@ public class Table extends AbstractSelect implements Action.Container,
                     propertyId = columnIdMap.get(colkey);
                 }
                 MouseEventDetails evt = MouseEventDetails
-                        .deSerialize((String) variables.get("clickEvent"));
+                        .deserialize((String) variables.get("clickEvent"));
                 Item item = getItem(itemId);
                 if (item != null) {
                     fireEvent(new ItemClickEvent(this, item, itemId,
index 94c97849c2eb9dd559dc5330e829d32383acea48..d54a4d00aabd3bb39247c4020cf56dfaf66aca93 100644 (file)
@@ -87,6 +87,9 @@ public class TextField extends AbstractField {
      */
     private int maxLength = -1;
 
+    private static final String BLUR_EVENT = VTextField.BLUR_EVENT_IDENTIFIER;
+    private static final String FOCUS_EVENT = VTextField.FOCUS_EVENT_IDENTIFIER;
+
     /* Constructors */
 
     /**
@@ -245,6 +248,13 @@ public class TextField extends AbstractField {
 
         super.changeVariables(source, variables);
 
+        if (variables.containsKey(FOCUS_EVENT)) {
+            fireFocus(variables.get(FOCUS_EVENT));
+        }
+        if (variables.containsKey(BLUR_EVENT)) {
+            fireBlur(variables.get(BLUR_EVENT));
+        }
+
         // Sets the text
         if (variables.containsKey("text") && !isReadOnly()) {
 
@@ -551,33 +561,50 @@ public class TextField extends AbstractField {
         requestRepaint();
     }
 
-    @Override
-    protected void handleEvent(String eventIdentifier, String[] parameters) {
-        if (eventIdentifier.equals("focus")) {
-            fireEvent(new FocusEvent(this));
-        } else if (eventIdentifier.equals("blur")) {
-            fireEvent(new BlurEvent(this));
-        }
+    private void fireFocus(Object object) {
+        fireEvent(new FocusEvent(this));
     }
 
+    private void fireBlur(Object object) {
+        fireEvent(new BlurEvent(this));
+    }
+
+    /**
+     * TODO
+     * 
+     * @param listener
+     */
     public void addListener(FocusListener listener) {
-        addEventListener("focus", FocusEvent.class, listener,
+        addListener(FOCUS_EVENT, FocusEvent.class, listener,
                 FocusListener.focusMethod);
     }
 
+    /**
+     * TODO
+     * 
+     * @param listener
+     */
     public void removeListener(FocusListener listener) {
-        removeEventListener("focus", FocusEvent.class, listener,
-                FocusListener.focusMethod);
+        removeListener(FOCUS_EVENT, FocusEvent.class, listener);
     }
 
+    /**
+     * TODO
+     * 
+     * @param listener
+     */
     public void addListener(BlurListener listener) {
-        addEventListener("blur", BlurEvent.class, listener,
+        addListener(BLUR_EVENT, BlurEvent.class, listener,
                 BlurListener.blurMethod);
     }
 
+    /**
+     * TODO
+     * 
+     * @param listener
+     */
     public void removeListener(BlurListener listener) {
-        removeEventListener("blur", BlurEvent.class, listener,
-                BlurListener.blurMethod);
+        removeListener(BLUR_EVENT, BlurEvent.class, listener);
     }
 
 }
index 082b9f46244faf38db5976e2202c2a8b6e469675..2182e3aab6d766bc4d8aa70eef41b278b6df6a36 100644 (file)
@@ -333,7 +333,7 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
 
             Object id = itemIdMapper.get(key);
             MouseEventDetails details = MouseEventDetails
-                    .deSerialize((String) variables.get("clickEvent"));
+                    .deserialize((String) variables.get("clickEvent"));
             Item item = getItem(id);
             if (item != null) {
                 fireEvent(new ItemClickEvent(this, item, id, null, details));