diff options
author | Leif Åstrand <leif@vaadin.com> | 2012-08-16 15:46:11 +0300 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2012-08-20 08:53:46 +0300 |
commit | e81cf22601718cd7909fea1db295bb538b104c9a (patch) | |
tree | 8db569d6d57a7f18adb428fdc5784581c406d715 /client | |
parent | 4863e078780a3d0ca94c4edcc153d1bdfe5a7f92 (diff) | |
download | vaadin-framework-e81cf22601718cd7909fea1db295bb538b104c9a.tar.gz vaadin-framework-e81cf22601718cd7909fea1db295bb538b104c9a.zip |
Support StateChangeHandler for selected parts of the state (#8598)
Diffstat (limited to 'client')
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()); } } |