summaryrefslogtreecommitdiffstats
path: root/client
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2012-08-16 15:46:11 +0300
committerLeif Åstrand <leif@vaadin.com>2012-08-20 08:53:46 +0300
commite81cf22601718cd7909fea1db295bb538b104c9a (patch)
tree8db569d6d57a7f18adb428fdc5784581c406d715 /client
parent4863e078780a3d0ca94c4edcc153d1bdfe5a7f92 (diff)
downloadvaadin-framework-e81cf22601718cd7909fea1db295bb538b104c9a.tar.gz
vaadin-framework-e81cf22601718cd7909fea1db295bb538b104c9a.zip
Support StateChangeHandler for selected parts of the state (#8598)
Diffstat (limited to 'client')
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java33
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ServerConnector.java17
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java41
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java31
-rw-r--r--client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java84
5 files changed, 169 insertions, 37 deletions
diff --git a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
index 664a73dc12..32b15d6d87 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java
@@ -1473,9 +1473,12 @@ public class ApplicationConnection {
.getName(), null), stateJson, state,
ApplicationConnection.this);
- StateChangeEvent event = GWT
- .create(StateChangeEvent.class);
- event.setConnector(connector);
+ Set<String> changedProperties = new HashSet<String>();
+ addJsonFields(stateJson, changedProperties, "");
+
+ StateChangeEvent event = new StateChangeEvent(
+ connector, changedProperties);
+
events.add(event);
}
} catch (final Throwable e) {
@@ -1487,6 +1490,30 @@ public class ApplicationConnection {
}
/**
+ * Recursively adds the names of all fields in all objects in the
+ * provided json object.
+ *
+ * @param json
+ * the json object to process
+ * @param fields
+ * a set of all currently added fields
+ * @param context
+ * the base name of the current object
+ */
+ private void addJsonFields(JSONObject json, Set<String> fields,
+ String context) {
+ for (String key : json.keySet()) {
+ String fieldName = context + key;
+ fields.add(fieldName);
+
+ JSONObject object = json.get(key).isObject();
+ if (object != null) {
+ addJsonFields(object, fields, fieldName + ".");
+ }
+ }
+ }
+
+ /**
* Updates the connector hierarchy and returns a list of events that
* should be fired after update of the hierarchy and the state is
* done.
diff --git a/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java b/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java
index ff37f04f04..8788de74bf 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ServerConnector.java
@@ -75,7 +75,7 @@ public interface ServerConnector extends Connector {
String rpcInterfaceId);
/**
- * Adds a handler that is called whenever some part of the state has been
+ * Adds a handler that is called whenever any part of the state has been
* updated by the server.
*
* @param handler
@@ -86,6 +86,21 @@ public interface ServerConnector extends Connector {
public HandlerRegistration addStateChangeHandler(StateChangeHandler handler);
/**
+ * Adds a handler that is called whenever the given part of the state has
+ * been updated by the server.
+ *
+ * @param propertyName
+ * the name of the property for which the handler should be
+ * called
+ * @param handler
+ * The handler that should be added.
+ * @return A handler registration reference that can be used to unregister
+ * the handler
+ */
+ public HandlerRegistration addStateChangeHandler(String propertyName,
+ StateChangeHandler handler);
+
+ /**
* Sends the given event to all registered handlers.
*
* @param event
diff --git a/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java b/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java
index e1847bdab7..8ed32bc94b 100644
--- a/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java
+++ b/client/src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java
@@ -16,8 +16,11 @@
package com.vaadin.terminal.gwt.client.communication;
import java.io.Serializable;
+import java.util.Collections;
+import java.util.Set;
import com.google.gwt.event.shared.EventHandler;
+import com.vaadin.terminal.gwt.client.ServerConnector;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;
public class StateChangeEvent extends
@@ -27,12 +30,25 @@ public class StateChangeEvent extends
*/
public static final Type<StateChangeHandler> TYPE = new Type<StateChangeHandler>();
+ private Set<String> changedProperties;
+
@Override
public Type<StateChangeHandler> getAssociatedType() {
return TYPE;
}
- public StateChangeEvent() {
+ /**
+ * Creates a new state change event.
+ *
+ * @param connector
+ * the event whose state has changed
+ * @param changedProperties
+ * a set of names of the changed properties
+ */
+ public StateChangeEvent(ServerConnector connector,
+ Set<String> changedProperties) {
+ setConnector(connector);
+ this.changedProperties = changedProperties;
}
@Override
@@ -40,7 +56,30 @@ public class StateChangeEvent extends
listener.onStateChanged(this);
}
+ /**
+ * Event handler that gets notified whenever any part of the state has been
+ * updated by the server.
+ *
+ * @author Vaadin Ltd
+ * @version @VERSION@
+ * @since 7.0.0
+ */
public interface StateChangeHandler extends Serializable, EventHandler {
+ /**
+ * Notifies the event handler that the state has changed.
+ *
+ * @param stateChangeEvent
+ * the state change event with details about the change
+ */
public void onStateChanged(StateChangeEvent stateChangeEvent);
}
+
+ /**
+ * Gets the properties that have changed.
+ *
+ * @return a set of names of the changed properties
+ */
+ public Set<String> getChangedProperties() {
+ return Collections.unmodifiableSet(changedProperties);
+ }
}
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java
index 514f63fdd8..435fff8a5b 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java
@@ -48,6 +48,7 @@ public abstract class AbstractConnector implements ServerConnector,
private String id;
private HandlerManager handlerManager;
+ private Map<String, HandlerManager> statePropertyHandlerManagers;
private Map<String, Collection<ClientRpc>> rpcImplementations;
private final boolean debugLogging = false;
@@ -168,6 +169,17 @@ public abstract class AbstractConnector implements ServerConnector,
if (handlerManager != null) {
handlerManager.fireEvent(event);
}
+ if (statePropertyHandlerManagers != null
+ && event instanceof StateChangeEvent) {
+ for (String property : ((StateChangeEvent) event)
+ .getChangedProperties()) {
+ HandlerManager manager = statePropertyHandlerManagers
+ .get(property);
+ if (manager != null) {
+ manager.fireEvent(event);
+ }
+ }
+ }
}
protected HandlerManager ensureHandlerManager() {
@@ -185,6 +197,25 @@ public abstract class AbstractConnector implements ServerConnector,
}
@Override
+ public HandlerRegistration addStateChangeHandler(String propertyName,
+ StateChangeHandler handler) {
+ return ensureHandlerManager(propertyName).addHandler(
+ StateChangeEvent.TYPE, handler);
+ }
+
+ private HandlerManager ensureHandlerManager(String propertyName) {
+ if (statePropertyHandlerManagers == null) {
+ statePropertyHandlerManagers = new HashMap<String, HandlerManager>();
+ }
+ HandlerManager manager = statePropertyHandlerManagers.get(propertyName);
+ if (manager == null) {
+ manager = new HandlerManager(this);
+ statePropertyHandlerManagers.put(propertyName, manager);
+ }
+ return manager;
+ }
+
+ @Override
public void onStateChanged(StateChangeEvent stateChangeEvent) {
if (debugLogging) {
VConsole.log("State change event for "
diff --git a/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java b/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
index 59e187014c..59f90a9840 100644
--- a/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
+++ b/client/src/com/vaadin/terminal/gwt/client/ui/button/ButtonConnector.java
@@ -16,6 +16,8 @@
package com.vaadin.terminal.gwt.client.ui.button;
+import java.util.Set;
+
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
@@ -34,6 +36,7 @@ import com.vaadin.terminal.gwt.client.EventHelper;
import com.vaadin.terminal.gwt.client.MouseEventDetailsBuilder;
import com.vaadin.terminal.gwt.client.communication.RpcProxy;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
+import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;
import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector;
import com.vaadin.terminal.gwt.client.ui.Icon;
import com.vaadin.ui.Button;
@@ -59,6 +62,47 @@ public class ButtonConnector extends AbstractComponentConnector implements
super.init();
getWidget().addClickHandler(this);
getWidget().client = getConnection();
+ addStateChangeHandler("errorMessage", new StateChangeHandler() {
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ if (null != getState().getErrorMessage()) {
+ if (getWidget().errorIndicatorElement == null) {
+ getWidget().errorIndicatorElement = DOM.createSpan();
+ getWidget().errorIndicatorElement
+ .setClassName("v-errorindicator");
+ }
+ getWidget().wrapper.insertBefore(
+ getWidget().errorIndicatorElement,
+ getWidget().captionElement);
+
+ } else if (getWidget().errorIndicatorElement != null) {
+ getWidget().wrapper
+ .removeChild(getWidget().errorIndicatorElement);
+ getWidget().errorIndicatorElement = null;
+ }
+ }
+ });
+
+ addStateChangeHandler("icon", new StateChangeHandler() {
+ @Override
+ public void onStateChanged(StateChangeEvent stateChangeEvent) {
+ if (getState().getIcon() != null) {
+ if (getWidget().icon == null) {
+ getWidget().icon = new Icon(getConnection());
+ getWidget().wrapper.insertBefore(
+ getWidget().icon.getElement(),
+ getWidget().captionElement);
+ }
+ getWidget().icon.setUri(getState().getIcon().getURL());
+ } else {
+ if (getWidget().icon != null) {
+ getWidget().wrapper.removeChild(getWidget().icon
+ .getElement());
+ getWidget().icon = null;
+ }
+ }
+ }
+ });
}
@Override
@@ -68,39 +112,15 @@ public class ButtonConnector extends AbstractComponentConnector implements
focusHandlerRegistration);
blurHandlerRegistration = EventHelper.updateBlurHandler(this,
blurHandlerRegistration);
- // Set text
- if (getState().isHtmlContentAllowed()) {
- getWidget().setHtml(getState().getCaption());
- } else {
- getWidget().setText(getState().getCaption());
- }
- // handle error
- if (null != getState().getErrorMessage()) {
- if (getWidget().errorIndicatorElement == null) {
- getWidget().errorIndicatorElement = DOM.createSpan();
- getWidget().errorIndicatorElement
- .setClassName("v-errorindicator");
- }
- getWidget().wrapper.insertBefore(getWidget().errorIndicatorElement,
- getWidget().captionElement);
-
- } else if (getWidget().errorIndicatorElement != null) {
- getWidget().wrapper.removeChild(getWidget().errorIndicatorElement);
- getWidget().errorIndicatorElement = null;
- }
-
- if (getState().getIcon() != null) {
- if (getWidget().icon == null) {
- getWidget().icon = new Icon(getConnection());
- getWidget().wrapper.insertBefore(getWidget().icon.getElement(),
- getWidget().captionElement);
- }
- getWidget().icon.setUri(getState().getIcon().getURL());
- } else {
- if (getWidget().icon != null) {
- getWidget().wrapper.removeChild(getWidget().icon.getElement());
- getWidget().icon = null;
+ Set<String> changedProperties = stateChangeEvent.getChangedProperties();
+ if (changedProperties.contains("caption")
+ || changedProperties.contains("htmlContentAllowed")) {
+ // Set text
+ if (getState().isHtmlContentAllowed()) {
+ getWidget().setHtml(getState().getCaption());
+ } else {
+ getWidget().setText(getState().getCaption());
}
}