瀏覽代碼

#8420 StateChangeHandler that is called for all state changes

tags/7.0.0.alpha2
Artur Signell 12 年之前
父節點
當前提交
6c9783167e

+ 37
- 12
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java 查看文件

@@ -44,6 +44,7 @@ import com.vaadin.terminal.gwt.client.communication.JsonEncoder;
import com.vaadin.terminal.gwt.client.communication.MethodInvocation;
import com.vaadin.terminal.gwt.client.communication.RpcManager;
import com.vaadin.terminal.gwt.client.communication.SharedState;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
import com.vaadin.terminal.gwt.client.ui.RootConnector;
import com.vaadin.terminal.gwt.client.ui.VContextMenu;
import com.vaadin.terminal.gwt.client.ui.VNotification;
@@ -1003,7 +1004,7 @@ public class ApplicationConnection {
createConnectorsIfNeeded(json);

// Update states, do not fire events
updateConnectorState(json);
Collection<StateChangeEvent> pendingStateChangeEvents = updateConnectorState(json);

// Update hierarchy, do not fire events
Collection<ConnectorHierarchyChangedEvent> pendingHierarchyChangeEvents = updateConnectorHierarchy(json);
@@ -1011,12 +1012,8 @@ public class ApplicationConnection {
// Fire hierarchy change events
sendHierarchyChangeEvents(pendingHierarchyChangeEvents);

// (TODO) Fire state change events. Should be after hierarchy
// change listeners: At least caption updates for the parent are
// strange if fired from state change listeners and thus calls
// the parent BEFORE the parent is aware of the child (through a
// hierarchy change event)
VConsole.log(" * Sending state change events");
// Fire state change events.
sendStateChangeEvents(pendingStateChangeEvents);

// Update of legacy (UIDL) style connectors
updateVaadin6StyleConnectors(json);
@@ -1091,6 +1088,29 @@ public class ApplicationConnection {

}

/**
* Sends the state change events created while updating the state
* information.
*
* This must be called after hierarchy change listeners have been
* called. At least caption updates for the parent are strange if
* fired from state change listeners and thus calls the parent
* BEFORE the parent is aware of the child (through a
* ConnectorHierarchyChangedEvent)
*
* @param pendingStateChangeEvents
* The events to send
*/
private void sendStateChangeEvents(
Collection<StateChangeEvent> pendingStateChangeEvents) {
VConsole.log(" * Sending state change events");

for (StateChangeEvent sce : pendingStateChangeEvents) {
sce.getConnector().fireEvent(sce);
}

}

private void unregisterRemovedConnectors() {
int unregistered = 0;
List<ServerConnector> currentConnectors = new ArrayList<ServerConnector>(
@@ -1204,10 +1224,12 @@ public class ApplicationConnection {

}

private void updateConnectorState(ValueMap json) {
private Collection<StateChangeEvent> updateConnectorState(
ValueMap json) {
ArrayList<StateChangeEvent> events = new ArrayList<StateChangeEvent>();
VConsole.log(" * Updating connector states");
if (!json.containsKey("state")) {
return;
return events;
}
// set states for all paintables mentioned in "state"
ValueMap states = json.getValueMap("state");
@@ -1215,9 +1237,9 @@ public class ApplicationConnection {
for (int i = 0; i < keyArray.length(); i++) {
try {
String connectorId = keyArray.get(i);
ServerConnector paintable = connectorMap
ServerConnector connector = connectorMap
.getConnector(connectorId);
if (null != paintable) {
if (null != connector) {

JSONArray stateDataAndType = new JSONArray(
states.getJavaScriptObject(connectorId));
@@ -1226,12 +1248,15 @@ public class ApplicationConnection {
stateDataAndType, connectorMap,
ApplicationConnection.this);

paintable.setState((SharedState) state);
connector.setState((SharedState) state);
events.add(new StateChangeEvent(connector));
}
} catch (final Throwable e) {
VConsole.error(e);
}
}

return events;
}

/**

+ 19
- 0
src/com/vaadin/terminal/gwt/client/ServerConnector.java 查看文件

@@ -5,8 +5,11 @@ package com.vaadin.terminal.gwt.client;

import java.util.Collection;

import com.google.gwt.event.shared.GwtEvent;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.vaadin.terminal.gwt.client.communication.ClientRpc;
import com.vaadin.terminal.gwt.client.communication.SharedState;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;

/**
* Interface implemented by all client side classes that can be communicate with
@@ -79,4 +82,20 @@ public interface ServerConnector extends Connector {
public <T extends ClientRpc> Collection<T> getRpcImplementations(
String rpcInterfaceId);

/**
* Adds a handler that is called whenever some part of the state has been
* updated by the server.
*
* @param handler
* The handler that should be added.
*/
public HandlerRegistration addStateChangeHandler(StateChangeHandler handler);

/**
* Sends the given event to all registered handlers.
*
* @param event
* The event to send.
*/
public void fireEvent(GwtEvent<?> event);
}

+ 27
- 0
src/com/vaadin/terminal/gwt/client/communication/AbstractServerConnectorEvent.java 查看文件

@@ -0,0 +1,27 @@
package com.vaadin.terminal.gwt.client.communication;

import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.vaadin.terminal.gwt.client.ServerConnector;

public abstract class AbstractServerConnectorEvent<H extends EventHandler> extends
GwtEvent<H> {
private ServerConnector connector;

protected AbstractServerConnectorEvent(ServerConnector connector) {
this.connector = connector;
}

public ServerConnector getConnector() {
return connector;
}

/**
* Sends this event to the given handler.
*
* @param handler
* The handler to dispatch.
*/
@Override
public abstract void dispatch(H handler);
}

+ 33
- 0
src/com/vaadin/terminal/gwt/client/communication/StateChangeEvent.java 查看文件

@@ -0,0 +1,33 @@
package com.vaadin.terminal.gwt.client.communication;

import java.io.Serializable;

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
AbstractServerConnectorEvent<StateChangeHandler> {
/**
* Type of this event, used by the event bus.
*/
public static final Type<StateChangeHandler> TYPE = new Type<StateChangeHandler>();

@Override
public Type<StateChangeHandler> getAssociatedType() {
return TYPE;
}

public StateChangeEvent(ServerConnector connector) {
super(connector);
}

@Override
public void dispatch(StateChangeHandler listener) {
listener.onStateChanged(this);
}

public interface StateChangeHandler extends Serializable, EventHandler {
public void onStateChanged(StateChangeEvent stateChangeEvent);
}
}

+ 37
- 1
src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java 查看文件

@@ -9,9 +9,15 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.ServerConnector;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.communication.ClientRpc;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent;
import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler;

/**
* An abstract implementation of Connector.
@@ -21,11 +27,13 @@ import com.vaadin.terminal.gwt.client.communication.ClientRpc;
* @since 7.0.0
*
*/
public abstract class AbstractConnector implements ServerConnector {
public abstract class AbstractConnector implements ServerConnector,
StateChangeHandler {

private ApplicationConnection connection;
private String id;

private HandlerManager handlerManager;
private Map<String, Collection<ClientRpc>> rpcImplementations;

/*
@@ -59,6 +67,7 @@ public abstract class AbstractConnector implements ServerConnector {
this.connection = connection;
id = connectorId;

addStateChangeHandler(this);
init();
}

@@ -132,4 +141,31 @@ public abstract class AbstractConnector implements ServerConnector {
// Client side can always receive message from the server
return true;
}

public void fireEvent(GwtEvent<?> event) {
if (handlerManager != null) {
handlerManager.fireEvent(event);
}
}

protected HandlerManager ensureHandlerManager() {
if (handlerManager == null) {
handlerManager = new HandlerManager(this);
}

return handlerManager;
}

public HandlerRegistration addStateChangeHandler(StateChangeHandler handler) {
return ensureHandlerManager()
.addHandler(StateChangeEvent.TYPE, handler);
}

// TODO Should be abstract as all connectors need it
public void onStateChanged(StateChangeEvent stateChangeEvent) {
System.out.println("State change event for "
+ Util.getConnectorString(stateChangeEvent.getConnector())
+ " received by " + Util.getConnectorString(this));
}

}

Loading…
取消
儲存