svn changeset:10026/svn branch:event-framework-3234tags/6.7.0.beta1
@@ -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[] {}); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 { |
@@ -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; | |||
} | |||
} | |||
} |
@@ -638,4 +638,8 @@ public class ListenerMethod implements EventListener, Serializable { | |||
} | |||
} | |||
public boolean isType(Class<?> eventType) { | |||
return this.eventType == eventType; | |||
} | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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) { |
@@ -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); | |||
} | |||
} |
@@ -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); | |||
} | |||
/** |
@@ -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)); | |||
} | |||
} | |||
} |
@@ -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)); | |||
} | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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)); | |||
} | |||
} |
@@ -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, |
@@ -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); | |||
} | |||
} |
@@ -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)); |