diff options
author | Artur Signell <artur.signell@itmill.com> | 2009-11-25 14:33:16 +0000 |
---|---|---|
committer | Artur Signell <artur.signell@itmill.com> | 2009-11-25 14:33:16 +0000 |
commit | a23903bf21edeafa91a2a731d55698bbf3b95770 (patch) | |
tree | 759a22e68dfc21358cb522118bde1159ad3c282b /src | |
parent | e5caa74cc45cdd63a0edae9989010699dfaea1be (diff) | |
download | vaadin-framework-a23903bf21edeafa91a2a731d55698bbf3b95770.tar.gz vaadin-framework-a23903bf21edeafa91a2a731d55698bbf3b95770.zip |
Work in progress
svn changeset:10026/svn branch:event-framework-3234
Diffstat (limited to 'src')
27 files changed, 621 insertions, 715 deletions
diff --git a/src/com/vaadin/event/ClientEventList.java b/src/com/vaadin/event/ClientEventList.java deleted file mode 100644 index e2008085c4..0000000000 --- a/src/com/vaadin/event/ClientEventList.java +++ /dev/null @@ -1,106 +0,0 @@ -/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.event;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- *
- * <code>ClientEventList</code> class used to store the registered events so a
- * list of the required client event identifiers (that the client-side should
- * listen for and send to the server-side) can be sent to the client-side via a
- * variable.
- *
- * @author davengo GmbH (Germany/Berlin, www.davengo.com)
- * @since 6.2
- *
- */
-public class ClientEventList {
-
- /**
- * the list containing the registered client events (as strings for
- * client-side transfer)
- *
- * @since 6.2
- */
- private Map<String, Integer> clientEvents = null;
-
- /**
- * initializes the list if necessary
- *
- * @since 6.2
- */
- private void checkList() {
- if (clientEvents == null) {
- clientEvents = new HashMap<String, Integer>();
- }
- }
-
- /**
- * listens for the event <br>
- * <br>
- * increments the internal counter for the event by one
- *
- * @param eventIdentifier
- * the identifier of the event to listen for
- *
- * @return true, if the event is newly added to the list<br>
- * false, if the list already contained the event (the internal
- * counter was incremented)
- *
- * @since 6.2
- */
- public boolean listenEvent(String eventIdentifier) {
- checkList();
- if (!clientEvents.keySet().contains(eventIdentifier)) {
- clientEvents.put(eventIdentifier, 1);
- return true;
- } else {
- clientEvents.put(eventIdentifier,
- clientEvents.get(eventIdentifier) + 1);
- return false;
- }
- }
-
- /**
- * unlistens for an event <br>
- * <br>
- * decrements the internal counter by one, if 0 is reached the event is
- * removed from the event-list
- *
- * @param eventIdentifier
- * the identifier of the event to stop listening for
- * @return true, if the event was removed from the list<br>
- * false, if the event is hold in list (the internal counter was
- * greater than zero)
- */
- public boolean unlistenEvent(String eventIdentifier) {
- checkList();
- if (clientEvents.keySet().contains(eventIdentifier)) {
- clientEvents.put(eventIdentifier,
- clientEvents.get(eventIdentifier) - 1);
- if (clientEvents.get(eventIdentifier) <= 0) {
- clientEvents.remove(eventIdentifier);
- return true;
- }
- return false;
- }
- return false;
- }
-
- /**
- * @return a string array containing all registered events
- *
- * @since 6.2
- */
- public String[] getEvents() {
- if (clientEvents == null) {
- return new String[] {};
- }
- return clientEvents.keySet().toArray(new String[] {});
- }
-
-}
diff --git a/src/com/vaadin/event/EventRouter.java b/src/com/vaadin/event/EventRouter.java index ca98c5e799..b12a280262 100644 --- a/src/com/vaadin/event/EventRouter.java +++ b/src/com/vaadin/event/EventRouter.java @@ -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; + } } diff --git a/src/com/vaadin/event/FieldEvents.java b/src/com/vaadin/event/FieldEvents.java index 3becb58aef..fc9f225b8f 100644 --- a/src/com/vaadin/event/FieldEvents.java +++ b/src/com/vaadin/event/FieldEvents.java @@ -83,41 +83,4 @@ public interface FieldEvents { public void blur(BlurEvent event);
}
- /**
- * <code>ValueChangeEvent</code> class for holding additional event
- * information. Fired when the value of a <code>Field</code> changes.
- *
- * @since 6.2
- */
- public class ValueChangeEvent extends Component.Event {
-
- private static final long serialVersionUID = -7644184999481404162L;
-
- public ValueChangeEvent(Component source) {
- super(source);
- }
- }
-
- /**
- * <code>ValueChangeListener</code> interface for listening for
- * <code>ValueChangeEvent</code> fired by a <code>Field</code>.
- *
- * @see ValueChangeEvent
- * @since 6.2
- */
- public interface ValueChangeListener extends ComponentEventListener {
-
- public static final Method valueChangeMethod = ReflectTools.findMethod(
- ValueChangeListener.class, "valueChange",
- ValueChangeEvent.class);
-
- /**
- * Component value was changed
- *
- * @param event
- * Component change event.
- */
- public void valueChange(ValueChangeEvent event);
- }
-
}
diff --git a/src/com/vaadin/event/ItemClickEvent.java b/src/com/vaadin/event/ItemClickEvent.java index b69e8e4c92..4fe87d927e 100644 --- a/src/com/vaadin/event/ItemClickEvent.java +++ b/src/com/vaadin/event/ItemClickEvent.java @@ -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 index 0000000000..025e9bb40e --- /dev/null +++ b/src/com/vaadin/event/LayoutEvents.java @@ -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 diff --git a/src/com/vaadin/event/ListenerMethod.java b/src/com/vaadin/event/ListenerMethod.java index 3efd4c70c7..b294dbf86d 100644 --- a/src/com/vaadin/event/ListenerMethod.java +++ b/src/com/vaadin/event/ListenerMethod.java @@ -638,4 +638,8 @@ public class ListenerMethod implements EventListener, Serializable { } } + + public boolean isType(Class<?> eventType) { + return this.eventType == eventType; + } } diff --git a/src/com/vaadin/event/MouseEvents.java b/src/com/vaadin/event/MouseEvents.java index bf417c1ebf..09fcc85b59 100644 --- a/src/com/vaadin/event/MouseEvents.java +++ b/src/com/vaadin/event/MouseEvents.java @@ -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(); } } diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 362e3eb8b1..9ee2b8842f 100755 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -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); } } diff --git a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java index 8f39733ef1..2d7f28dd4b 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentDetail.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentDetail.java @@ -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 index 2df8f9bf11..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ComponentEventHandler.java +++ /dev/null @@ -1,149 +0,0 @@ -/*
-@ITMillApache2LicenseForJavaFiles@
- */
-
-package com.vaadin.terminal.gwt.client;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * class for event handlers used by ComponentEventHandler
- *
- * @author davengo GmbH (Germany/Berlin, www.davengo.com)
- * @since 6.2
- *
- */
-public class ComponentEventHandler {
-
- public static final String HANDLER_LISTEN_ATTRIBUTE = "listenEvents";
- public static final String HANDLER_TRIGGER_VARIABLE = "fireEvent";
-
- private List<String> eventRegistrations;
- private ComponentDetail detail;
- private ApplicationConnection client;
-
- /**
- * creates a new <code>ComponentEventHandler</code> instance for the given
- * <code>ComponentDetail</code> and <code>ApplicationConntection</code>
- * instance.
- *
- * @param detail
- * the attached ComponentDetail
- * @param client
- * the <code>ApplicationConnection</code> for sending events
- *
- * @see ApplicationConnection
- * @see ComponentDetail
- * @since 6.2
- */
- public ComponentEventHandler(ComponentDetail detail,
- ApplicationConnection client) {
- this.detail = detail;
- this.client = client;
- this.eventRegistrations = null;
- }
-
- /**
- * Fires a event which is transmitted to the server and passed on the the
- * components handleEvent method provided listeners have been registered on
- * the server side.
- *
- * @param eventIdentifier
- * the unique identifier for the event
- * @param parameters
- * the parameters for the event (can be null)
- * @since 6.2
- */
- public void fireEvent(String eventIdentifier, String... parameters) {
- fireEvent(eventIdentifier, false, parameters);
- }
-
- /**
- * Fires a component event which is transmitted to the server and passed on
- * the the components handleEvent method. The event is sent to the server
- * even though there are no explicit listeners registered on the server
- * side.
- *
- * @param eventIdentifier
- * the unique identifier for the event
- * @param parameters
- * the parameters for the event (can be null)
- * @since 6.2
- */
- public void fireComponentEvent(String eventIdentifier, String... parameters) {
- fireEvent(eventIdentifier, true, parameters);
- }
-
- /**
- * Transmit the event to the Server (Fires a event which is transmitted to
- * the server and passed on the the components handleEvent method)
- *
- * @param eventIdentifier
- * the unique identifier for the event
- * @param forceTransmission
- * enforce the transmission to the server
- * @param parameters
- * the parameters for the event (can be null)
- * @since 6.2
- */
- private void fireEvent(String eventIdentifier, boolean forceTransmission,
- String... parameters) {
-
- String[] event;
-
- // filter events which are not listened on the server-side right here
- boolean transmit = forceTransmission
- || ((!(eventRegistrations == null)) && eventRegistrations
- .contains(eventIdentifier));
-
- if (transmit) {
- if (parameters != null) {
- event = new String[parameters.length + 1];
- event[0] = eventIdentifier;
- for (int i = 0; i < parameters.length; i++) {
- event[i + 1] = parameters[i];
- }
- } else {
- event = new String[] { eventIdentifier };
- }
-
- // transmit the event to the server-side
- client.updateVariable(detail.getPid(), HANDLER_TRIGGER_VARIABLE,
- event, true);
- }
- }
-
- /**
- * Registers the Events listened on the server-side from the UIDL
- *
- * @param componentUIDL
- * @since 6.2
- */
- void registerEventsFromUIDL(UIDL componentUIDL) {
-
- // read out the request event handlers
- if (componentUIDL.hasAttribute(HANDLER_LISTEN_ATTRIBUTE)) {
- String[] requestedEvents = componentUIDL
- .getStringArrayAttribute(HANDLER_LISTEN_ATTRIBUTE);
-
- // create the eventRegistrations list if necessary
- if ((requestedEvents.length > 0) && (eventRegistrations == null)) {
- eventRegistrations = new ArrayList<String>();
- }
-
- // parse the requested event handlers
- for (String reqEvent : requestedEvents) {
-
- if (!eventRegistrations.contains(reqEvent)) {
- eventRegistrations.add(reqEvent);
- }
-
- }
-
- }
-
- }
-
-}
diff --git a/src/com/vaadin/terminal/gwt/client/EventListenerRegister.java b/src/com/vaadin/terminal/gwt/client/EventListenerRegister.java new file mode 100644 index 0000000000..63710c3db3 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/EventListenerRegister.java @@ -0,0 +1,70 @@ +/*
+@ITMillApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.terminal.gwt.client;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * EventListenerRegister is used internally for keeping track of which component
+ * events have registered listeners on the server-side.
+ *
+ * @author davengo GmbH (Germany/Berlin, www.davengo.com), IT Mill
+ * @since 6.2
+ *
+ */
+public class EventListenerRegister {
+
+ public static final String REGISTERED_EVENT_LISTENERS_ATTRIBUTE = "eventListeners";
+
+ private List<String> eventRegistrations;
+
+ EventListenerRegister() {
+ }
+
+ /**
+ * Checks if there is a registered server side listener for the event.
+ *
+ * @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.
+ */
+ boolean hasEventListeners(String eventIdentifier) {
+ return ((!(eventRegistrations == null)) && eventRegistrations
+ .contains(eventIdentifier));
+ }
+
+ /**
+ * Stores the event listeners registered on server-side and passed along in
+ * the UIDL.
+ *
+ * @param componentUIDL
+ * The UIDL for the component
+ * @since 6.2
+ */
+ void registerEventListenersFromUIDL(UIDL componentUIDL) {
+
+ // read out the request event handlers
+ if (componentUIDL.hasAttribute(REGISTERED_EVENT_LISTENERS_ATTRIBUTE)) {
+ String[] registeredListeners = componentUIDL
+ .getStringArrayAttribute(REGISTERED_EVENT_LISTENERS_ATTRIBUTE);
+
+ if (registeredListeners == null || registeredListeners.length == 0) {
+ eventRegistrations = null;
+ } else {
+ eventRegistrations = new ArrayList<String>(
+ registeredListeners.length);
+ for (String listener : registeredListeners) {
+ eventRegistrations.add(listener);
+ }
+ }
+
+ }
+
+ }
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/MouseEventDetails.java b/src/com/vaadin/terminal/gwt/client/MouseEventDetails.java index 175dfd8ce2..abe332e6df 100644 --- a/src/com/vaadin/terminal/gwt/client/MouseEventDetails.java +++ b/src/com/vaadin/terminal/gwt/client/MouseEventDetails.java @@ -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; } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java index bd778c8d5c..ff26e4b005 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VAbsoluteLayout.java @@ -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; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java index 159ecafa53..2c00a68f92 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VEmbedded.java @@ -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); + + } + } + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java index 366476bef0..29f4c77769 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VGridLayout.java @@ -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; } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java index 10d7fe4d02..9c07d61196 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java @@ -5,15 +5,14 @@ import java.util.Iterator; import java.util.Set;
import com.google.gwt.core.client.JsArrayString;
-import com.google.gwt.dom.client.Node;
-import com.google.gwt.dom.client.NodeList;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
-import com.google.gwt.user.client.DOM;
+import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.Element;
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.MouseEventDetails;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
@@ -28,6 +27,8 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler { public static final String CLASSNAME = "v-orderedlayout";
+ public static final String CLICK_EVENT_IDENTIFIER = "click";
+
private int orientation;
// Can be removed once OrderedLayout is removed
@@ -55,7 +56,6 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler { public VOrderedLayout() {
this(CLASSNAME, ORIENTATION_VERTICAL);
allowOrientationUpdate = true;
- addDomHandler(this, ClickEvent.getType());
}
protected VOrderedLayout(String className, int orientation) {
@@ -67,8 +67,6 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler { STYLENAME_MARGIN_RIGHT = className + "-margin-right";
STYLENAME_MARGIN_BOTTOM = className + "-margin-bottom";
STYLENAME_MARGIN_LEFT = className + "-margin-left";
-
- addDomHandler(this, ClickEvent.getType());
}
@Override
@@ -83,6 +81,8 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler { return;
}
+ handleHandlerRegistration();
+
if (allowOrientationUpdate) {
handleOrientationUpdate(uidl);
}
@@ -248,6 +248,26 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler { sizeHasChangedDuringRendering = 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 void layoutSizeMightHaveChanged() {
Size oldSize = new Size(activeLayoutSize.getWidth(), activeLayoutSize
.getHeight());
@@ -924,50 +944,37 @@ public class VOrderedLayout extends CellBasedLayout implements ClickHandler { }
public void onClick(ClickEvent event) {
- Integer childComponentId = getChildComponentId((Element) event
+ // This is only called if there are click listeners registered on server
+ // side
+
+ Paintable childComponent = getChildComponent((Element) event
.getNativeEvent().getEventTarget().cast());
- String childComponentString = childComponentId.toString();
- client.getEventHandler(this).fireEvent("click", "left",
- childComponentString);
+ final MouseEventDetails details = new MouseEventDetails(event
+ .getNativeEvent());
+ Object[] parameters = new Object[] { details, childComponent };
+
+ client.updateVariable(client.getPid(this), CLICK_EVENT_IDENTIFIER,
+ parameters, true);
}
/**
- * Returns the index of the child component which contains "element".
+ * Returns the child component which contains "element".
*
* @param element
* @return
*/
- private int getChildComponentId(Element element) {
+ private Paintable getChildComponent(Element element) {
Element rootElement = getElement();
- Element parent = DOM.getParent(element);
- if (parent == null) {
- return -1;
- }
- Element grandParent = DOM.getParent(parent);
- if (grandParent == null) {
- return -1;
- }
-
- while (grandParent != null && parent != rootElement) {
- if (grandParent == rootElement) {
- NodeList<Node> nodes = parent.getChildNodes();
- int size = nodes.getLength();
- for (int index = 0; index < size; index++) {
- if (nodes.getItem(index) == element) {
- return index;
- }
- }
-
- // This should not happen
- return -1;
+ while (element != null && element != rootElement) {
+ Paintable paintable = client.getPaintable(element);
+ if (paintable != null
+ && widgetToComponentContainer.containsKey(paintable)) {
+ return paintable;
}
-
- element = parent;
- parent = grandParent;
- grandParent = DOM.getParent(grandParent);
}
- return -1;
+
+ return null;
}
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java index 608a7fd9ab..d2db9ce572 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VPanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VPanel.java @@ -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); } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java index 860891f99f..5e5d0bf687 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTextField.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTextField.java @@ -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) { diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java index 8e382622ca..b2f0a5be76 100644 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ b/src/com/vaadin/ui/AbsoluteLayout.java @@ -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); + } + } diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index ee07a560e4..c72701b8ac 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -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); } /** diff --git a/src/com/vaadin/ui/AbstractOrderedLayout.java b/src/com/vaadin/ui/AbstractOrderedLayout.java index ed2f70d4f0..b3cfebc212 100644 --- a/src/com/vaadin/ui/AbstractOrderedLayout.java +++ b/src/com/vaadin/ui/AbstractOrderedLayout.java @@ -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)); - } - } } diff --git a/src/com/vaadin/ui/Embedded.java b/src/com/vaadin/ui/Embedded.java index be60b744aa..c670de86a2 100644 --- a/src/com/vaadin/ui/Embedded.java +++ b/src/com/vaadin/ui/Embedded.java @@ -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)); + } + } diff --git a/src/com/vaadin/ui/GridLayout.java b/src/com/vaadin/ui/GridLayout.java index 510a8051d7..530b5fc7dd 100644 --- a/src/com/vaadin/ui/GridLayout.java +++ b/src/com/vaadin/ui/GridLayout.java @@ -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); } } diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java index 2aaf697e85..7148df9e04 100644 --- a/src/com/vaadin/ui/Panel.java +++ b/src/com/vaadin/ui/Panel.java @@ -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)); } } diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index 99e7cec3de..a79bb614b8 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -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, diff --git a/src/com/vaadin/ui/TextField.java b/src/com/vaadin/ui/TextField.java index 94c97849c2..d54a4d00aa 100644 --- a/src/com/vaadin/ui/TextField.java +++ b/src/com/vaadin/ui/TextField.java @@ -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); } } diff --git a/src/com/vaadin/ui/Tree.java b/src/com/vaadin/ui/Tree.java index 082b9f4624..2182e3aab6 100644 --- a/src/com/vaadin/ui/Tree.java +++ b/src/com/vaadin/ui/Tree.java @@ -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)); |