From f7da26697a01cfda4334557fe94579abffee09bb Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Fri, 25 May 2012 16:09:54 +0300 Subject: [PATCH] Initial extension support (#6690) --- .../terminal/AbstractClientConnector.java | 452 ++++++++++++++++++ .../vaadin/terminal/AbstractExtension.java | 25 + src/com/vaadin/terminal/Extension.java | 7 + src/com/vaadin/terminal/PaintTarget.java | 26 +- .../gwt/client/ApplicationConfiguration.java | 16 +- .../gwt/client/ApplicationConnection.java | 119 ++--- .../gwt/client/ComponentConnector.java | 23 - .../client/ComponentContainerConnector.java | 12 +- .../terminal/gwt/client/ComponentLocator.java | 29 +- .../terminal/gwt/client/ComponentState.java | 24 - .../vaadin/terminal/gwt/client/Connector.java | 8 + .../terminal/gwt/client/ConnectorMap.java | 21 +- .../terminal/gwt/client/LayoutManager.java | 12 +- .../terminal/gwt/client/ServerConnector.java | 29 ++ src/com/vaadin/terminal/gwt/client/Util.java | 15 +- .../terminal/gwt/client/VDebugConsole.java | 47 +- .../terminal/gwt/client/VUIDLBrowser.java | 4 +- .../gwt/client/WidgetInstantiator.java | 2 +- .../vaadin/terminal/gwt/client/WidgetMap.java | 12 +- .../vaadin/terminal/gwt/client/WidgetSet.java | 35 +- .../gwt/client/communication/SharedState.java | 26 + .../client/ui/AbstractComponentConnector.java | 67 +-- .../AbstractComponentContainerConnector.java | 41 +- .../gwt/client/ui/AbstractConnector.java | 66 ++- .../AbsoluteLayoutConnector.java | 8 +- .../ui/csslayout/CssLayoutConnector.java | 4 +- .../CustomComponentConnector.java | 4 +- .../customlayout/CustomLayoutConnector.java | 2 +- .../ui/formlayout/FormLayoutConnector.java | 4 +- .../ui/gridlayout/GridLayoutConnector.java | 4 +- .../ui/helloworldfeature/GreetAgainRpc.java | 12 + .../HelloWorldExtensionConnector.java | 48 ++ .../ui/helloworldfeature/HelloWorldRpc.java | 10 + .../ui/helloworldfeature/HelloWorldState.java | 18 + .../ui/layout/LayoutDependencyTree.java | 23 +- .../AbstractOrderedLayoutConnector.java | 6 +- .../gwt/client/ui/panel/PanelConnector.java | 4 +- .../gwt/client/ui/root/RootConnector.java | 6 +- .../AbstractSplitPanelConnector.java | 2 +- .../gwt/client/ui/table/TableConnector.java | 8 +- .../gwt/client/ui/window/WindowConnector.java | 4 +- .../server/AbstractApplicationPortlet.java | 47 +- .../server/AbstractCommunicationManager.java | 100 ++-- .../terminal/gwt/server/ClientConnector.java | 96 ++++ .../gwt/server/DragAndDropService.java | 42 ++ .../terminal/gwt/server/JsonPaintTarget.java | 9 +- .../CustomWidgetMapGenerator.java | 4 +- .../EagerWidgetMapGenerator.java | 5 +- .../LazyWidgetMapGenerator.java | 5 +- .../SerializerMapGenerator.java | 1 + .../widgetsetutils/WidgetMapGenerator.java | 62 ++- src/com/vaadin/ui/AbsoluteLayout.java | 3 +- src/com/vaadin/ui/AbstractComponent.java | 395 ++------------- .../vaadin/ui/AbstractComponentContainer.java | 70 --- src/com/vaadin/ui/Component.java | 138 +----- src/com/vaadin/ui/CssLayout.java | 5 +- src/com/vaadin/ui/CustomField.java | 9 +- src/com/vaadin/ui/DirtyConnectorTracker.java | 84 ++-- src/com/vaadin/ui/Form.java | 4 - src/com/vaadin/ui/HasComponents.java | 11 +- src/com/vaadin/ui/HelloWorldExtension.java | 38 ++ src/com/vaadin/ui/Panel.java | 38 -- src/com/vaadin/ui/Root.java | 8 - src/com/vaadin/ui/Table.java | 18 - .../TestAbstractComponentStyleNames.java | 1 - .../TextFieldWithPropertyFormatter.java | 15 +- .../tests/features/HelloWorldFeatureTest.java | 38 ++ 67 files changed, 1352 insertions(+), 1179 deletions(-) create mode 100644 src/com/vaadin/terminal/AbstractClientConnector.java create mode 100644 src/com/vaadin/terminal/AbstractExtension.java create mode 100644 src/com/vaadin/terminal/Extension.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/GreetAgainRpc.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldExtensionConnector.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldRpc.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldState.java create mode 100644 src/com/vaadin/ui/HelloWorldExtension.java create mode 100644 tests/testbench/com/vaadin/tests/features/HelloWorldFeatureTest.java diff --git a/src/com/vaadin/terminal/AbstractClientConnector.java b/src/com/vaadin/terminal/AbstractClientConnector.java new file mode 100644 index 0000000000..ad7c98b7e1 --- /dev/null +++ b/src/com/vaadin/terminal/AbstractClientConnector.java @@ -0,0 +1,452 @@ +package com.vaadin.terminal; + +import java.io.Serializable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.logging.Logger; + +import com.vaadin.Application; +import com.vaadin.terminal.gwt.client.communication.ClientRpc; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.communication.SharedState; +import com.vaadin.terminal.gwt.server.ClientConnector; +import com.vaadin.terminal.gwt.server.ClientMethodInvocation; +import com.vaadin.terminal.gwt.server.RpcManager; +import com.vaadin.terminal.gwt.server.RpcTarget; +import com.vaadin.terminal.gwt.server.ServerRpcManager; +import com.vaadin.ui.HasComponents; +import com.vaadin.ui.Root; + +/** + * + */ +public abstract class AbstractClientConnector implements ClientConnector { + /** + * A map from client to server RPC interface class to the RPC call manager + * that handles incoming RPC calls for that interface. + */ + private Map, RpcManager> rpcManagerMap = new HashMap, RpcManager>(); + + /** + * A map from server to client RPC interface class to the RPC proxy that + * sends ourgoing RPC calls for that interface. + */ + private Map, ClientRpc> rpcProxyMap = new HashMap, ClientRpc>(); + + /** + * Shared state object to be communicated from the server to the client when + * modified. + */ + private SharedState sharedState; + + /** + * Pending RPC method invocations to be sent. + */ + private ArrayList pendingInvocations = new ArrayList(); + + private String connectorId; + + private ArrayList extensions = new ArrayList(); + + private ClientConnector parent; + + /* Documentation copied from interface */ + public void requestRepaint() { + Root root = getRoot(); + if (root != null) { + root.getDirtyConnectorTracker().markDirty(this); + } + } + + /** + * Registers an RPC interface implementation for this component. + * + * A component can listen to multiple RPC interfaces, and subclasses can + * register additional implementations. + * + * @since 7.0 + * + * @param implementation + * RPC interface implementation + * @param rpcInterfaceType + * RPC interface class for which the implementation should be + * registered + */ + protected void registerRpc(T implementation, Class rpcInterfaceType) { + rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager( + implementation, rpcInterfaceType)); + } + + /** + * Registers an RPC interface implementation for this component. + * + * A component can listen to multiple RPC interfaces, and subclasses can + * register additional implementations. + * + * @since 7.0 + * + * @param implementation + * RPC interface implementation. Also used to deduce the type. + */ + protected void registerRpc(T implementation) { + Class cls = implementation.getClass(); + Class[] interfaces = cls.getInterfaces(); + while (interfaces.length == 0) { + // Search upwards until an interface is found. It must be found as T + // extends ServerRpc + cls = cls.getSuperclass(); + interfaces = cls.getInterfaces(); + } + if (interfaces.length != 1 + || !(ServerRpc.class.isAssignableFrom(interfaces[0]))) { + throw new RuntimeException( + "Use registerRpc(T implementation, Class rpcInterfaceType) if the Rpc implementation implements more than one interface"); + } + Class type = (Class) interfaces[0]; + registerRpc(implementation, type); + } + + public SharedState getState() { + if (null == sharedState) { + sharedState = createState(); + } + return sharedState; + } + + /** + * Creates the shared state bean to be used in server to client + * communication. + *

+ * By default a state object of the defined return type of + * {@link #getState()} is created. Subclasses can override this method and + * return a new instance of the correct state class but this should rarely + * be necessary. + *

+ *

+ * No configuration of the values of the state should be performed in + * {@link #createState()}. + * + * @since 7.0 + * + * @return new shared state object + */ + protected SharedState createState() { + try { + return getStateType().newInstance(); + } catch (Exception e) { + throw new RuntimeException( + "Error creating state of type " + getStateType().getName() + + " for " + getClass().getName(), e); + } + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.terminal.gwt.server.ClientConnector#getStateType() + */ + public Class getStateType() { + try { + Method m = getClass().getMethod("getState", (Class[]) null); + Class type = m.getReturnType(); + return type.asSubclass(SharedState.class); + } catch (Exception e) { + throw new RuntimeException("Error finding state type for " + + getClass().getName(), e); + } + } + + /** + * Returns an RPC proxy for a given server to client RPC interface for this + * component. + * + * TODO more javadoc, subclasses, ... + * + * @param rpcInterface + * RPC interface type + * + * @since 7.0 + */ + public T getRpcProxy(final Class rpcInterface) { + // create, initialize and return a dynamic proxy for RPC + try { + if (!rpcProxyMap.containsKey(rpcInterface)) { + Class proxyClass = Proxy.getProxyClass( + rpcInterface.getClassLoader(), rpcInterface); + Constructor constructor = proxyClass + .getConstructor(InvocationHandler.class); + T rpcProxy = rpcInterface.cast(constructor + .newInstance(new RpcInvoicationHandler(rpcInterface))); + // cache the proxy + rpcProxyMap.put(rpcInterface, rpcProxy); + } + return (T) rpcProxyMap.get(rpcInterface); + } catch (Exception e) { + // TODO exception handling? + throw new RuntimeException(e); + } + } + + private class RpcInvoicationHandler implements InvocationHandler, + Serializable { + + private String rpcInterfaceName; + + public RpcInvoicationHandler(Class rpcInterface) { + rpcInterfaceName = rpcInterface.getName().replaceAll("\\$", "."); + } + + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + addMethodInvocationToQueue(rpcInterfaceName, method, args); + // TODO no need to do full repaint if only RPC calls + requestRepaint(); + return null; + } + + } + + /** + * For internal use: adds a method invocation to the pending RPC call queue. + * + * @param interfaceName + * RPC interface name + * @param method + * RPC method + * @param parameters + * RPC all parameters + * + * @since 7.0 + */ + protected void addMethodInvocationToQueue(String interfaceName, + Method method, Object[] parameters) { + // add to queue + pendingInvocations.add(new ClientMethodInvocation(this, interfaceName, + method, parameters)); + } + + /** + * @see RpcTarget#getRpcManager(Class) + * + * @param rpcInterface + * RPC interface for which a call was made + * @return RPC Manager handling calls for the interface + * + * @since 7.0 + */ + public RpcManager getRpcManager(Class rpcInterface) { + return rpcManagerMap.get(rpcInterface); + } + + public List retrievePendingRpcCalls() { + if (pendingInvocations.isEmpty()) { + return Collections.emptyList(); + } else { + List result = pendingInvocations; + pendingInvocations = new ArrayList(); + return Collections.unmodifiableList(result); + } + } + + public String getConnectorId() { + if (connectorId == null) { + if (getApplication() == null) { + throw new RuntimeException( + "Component must be attached to an application when getConnectorId() is called for the first time"); + } + connectorId = getApplication().createConnectorId(this); + } + return connectorId; + } + + /** + * Finds the Application to which this connector belongs. If the connector + * has not been attached, null is returned. + * + * @return The connector's application, or null if not attached + */ + protected Application getApplication() { + Root root = getRoot(); + if (root == null) { + return null; + } else { + return root.getApplication(); + } + } + + /** + * Finds a Root ancestor of this connector. null is returned if + * no Root ancestor is found (typically because the connector is not + * attached to a proper hierarchy). + * + * @return the Root ancestor of this connector, or null if none + * is found. + */ + protected Root getRoot() { + ClientConnector connector = this; + while (connector != null) { + if (connector instanceof Root) { + return (Root) connector; + } + connector = connector.getParent(); + } + return null; + } + + private static Logger getLogger() { + return Logger.getLogger(AbstractClientConnector.class.getName()); + } + + public void requestRepaintAll() { + requestRepaint(); + + for (ClientConnector connector : getAllChildrenIteratable(this)) { + connector.requestRepaintAll(); + } + } + + private static final class CombinedIterator implements Iterator, + Serializable { + + private final Collection> iterators = new ArrayList>(); + + public void addIterator(Iterator iterator) { + iterators.add(iterator); + } + + public boolean hasNext() { + for (Iterator i : iterators) { + if (i.hasNext()) { + return true; + } + } + return false; + } + + public T next() { + for (Iterator i : iterators) { + if (i.hasNext()) { + return i.next(); + } + } + throw new NoSuchElementException(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } + } + + public static Iterable getAllChildrenIteratable( + final ClientConnector connector) { + return new Iterable() { + public Iterator iterator() { + CombinedIterator iterator = new CombinedIterator(); + iterator.addIterator(connector.getExtensionIterator()); + + if (connector instanceof HasComponents) { + HasComponents hasComponents = (HasComponents) connector; + iterator.addIterator(hasComponents.iterator()); + } + + return iterator; + } + }; + } + + public Iterator getExtensionIterator() { + return Collections.unmodifiableList(extensions).iterator(); + } + + protected void addExtension(Extension extension) { + addExtensionAtIndex(extension, extensions.size()); + } + + protected void addExtensionAtIndex(Extension extension, int index) { + ClientConnector previousParent = extension.getParent(); + if (previousParent == this) { + int oldIndex = extensions.indexOf(extension); + if (oldIndex < index) { + index--; + } + extensions.remove(oldIndex); + extensions.add(index, extension); + } else { + if (previousParent != null) { + previousParent.removeExtension(extension); + } + extensions.add(index, extension); + extension.setParent(this); + } + requestRepaint(); + } + + public void removeExtension(Extension extension) { + extension.setParent(null); + extensions.remove(extension); + requestRepaint(); + } + + public void setParent(ClientConnector parent) { + + // If the parent is not changed, don't do anything + if (parent == this.parent) { + return; + } + + if (parent != null && this.parent != null) { + throw new IllegalStateException(getClass().getName() + + " already has a parent."); + } + + // Send detach event if the component have been connected to a window + if (getApplication() != null) { + detach(); + } + + // Connect to new parent + this.parent = parent; + + // Send attach event if connected to an application + if (getApplication() != null) { + attach(); + } + } + + public ClientConnector getParent() { + return parent; + } + + public void attach() { + requestRepaint(); + + for (ClientConnector connector : getAllChildrenIteratable(this)) { + connector.attach(); + } + } + + public void detach() { + for (ClientConnector connector : getAllChildrenIteratable(this)) { + connector.detach(); + } + } + + public boolean isConnectorEnabled() { + if (getParent() == null) { + // No parent -> the component cannot receive updates from the client + return false; + } else { + return getParent().isConnectorEnabled(); + } + } +} diff --git a/src/com/vaadin/terminal/AbstractExtension.java b/src/com/vaadin/terminal/AbstractExtension.java new file mode 100644 index 0000000000..d01f7544c5 --- /dev/null +++ b/src/com/vaadin/terminal/AbstractExtension.java @@ -0,0 +1,25 @@ +package com.vaadin.terminal; + +import com.vaadin.terminal.gwt.server.ClientConnector; + +public abstract class AbstractExtension extends AbstractClientConnector implements + Extension { + + protected Class getAcceptedParentType() { + return ClientConnector.class; + } + + @Override + public void setParent(ClientConnector parent) { + Class acceptedParentType = getAcceptedParentType(); + if (parent == null || acceptedParentType.isInstance(parent)) { + super.setParent(parent); + } else { + throw new IllegalArgumentException(getClass().getName() + + " can only be attached to parents of type " + + acceptedParentType.getName() + " but attach to " + + parent.getClass().getName() + " was attempted."); + } + } + +} diff --git a/src/com/vaadin/terminal/Extension.java b/src/com/vaadin/terminal/Extension.java new file mode 100644 index 0000000000..7e4b92811d --- /dev/null +++ b/src/com/vaadin/terminal/Extension.java @@ -0,0 +1,7 @@ +package com.vaadin.terminal; + +import com.vaadin.terminal.gwt.server.ClientConnector; + +public interface Extension extends ClientConnector { + +} diff --git a/src/com/vaadin/terminal/PaintTarget.java b/src/com/vaadin/terminal/PaintTarget.java index 9cfa324133..b658c9f4a3 100644 --- a/src/com/vaadin/terminal/PaintTarget.java +++ b/src/com/vaadin/terminal/PaintTarget.java @@ -9,7 +9,9 @@ import java.util.Map; import com.vaadin.terminal.StreamVariable.StreamingStartEvent; import com.vaadin.terminal.gwt.client.ApplicationConnection; +import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.server.ClientConnector; +import com.vaadin.ui.Component; /** * This interface defines the methods for painting XML to the UIDL stream. @@ -39,7 +41,7 @@ public interface PaintTarget extends Serializable { /** * Result of starting to paint a Paintable ( - * {@link PaintTarget#startPaintable(ClientConnector, String)}). + * {@link PaintTarget#startPaintable(Component, String)}). * * @since 7.0 */ @@ -55,7 +57,7 @@ public interface PaintTarget extends Serializable { * changes. */ CACHED - }; + } /** * Prints element start tag of a paintable section. Starts a paintable @@ -73,8 +75,8 @@ public interface PaintTarget extends Serializable { *

*

* Each paintable being painted should be closed by a matching - * {@link #endPaintable(ClientConnector)} regardless of the - * {@link PaintStatus} returned. + * {@link #endPaintable(Component)} regardless of the {@link PaintStatus} + * returned. *

* * @param paintable @@ -89,15 +91,15 @@ public interface PaintTarget extends Serializable { * @see #startTag(String) * @since 7.0 (previously using startTag(Paintable, String)) */ - public PaintStatus startPaintable(ClientConnector paintable, String tag) + public PaintStatus startPaintable(Component paintable, String tag) throws PaintException; /** * Prints paintable element end tag. * - * Calls to {@link #startPaintable(ClientConnector, String)}should be - * matched by {@link #endPaintable(ClientConnector)}. If the parent tag is - * closed before every child tag is closed a PaintException is raised. + * Calls to {@link #startPaintable(Component, String)}should be matched by + * {@link #endPaintable(Component)}. If the parent tag is closed before + * every child tag is closed a PaintException is raised. * * @param paintable * the paintable to close. @@ -105,7 +107,7 @@ public interface PaintTarget extends Serializable { * if the paint operation failed. * @since 7.0 (previously using engTag(String)) */ - public void endPaintable(ClientConnector paintable) throws PaintException; + public void endPaintable(Component paintable) throws PaintException; /** * Prints element start tag. @@ -289,7 +291,7 @@ public interface PaintTarget extends Serializable { * the Paintable to be referenced on client side * @throws PaintException */ - public void addAttribute(String name, ClientConnector value) + public void addAttribute(String name, Component value) throws PaintException; /** @@ -421,8 +423,8 @@ public interface PaintTarget extends Serializable { * @throws PaintException * if the paint oparation fails */ - public void addVariable(VariableOwner owner, String name, - ClientConnector value) throws PaintException; + public void addVariable(VariableOwner owner, String name, Component value) + throws PaintException; /** * Adds a upload stream type variable. diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java index 8eeccb828d..244f310c1a 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConfiguration.java @@ -209,7 +209,7 @@ public class ApplicationConfiguration implements EntryPoint { private HashMap unknownComponents; - private Class[] classes = new Class[1024]; + private Class[] classes = new Class[1024]; private boolean browserDetailsSent = false; private boolean widgetsetVersionSent = false; @@ -393,7 +393,7 @@ public class ApplicationConfiguration implements EntryPoint { return useDebugIdInDom; } - public Class getWidgetClassByEncodedTag( + public Class getConnectorClassByEncodedTag( int tag) { try { return classes[tag]; @@ -508,7 +508,7 @@ public class ApplicationConfiguration implements EntryPoint { public void run() { pending = false; if (!isBusy()) { - Class nextType = getNextType(); + Class nextType = getNextType(); if (nextType == null) { // ensured that all widgets are loaded deferredWidgetLoader = null; @@ -521,13 +521,13 @@ public class ApplicationConfiguration implements EntryPoint { } } - private Class getNextType() { - Class[] deferredLoadedWidgets = widgetSet - .getDeferredLoadedWidgets(); - if (deferredLoadedWidgets.length <= nextWidgetIndex) { + private Class getNextType() { + Class[] deferredLoadedConnectors = widgetSet + .getDeferredLoadedConnectors(); + if (deferredLoadedConnectors.length <= nextWidgetIndex) { return null; } else { - return deferredLoadedWidgets[nextWidgetIndex++]; + return deferredLoadedConnectors[nextWidgetIndex++]; } } diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 51a0ec3f02..4e7213e777 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -1271,27 +1271,24 @@ public class ApplicationConnection { List currentConnectors = new ArrayList( connectorMap.getConnectors()); for (ServerConnector c : currentConnectors) { - if (c instanceof ComponentConnector) { - ComponentConnector cc = (ComponentConnector) c; - if (cc.getParent() != null) { - if (!cc.getParent().getChildren().contains(cc)) { - VConsole.error("ERROR: Connector is connected to a parent but the parent does not contain the connector"); - } - } else if ((cc instanceof RootConnector && cc == getRootConnector())) { - // RootConnector for this connection, leave as-is - } else if (cc instanceof WindowConnector - && getRootConnector().hasSubWindow( - (WindowConnector) cc)) { - // Sub window attached to this RootConnector, leave - // as-is - } else { - // The connector has been detached from the - // hierarchy, unregister it and any possible - // children. The RootConnector should never be - // unregistered even though it has no parent. - connectorMap.unregisterConnector(cc); - unregistered++; + if (c.getParent() != null) { + if (!c.getParent().getChildren().contains(c)) { + VConsole.error("ERROR: Connector is connected to a parent but the parent does not contain the connector"); } + } else if ((c instanceof RootConnector && c == getRootConnector())) { + // RootConnector for this connection, leave as-is + } else if (c instanceof WindowConnector + && getRootConnector().hasSubWindow( + (WindowConnector) c)) { + // Sub window attached to this RootConnector, leave + // as-is + } else { + // The connector has been detached from the + // hierarchy, unregister it and any possible + // children. The RootConnector should never be + // unregistered even though it has no parent. + connectorMap.unregisterConnector(c); + unregistered++; } } @@ -1319,8 +1316,8 @@ public class ApplicationConnection { continue; } - Class connectorClass = configuration - .getWidgetClassByEncodedTag(connectorType); + Class connectorClass = configuration + .getConnectorClassByEncodedTag(connectorType); // Connector does not exist so we must create it if (connectorClass != RootConnector.class) { @@ -1454,47 +1451,44 @@ public class ApplicationConnection { for (int i = 0; i < hierarchyKeys.length(); i++) { try { String connectorId = hierarchyKeys.get(i); - ServerConnector connector = connectorMap + ServerConnector parentConnector = connectorMap .getConnector(connectorId); - if (!(connector instanceof ComponentContainerConnector)) { - VConsole.error("Retrieved a hierarchy update for a connector (" - + connectorId - + ") that is not a ComponentContainerConnector"); - continue; - } - ComponentContainerConnector ccc = (ComponentContainerConnector) connector; - JsArrayString childConnectorIds = hierarchies .getJSStringArray(connectorId); int childConnectorSize = childConnectorIds.length(); List newChildren = new ArrayList(); + List newComponents = new ArrayList(); for (int connectorIndex = 0; connectorIndex < childConnectorSize; connectorIndex++) { String childConnectorId = childConnectorIds .get(connectorIndex); - ComponentConnector childConnector = (ComponentConnector) connectorMap + ServerConnector childConnector = connectorMap .getConnector(childConnectorId); if (childConnector == null) { VConsole.error("Hierarchy claims that " + childConnectorId + " is a child for " + connectorId + " (" - + connector.getClass().getName() + + parentConnector.getClass().getName() + ") but no connector with id " + childConnectorId + " has been registered"); continue; } newChildren.add(childConnector); - if (childConnector.getParent() != ccc) { + if (childConnector instanceof ComponentConnector) { + newComponents + .add((ComponentConnector) childConnector); + } + if (childConnector.getParent() != parentConnector) { // Avoid extra calls to setParent - childConnector.setParent(ccc); + childConnector.setParent(parentConnector); } } // TODO This check should be done on the server side in // the future so the hierarchy update is only sent when // something actually has changed - List oldChildren = ccc + List oldChildren = parentConnector .getChildren(); boolean actuallyChanged = !Util.collectionsEquals( oldChildren, newChildren); @@ -1503,19 +1497,34 @@ public class ApplicationConnection { continue; } - // Fire change event if the hierarchy has changed - ConnectorHierarchyChangeEvent event = GWT - .create(ConnectorHierarchyChangeEvent.class); - event.setOldChildren(oldChildren); - event.setConnector(ccc); - ccc.setChildren((List) newChildren); - events.add(event); + if (parentConnector instanceof ComponentContainerConnector) { + ComponentContainerConnector ccc = (ComponentContainerConnector) parentConnector; + List oldComponents = ccc + .getChildComponents(); + if (!Util.collectionsEquals(oldComponents, + newComponents)) { + // Fire change event if the hierarchy has + // changed + ConnectorHierarchyChangeEvent event = GWT + .create(ConnectorHierarchyChangeEvent.class); + event.setOldChildren(oldComponents); + event.setConnector(parentConnector); + ccc.setChildComponents(newComponents); + events.add(event); + } + } else if (!newComponents.isEmpty()) { + VConsole.error("Hierachy claims " + + Util.getConnectorString(parentConnector) + + " has component children even though it isn't a ComponentContainerConnector"); + } + + parentConnector.setChildren(newChildren); // Remove parent for children that are no longer // attached to this (avoid updating children if they // have already been assigned to a new parent) - for (ComponentConnector oldChild : oldChildren) { - if (oldChild.getParent() != ccc) { + for (ServerConnector oldChild : oldChildren) { + if (oldChild.getParent() != parentConnector) { continue; } @@ -2079,7 +2088,9 @@ public class ApplicationConnection { @Deprecated public ComponentConnector getPaintable(UIDL uidl) { - return getConnector(uidl.getId(), Integer.parseInt(uidl.getTag())); + // Non-component connectors shouldn't be painted from legacy connectors + return (ComponentConnector) getConnector(uidl.getId(), + Integer.parseInt(uidl.getTag())); } /** @@ -2098,17 +2109,17 @@ public class ApplicationConnection { * @return Either an existing ComponentConnector or a new ComponentConnector * of the given type */ - public ComponentConnector getConnector(String connectorId, int connectorType) { + public ServerConnector getConnector(String connectorId, int connectorType) { if (!connectorMap.hasConnector(connectorId)) { return createAndRegisterConnector(connectorId, connectorType); } - return (ComponentConnector) connectorMap.getConnector(connectorId); + return connectorMap.getConnector(connectorId); } /** - * Creates a new ComponentConnector with the given type and id. + * Creates a new ServerConnector with the given type and id. * - * Creates and registers a new ComponentConnector of the given type. Should + * Creates and registers a new ServerConnector of the given type. Should * never be called with the connector id of an existing connector. * * @param connectorId @@ -2116,13 +2127,13 @@ public class ApplicationConnection { * @param connectorType * Type of the connector, as passed from the server side * - * @return A new ComponentConnector of the given type + * @return A new ServerConnector of the given type */ - private ComponentConnector createAndRegisterConnector(String connectorId, + private ServerConnector createAndRegisterConnector(String connectorId, int connectorType) { // Create and register a new connector with the given type - ComponentConnector p = widgetSet.createWidget(connectorType, - configuration); + ServerConnector p = widgetSet + .createWidget(connectorType, configuration); connectorMap.registerConnector(connectorId, p); p.doInit(connectorId, this); diff --git a/src/com/vaadin/terminal/gwt/client/ComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ComponentConnector.java index 5f9171084e..4e6a690a3c 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentConnector.java @@ -70,29 +70,6 @@ public interface ComponentConnector extends ServerConnector { */ public boolean isRelativeHeight(); - /** - * Returns the parent of this connector. Can be null for only the root - * connector. - * - * @return The parent of this connector, as set by - * {@link #setParent(ComponentContainerConnector)}. - */ - public ComponentContainerConnector getParent(); - - /** - * Sets the parent for this connector. This method should only be called by - * the framework to ensure that the connector hierarchy on the client side - * and the server side are in sync. - *

- * Note that calling this method does not fire a - * {@link ConnectorHierarchyChangeEvent}. The event is fired only when the - * whole hierarchy has been updated. - * - * @param parent - * The new parent of the connector - */ - public void setParent(ComponentContainerConnector parent); - /** * Checks if the connector is read only. * diff --git a/src/com/vaadin/terminal/gwt/client/ComponentContainerConnector.java b/src/com/vaadin/terminal/gwt/client/ComponentContainerConnector.java index 05334e8049..08ce3d31dc 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentContainerConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentContainerConnector.java @@ -14,7 +14,7 @@ import com.vaadin.terminal.gwt.client.ConnectorHierarchyChangeEvent.ConnectorHie * An interface used by client-side connectors whose widget is a component * container (implements {@link HasWidgets}). */ -public interface ComponentContainerConnector extends ComponentConnector { +public interface ComponentContainerConnector extends ServerConnector { /** * Update child components caption, description and error message. @@ -42,7 +42,7 @@ public interface ComponentContainerConnector extends ComponentConnector { * @return A collection of children for this connector. An empty collection * if there are no children. Never returns null. */ - public List getChildren(); + public List getChildComponents(); /** * Sets the children for this connector. This method should only be called @@ -50,14 +50,14 @@ public interface ComponentContainerConnector extends ComponentConnector { * side and the server side are in sync. *

* Note that calling this method does not call - * {@link #connectorHierarchyChanged(ConnectorHierarchyChangeEvent)}. The - * event method is called only when the hierarchy has been updated for all - * connectors. + * {@link ConnectorHierarchyChangeHandler#onConnectorHierarchyChange(ConnectorHierarchyChangeEvent)} + * . The event method is called only when the hierarchy has been updated for + * all connectors. * * @param children * The new child connectors */ - public void setChildren(List children); + public void setChildComponents(List children); /** * Adds a handler that is called whenever the child hierarchy of this diff --git a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java index d847d49e6f..205317542f 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentLocator.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentLocator.java @@ -11,7 +11,9 @@ import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.Widget; +import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.terminal.gwt.client.ui.SubPartAware; import com.vaadin.terminal.gwt.client.ui.gridlayout.VGridLayout; import com.vaadin.terminal.gwt.client.ui.orderedlayout.VMeasuringOrderedLayout; @@ -440,8 +442,8 @@ public class ComponentLocator { } else if (w == null) { String id = part; // Must be old static pid (PID_S*) - ComponentConnector connector = (ComponentConnector) ConnectorMap - .get(client).getConnector(id); + ServerConnector connector = ConnectorMap.get(client) + .getConnector(id); if (connector == null) { // Lookup by debugId // TODO Optimize this @@ -449,8 +451,8 @@ public class ComponentLocator { id.substring(5)); } - if (connector != null) { - w = connector.getWidget(); + if (connector instanceof ComponentConnector) { + w = ((SimplePanel) connector).getWidget(); } else { // Not found return null; @@ -588,19 +590,16 @@ public class ComponentLocator { return w; } - private ComponentConnector findConnectorById(ComponentConnector root, - String id) { - if (root instanceof ComponentConnector - && id.equals(root.getState().getDebugId())) { + private ServerConnector findConnectorById(ServerConnector root, String id) { + SharedState state = root.getState(); + if (state instanceof ComponentState + && id.equals(((ComponentState) state).getDebugId())) { return root; } - if (root instanceof ComponentContainerConnector) { - ComponentContainerConnector ccc = (ComponentContainerConnector) root; - for (ComponentConnector child : ccc.getChildren()) { - ComponentConnector found = findConnectorById(child, id); - if (found != null) { - return found; - } + for (ServerConnector child : root.getChildren()) { + ServerConnector found = findConnectorById(child, id); + if (found != null) { + return found; } } diff --git a/src/com/vaadin/terminal/gwt/client/ComponentState.java b/src/com/vaadin/terminal/gwt/client/ComponentState.java index 10cd14251b..9cd5c6f668 100644 --- a/src/com/vaadin/terminal/gwt/client/ComponentState.java +++ b/src/com/vaadin/terminal/gwt/client/ComponentState.java @@ -24,7 +24,6 @@ public class ComponentState extends SharedState { private String width = ""; private boolean readOnly = false; private boolean immediate = false; - private boolean enabled = true; private String description = ""; // Note: for the caption, there is a difference between null and an empty // string! @@ -174,29 +173,6 @@ public class ComponentState extends SharedState { return styles != null && !styles.isEmpty(); } - /** - * Returns true if the component is enabled. - * - * @see com.vaadin.ui.Component#isEnabled() - * - * @return true if the component is enabled - */ - public boolean isEnabled() { - return enabled; - } - - /** - * Enables or disables the component. - * - * @see com.vaadin.ui.Component#setEnabled(boolean) - * - * @param enabled - * new mode for the component - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - /** * Gets the description of the component (typically shown as tooltip). * diff --git a/src/com/vaadin/terminal/gwt/client/Connector.java b/src/com/vaadin/terminal/gwt/client/Connector.java index 1c61052735..9b2fcf61f1 100644 --- a/src/com/vaadin/terminal/gwt/client/Connector.java +++ b/src/com/vaadin/terminal/gwt/client/Connector.java @@ -46,4 +46,12 @@ public interface Connector extends Serializable { */ public String getConnectorId(); + /** + * Gets the parent connector of this connector, or null if the + * connector is not attached to any parent. + * + * @return the parent connector, or null if there is no parent. + */ + public Connector getParent(); + } diff --git a/src/com/vaadin/terminal/gwt/client/ConnectorMap.java b/src/com/vaadin/terminal/gwt/client/ConnectorMap.java index e57776cf1c..816c4f62e3 100644 --- a/src/com/vaadin/terminal/gwt/client/ConnectorMap.java +++ b/src/com/vaadin/terminal/gwt/client/ConnectorMap.java @@ -159,17 +159,16 @@ public class ConnectorMap { idToConnector.remove(connectorId); connector.onUnregister(); - if (connector instanceof ComponentContainerConnector) { - for (ComponentConnector child : ((ComponentContainerConnector) connector) - .getChildren()) { - if (child.getParent() == connector) { - // Only unregister children that are actually connected to - // this parent. For instance when moving connectors from one - // layout to another and removing the first layout it will - // still contain references to its old children, which are - // now attached to another connector. - unregisterConnector(child); - } + for (ServerConnector child : connector.getChildren()) { + if (child.getParent() == connector) { + /* + * Only unregister children that are actually connected to this + * parent. For instance when moving connectors from one layout + * to another and removing the first layout it will still + * contain references to its old children, which are now + * attached to another connector. + */ + unregisterConnector(child); } } } diff --git a/src/com/vaadin/terminal/gwt/client/LayoutManager.java b/src/com/vaadin/terminal/gwt/client/LayoutManager.java index 9390c719fc..2281b4ab9c 100644 --- a/src/com/vaadin/terminal/gwt/client/LayoutManager.java +++ b/src/com/vaadin/terminal/gwt/client/LayoutManager.java @@ -416,11 +416,13 @@ public class LayoutManager { for (ComponentConnector componentConnector : pendingOverflowFixes) { // Delay the overflow fix if the involved connectors might still // change - if (!currentDependencyTree - .noMoreChangesExpected(componentConnector) - || !currentDependencyTree - .noMoreChangesExpected(componentConnector - .getParent())) { + boolean connectorChangesExpected = !currentDependencyTree + .noMoreChangesExpected(componentConnector); + boolean parentChangesExcpected = componentConnector.getParent() instanceof ComponentConnector + && !currentDependencyTree + .noMoreChangesExpected((ComponentConnector) componentConnector + .getParent()); + if (connectorChangesExpected || parentChangesExcpected) { delayedOverflowFixes.add(componentConnector); continue; } diff --git a/src/com/vaadin/terminal/gwt/client/ServerConnector.java b/src/com/vaadin/terminal/gwt/client/ServerConnector.java index 44f65fc6a7..3809073076 100644 --- a/src/com/vaadin/terminal/gwt/client/ServerConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ServerConnector.java @@ -4,6 +4,7 @@ package com.vaadin.terminal.gwt.client; import java.util.Collection; +import java.util.List; import com.google.gwt.event.shared.GwtEvent; import com.google.web.bindery.event.shared.HandlerRegistration; @@ -85,4 +86,32 @@ public interface ServerConnector extends Connector { */ public void onUnregister(); + /** + * Returns the parent of this connector. Can be null for only the root + * connector. + * + * @return The parent of this connector, as set by + * {@link #setParent(ServerConnector)}. + */ + public ServerConnector getParent(); + + /** + * Sets the parent for this connector. This method should only be called by + * the framework to ensure that the connector hierarchy on the client side + * and the server side are in sync. + *

+ * Note that calling this method does not fire a + * {@link ConnectorHierarchyChangeEvent}. The event is fired only when the + * whole hierarchy has been updated. + * + * @param parent + * The new parent of the connector + */ + public void setParent(ServerConnector parent); + + public void updateEnabledState(boolean enabledState); + + public void setChildren(List children); + + public List getChildren(); } diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index c392a0ba9c..87bf27fc27 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -812,13 +812,12 @@ public class Util { return idx; } - private static void printPaintablesInvocations( + private static void printConnectorInvocations( ArrayList invocations, String id, ApplicationConnection c) { - ComponentConnector paintable = (ComponentConnector) ConnectorMap.get(c) - .getConnector(id); - if (paintable != null) { - VConsole.log("\t" + id + " (" + paintable.getClass() + ") :"); + ServerConnector connector = ConnectorMap.get(c).getConnector(id); + if (connector != null) { + VConsole.log("\t" + id + " (" + connector.getClass() + ") :"); for (MethodInvocation invocation : invocations) { Object[] parameters = invocation.getParameters(); String formattedParams = null; @@ -842,7 +841,7 @@ public class Util { + ")"); } } else { - VConsole.log("\t" + id + ": Warning: no corresponding paintable!"); + VConsole.log("\t" + id + ": Warning: no corresponding connector!"); } } @@ -858,14 +857,14 @@ public class Util { if (curId == null) { curId = id; } else if (!curId.equals(id)) { - printPaintablesInvocations(invocations, curId, c); + printConnectorInvocations(invocations, curId, c); invocations.clear(); curId = id; } invocations.add(loggedBurst.get(i)); } if (!invocations.isEmpty()) { - printPaintablesInvocations(invocations, curId, c); + printConnectorInvocations(invocations, curId, c); } } catch (Exception e) { VConsole.error(e); diff --git a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java index 5eaf78f255..09e939336e 100644 --- a/src/com/vaadin/terminal/gwt/client/VDebugConsole.java +++ b/src/com/vaadin/terminal/gwt/client/VDebugConsole.java @@ -560,23 +560,27 @@ public class VDebugConsole extends VOverlay implements Console { Set zeroHeightComponents, ApplicationConnection ac) { for (final ComponentConnector paintable : zeroHeightComponents) { - final Widget layout = paintable.getParent().getWidget(); + final ServerConnector parent = paintable.getParent(); VerticalPanel errorDetails = new VerticalPanel(); errorDetails.add(new Label("" + Util.getSimpleName(paintable) - + " inside " + Util.getSimpleName(layout))); - final CheckBox emphasisInUi = new CheckBox( - "Emphasize components parent in UI (the actual component is not visible)"); - emphasisInUi.addClickHandler(new ClickHandler() { - public void onClick(ClickEvent event) { - if (paintable != null) { + + " inside " + Util.getSimpleName(parent))); + if (parent instanceof ComponentConnector) { + ComponentConnector parentComponent = (ComponentConnector) parent; + final Widget layout = parentComponent.getWidget(); + + final CheckBox emphasisInUi = new CheckBox( + "Emphasize components parent in UI (the actual component is not visible)"); + emphasisInUi.addClickHandler(new ClickHandler() { + public void onClick(ClickEvent event) { Element element2 = layout.getElement(); Widget.setStyleName(element2, "invalidlayout", - emphasisInUi.getValue()); + emphasisInUi.getValue().booleanValue()); } - } - }); - errorDetails.add(emphasisInUi); + }); + + errorDetails.add(emphasisInUi); + } panel.add(errorDetails); } } @@ -862,7 +866,7 @@ public class VDebugConsole extends VOverlay implements Console { log("================"); log("Connector hierarchy for Root: " + root.getState().getCaption() + " (" + root.getConnectorId() + ")"); - Set connectorsInHierarchy = new HashSet(); + Set connectorsInHierarchy = new HashSet(); SimpleTree rootHierachy = dumpConnectorHierarchy(root, "", connectorsInHierarchy); if (panel.isAttached()) { @@ -874,7 +878,7 @@ public class VDebugConsole extends VOverlay implements Console { Collection registeredConnectors = connectorMap .getConnectors(); log("Sub windows:"); - Set subWindowHierarchyConnectors = new HashSet(); + Set subWindowHierarchyConnectors = new HashSet(); for (WindowConnector wc : root.getSubWindows()) { SimpleTree windowHierachy = dumpConnectorHierarchy(wc, "", subWindowHierarchyConnectors); @@ -908,14 +912,15 @@ public class VDebugConsole extends VOverlay implements Console { } - private SimpleTree dumpConnectorHierarchy( - final ComponentConnector connector, String indent, - Set connectors) { + private SimpleTree dumpConnectorHierarchy(final ServerConnector connector, + String indent, Set connectors) { SimpleTree simpleTree = new SimpleTree(getConnectorString(connector)) { @Override protected void select(ClickEvent event) { super.select(event); - VUIDLBrowser.highlight(connector); + if (connector instanceof ComponentConnector) { + VUIDLBrowser.highlight((ComponentConnector) connector); + } } }; simpleTree.addDomHandler(new MouseOutHandler() { @@ -930,12 +935,8 @@ public class VDebugConsole extends VOverlay implements Console { consoleLog(msg); System.out.println(msg); - if (connector instanceof ComponentContainerConnector) { - for (ComponentConnector c : ((ComponentContainerConnector) connector) - .getChildren()) { - simpleTree.add(dumpConnectorHierarchy(c, indent + " ", - connectors)); - } + for (ServerConnector c : connector.getChildren()) { + simpleTree.add(dumpConnectorHierarchy(c, indent + " ", connectors)); } return simpleTree; } diff --git a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java index 9fa973dc29..4230eda298 100644 --- a/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java +++ b/src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java @@ -98,8 +98,8 @@ public class VUIDLBrowser extends SimpleTree { private String getNodeName(UIDL uidl, ApplicationConfiguration conf, int tag) { - Class widgetClassByDecodedTag = conf - .getWidgetClassByEncodedTag(tag); + Class widgetClassByDecodedTag = conf + .getConnectorClassByEncodedTag(tag); if (widgetClassByDecodedTag == UnknownComponentConnector.class) { return conf.getUnknownServerClassNameByTag(tag) + "(NO CLIENT IMPLEMENTATION FOUND)"; diff --git a/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java b/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java index dd69883d58..0a4f92bc79 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetInstantiator.java @@ -7,5 +7,5 @@ package com.vaadin.terminal.gwt.client; * A helper class used by WidgetMap implementation. Used by the generated code. */ interface WidgetInstantiator { - public ComponentConnector get(); + public ServerConnector get(); } diff --git a/src/com/vaadin/terminal/gwt/client/WidgetMap.java b/src/com/vaadin/terminal/gwt/client/WidgetMap.java index af84a11ced..b770414457 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetMap.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetMap.java @@ -17,7 +17,7 @@ import com.vaadin.terminal.gwt.widgetsetutils.WidgetMapGenerator; */ abstract class WidgetMap { - protected static HashMap instmap = new HashMap(); + protected static HashMap, WidgetInstantiator> instmap = new HashMap, WidgetInstantiator>(); /** * Create a new instance of a connector based on its type. @@ -26,8 +26,8 @@ abstract class WidgetMap { * {@link ComponentConnector} class to instantiate * @return new instance of the connector */ - public ComponentConnector instantiate( - Class classType) { + public ServerConnector instantiate( + Class classType) { return instmap.get(classType).get(); } @@ -39,7 +39,7 @@ abstract class WidgetMap { * fully qualified name of the server side component class * @return component connector class to use */ - public abstract Class getConnectorClassForServerSideClassName( + public abstract Class getConnectorClassForServerSideClassName( String fullyqualifiedName); /** @@ -49,7 +49,7 @@ abstract class WidgetMap { * @return component connector class to load after the initial widgetset * loading */ - public abstract Class[] getDeferredLoadedWidgets(); + public abstract Class[] getDeferredLoadedConnectors(); /** * Make sure the code for a (deferred or lazy) component connector type has @@ -60,6 +60,6 @@ abstract class WidgetMap { * component connector class */ public abstract void ensureInstantiator( - Class classType); + Class classType); } diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java index e47837296d..a973c4fd05 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java @@ -18,20 +18,19 @@ public class WidgetSet { private WidgetMap widgetMap = GWT.create(WidgetMap.class); /** - * Create an uninitialized component that best matches given UIDL. The - * component must be a {@link Widget} that implements - * {@link ComponentConnector}. + * Create an uninitialized connector that best matches given UIDL. The + * connector must be a {@link Widget} that implements + * {@link ServerConnector}. * * @param tag - * component type tag for the component to create + * connector type tag for the connector to create * @param client * the application connection that whishes to instantiate widget * - * @return New uninitialized and unregistered component that can paint given + * @return New uninitialized and unregistered connector that can paint given * UIDL. */ - public ComponentConnector createWidget(int tag, - ApplicationConfiguration conf) { + public ServerConnector createWidget(int tag, ApplicationConfiguration conf) { /* * Yes, this (including the generated code in WidgetMap) may look very * odd code, but due the nature of GWT, we cannot do this any cleaner. @@ -40,7 +39,7 @@ public class WidgetSet { * has no "native" counterpart on client side. */ - Class classType = resolveInheritedWidgetType( + Class classType = resolveInheritedWidgetType( conf, tag); if (classType == null || classType == UnknownComponentConnector.class) { @@ -57,9 +56,9 @@ public class WidgetSet { } } - private Class resolveInheritedWidgetType( + private Class resolveInheritedWidgetType( ApplicationConfiguration conf, int tag) { - Class classType = null; + Class classType = null; Integer t = tag; do { classType = resolveWidgetType(t, conf); @@ -68,10 +67,10 @@ public class WidgetSet { return classType; } - protected Class resolveWidgetType(int tag, + protected Class resolveWidgetType(int tag, ApplicationConfiguration conf) { - Class widgetClass = conf - .getWidgetClassByEncodedTag(tag); + Class widgetClass = conf + .getConnectorClassByEncodedTag(tag); return widgetClass; } @@ -85,9 +84,9 @@ public class WidgetSet { * @param applicationConfiguration * @return */ - public Class getConnectorClassByTag(int tag, + public Class getConnectorClassByTag(int tag, ApplicationConfiguration conf) { - Class connectorClass = null; + Class connectorClass = null; Integer t = tag; do { String serverSideClassName = conf.getServerSideClassNameForTag(t); @@ -99,11 +98,11 @@ public class WidgetSet { return connectorClass; } - public Class[] getDeferredLoadedWidgets() { - return widgetMap.getDeferredLoadedWidgets(); + public Class[] getDeferredLoadedConnectors() { + return widgetMap.getDeferredLoadedConnectors(); } - public void loadImplementation(Class nextType) { + public void loadImplementation(Class nextType) { widgetMap.ensureInstantiator(nextType); } diff --git a/src/com/vaadin/terminal/gwt/client/communication/SharedState.java b/src/com/vaadin/terminal/gwt/client/communication/SharedState.java index 266d6bcbf2..b087907f9e 100644 --- a/src/com/vaadin/terminal/gwt/client/communication/SharedState.java +++ b/src/com/vaadin/terminal/gwt/client/communication/SharedState.java @@ -38,4 +38,30 @@ import com.vaadin.terminal.gwt.client.ui.AbstractComponentConnector; * @since 7.0 */ public class SharedState implements Serializable { + + private boolean enabled = true; + + /** + * Returns true if the component is enabled. + * + * @see com.vaadin.ui.Component#isEnabled() + * + * @return true if the component is enabled + */ + public boolean isEnabled() { + return enabled; + } + + /** + * Enables or disables the component. + * + * @see com.vaadin.ui.Component#setEnabled(boolean) + * + * @param enabled + * new mode for the component + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java index d690bdded1..67dbd2d9d9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentConnector.java @@ -12,8 +12,10 @@ import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.ComponentContainerConnector; import com.vaadin.terminal.gwt.client.ComponentState; +import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.terminal.gwt.client.ConnectorMap; import com.vaadin.terminal.gwt.client.LayoutManager; +import com.vaadin.terminal.gwt.client.ServerConnector; import com.vaadin.terminal.gwt.client.TooltipInfo; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; @@ -24,8 +26,6 @@ import com.vaadin.terminal.gwt.client.ui.root.RootConnector; public abstract class AbstractComponentConnector extends AbstractConnector implements ComponentConnector { - private ComponentContainerConnector parent; - private Widget widget; private String lastKnownWidth = ""; @@ -73,8 +73,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector @Override public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - ConnectorMap paintableMap = ConnectorMap.get(getConnection()); if (getState().getDebugId() != null) { @@ -86,7 +84,8 @@ public abstract class AbstractComponentConnector extends AbstractConnector /* * Disabled state may affect (override) tabindex so the order must be - * first setting tabindex, then enabled state. + * first setting tabindex, then enabled state (through super + * implementation). */ if (getState() instanceof TabIndexState && getWidget() instanceof Focusable) { @@ -94,7 +93,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector .getTabIndex()); } - setWidgetEnabled(isEnabled()); + super.onStateChanged(stateChangeEvent); // Style names String styleName = getStyleNames(getWidget().getStylePrimaryName()); @@ -112,10 +111,10 @@ public abstract class AbstractComponentConnector extends AbstractConnector // Set captions if (delegateCaptionHandling()) { - ComponentContainerConnector parent = getParent(); - if (parent != null) { - parent.updateCaption(this); - } else if (!(this instanceof RootConnector)) { + ServerConnector parent = getParent(); + if (parent instanceof ComponentContainerConnector) { + ((ComponentContainerConnector) parent).updateCaption(this); + } else if (parent == null && !(this instanceof RootConnector)) { VConsole.error("Parent of connector " + Util.getConnectorString(this) + " is null. This is typically an indication of a broken component hierarchy"); @@ -143,7 +142,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector // Parent should be updated if either dimension changed between relative // and non-relative if (newWidth.endsWith("%") != lastKnownWidth.endsWith("%")) { - ComponentContainerConnector parent = getParent(); + Connector parent = getParent(); if (parent instanceof ManagedLayout) { getLayoutManager().setNeedsHorizontalLayout( (ManagedLayout) parent); @@ -151,7 +150,7 @@ public abstract class AbstractComponentConnector extends AbstractConnector } if (newHeight.endsWith("%") != lastKnownHeight.endsWith("%")) { - ComponentContainerConnector parent = getParent(); + Connector parent = getParent(); if (parent instanceof ManagedLayout) { getLayoutManager().setNeedsVerticalLayout( (ManagedLayout) parent); @@ -187,23 +186,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector return getState().getWidth().length() == 0; } - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.gwt.client.Connector#isEnabled() - */ - public boolean isEnabled() { - if (!getState().isEnabled()) { - return false; - } - - if (getParent() == null) { - return true; - } else { - return getParent().isEnabled(); - } - } - /* * (non-Javadoc) * @@ -284,26 +266,6 @@ public abstract class AbstractComponentConnector extends AbstractConnector return LayoutManager.get(getConnection()); } - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.gwt.client.Connector#getParent() - */ - public ComponentContainerConnector getParent() { - return parent; - } - - /* - * (non-Javadoc) - * - * @see - * com.vaadin.terminal.gwt.client.Connector#setParent(com.vaadin.terminal - * .gwt.client.ComponentContainerConnector) - */ - public void setParent(ComponentContainerConnector parent) { - this.parent = parent; - } - /** * Checks if there is a registered server side listener for the given event * identifier. @@ -318,6 +280,13 @@ public abstract class AbstractComponentConnector extends AbstractConnector return (reg != null && reg.contains(eventIdentifier)); } + @Override + public void updateEnabledState(boolean enabledState) { + super.updateEnabledState(enabledState); + + setWidgetEnabled(isEnabled()); + } + @Override public void onUnregister() { super.onUnregister(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java index 526631e4b2..c6bfba5023 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/AbstractComponentContainerConnector.java @@ -3,7 +3,7 @@ */ package com.vaadin.terminal.gwt.client.ui; -import java.util.LinkedList; +import java.util.Collections; import java.util.List; import com.google.gwt.event.shared.HandlerRegistration; @@ -18,18 +18,10 @@ public abstract class AbstractComponentContainerConnector extends AbstractComponentConnector implements ComponentContainerConnector, ConnectorHierarchyChangeHandler { - List children; + List childComponents; private final boolean debugLogging = false; - /** - * Temporary storage for last enabled state to be able to see if it has - * changed. Can be removed once we are able to listen specifically for - * enabled changes in the state. Widget.isEnabled() cannot be used as all - * Widgets do not implement HasEnabled - */ - private boolean lastWidgetEnabledState = true; - /** * Default constructor */ @@ -43,12 +35,12 @@ public abstract class AbstractComponentContainerConnector extends * @see * com.vaadin.terminal.gwt.client.ComponentContainerConnector#getChildren() */ - public List getChildren() { - if (children == null) { - return new LinkedList(); + public List getChildComponents() { + if (childComponents == null) { + return Collections.emptyList(); } - return children; + return childComponents; } /* @@ -58,8 +50,8 @@ public abstract class AbstractComponentContainerConnector extends * com.vaadin.terminal.gwt.client.ComponentContainerConnector#setChildren * (java.util.Collection) */ - public void setChildren(List children) { - this.children = children; + public void setChildComponents(List childComponents) { + this.childComponents = childComponents; } /* @@ -80,7 +72,7 @@ public abstract class AbstractComponentContainerConnector extends VConsole.log(oldChildren); String newChildren = "* New children: "; - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { newChildren += Util.getConnectorString(child) + " "; } VConsole.log(newChildren); @@ -92,19 +84,4 @@ public abstract class AbstractComponentContainerConnector extends return ensureHandlerManager().addHandler( ConnectorHierarchyChangeEvent.TYPE, handler); } - - @Override - public void setWidgetEnabled(boolean widgetEnabled) { - if (lastWidgetEnabledState == widgetEnabled) { - return; - } - lastWidgetEnabledState = widgetEnabled; - - super.setWidgetEnabled(widgetEnabled); - for (ComponentConnector c : getChildren()) { - // Update children as they might be affected by the enabled state of - // their parent - c.setWidgetEnabled(c.isEnabled()); - } - } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java b/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java index dc960f90a5..bee9c75165 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/AbstractConnector.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import com.google.gwt.event.shared.GwtEvent; @@ -40,6 +41,16 @@ public abstract class AbstractConnector implements ServerConnector, private final boolean debugLogging = false; private SharedState state; + private ServerConnector parent; + + /** + * Temporary storage for last enabled state to be able to see if it has + * changed. Can be removed once we are able to listen specifically for + * enabled changes in the state. Widget.isEnabled() cannot be used as all + * Widgets do not implement HasEnabled + */ + private boolean lastEnabledState = true; + private List children; /* * (non-Javadoc) @@ -137,16 +148,6 @@ public abstract class AbstractConnector implements ServerConnector, return (Collection) rpcImplementations.get(rpcInterfaceId); } - /* - * (non-Javadoc) - * - * @see com.vaadin.terminal.gwt.client.Connector#isConnectorEnabled() - */ - public boolean isConnectorEnabled() { - // Client side can always receive message from the server - return true; - } - public void fireEvent(GwtEvent event) { if (handlerManager != null) { handlerManager.fireEvent(event); @@ -172,6 +173,8 @@ public abstract class AbstractConnector implements ServerConnector, + Util.getConnectorString(stateChangeEvent.getConnector()) + " received by " + Util.getConnectorString(this)); } + + updateEnabledState(isEnabled()); } /* @@ -214,4 +217,47 @@ public abstract class AbstractConnector implements ServerConnector, return ConnectorStateFactory.createState(getClass()); } + public ServerConnector getParent() { + return parent; + } + + public void setParent(ServerConnector parent) { + this.parent = parent; + } + + public List getChildren() { + if (children == null) { + return Collections.emptyList(); + } + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public boolean isEnabled() { + if (!getState().isEnabled()) { + return false; + } + + if (getParent() == null) { + return true; + } else { + return getParent().isEnabled(); + } + } + + public void updateEnabledState(boolean enabledState) { + if (lastEnabledState == enabledState) { + return; + } + lastEnabledState = enabledState; + + for (ServerConnector c : getChildren()) { + // Update children as they might be affected by the enabled state of + // their parent + c.updateEnabledState(c.isEnabled()); + } + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/absolutelayout/AbsoluteLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/absolutelayout/AbsoluteLayoutConnector.java index b42c0acea7..91436f5353 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/absolutelayout/AbsoluteLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/absolutelayout/AbsoluteLayoutConnector.java @@ -109,7 +109,7 @@ public class AbsoluteLayoutConnector extends // TODO Margin handling - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { getWrapper(child).setPosition( getState().getConnectorPosition(child)); } @@ -133,7 +133,7 @@ public class AbsoluteLayoutConnector extends public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) { super.onConnectorHierarchyChange(event); - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { getWrapper(child); } @@ -149,7 +149,7 @@ public class AbsoluteLayoutConnector extends public void layoutVertically() { VAbsoluteLayout layout = getWidget(); - for (ComponentConnector paintable : getChildren()) { + for (ComponentConnector paintable : getChildComponents()) { Widget widget = paintable.getWidget(); AbsoluteWrapper wrapper = (AbsoluteWrapper) widget.getParent(); Style wrapperStyle = wrapper.getElement().getStyle(); @@ -181,7 +181,7 @@ public class AbsoluteLayoutConnector extends public void layoutHorizontally() { VAbsoluteLayout layout = getWidget(); - for (ComponentConnector paintable : getChildren()) { + for (ComponentConnector paintable : getChildComponents()) { AbsoluteWrapper wrapper = getWrapper(paintable); Style wrapperStyle = wrapper.getElement().getStyle(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java index 71d670fe9d..4d341bddfc 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/csslayout/CssLayoutConnector.java @@ -64,7 +64,7 @@ public class CssLayoutConnector extends AbstractLayoutConnector { getWidget().setMarginStyles( new VMarginInfo(getState().getMarginsBitmask())); - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { if (!getState().getChildCss().containsKey(child)) { continue; } @@ -92,7 +92,7 @@ public class CssLayoutConnector extends AbstractLayoutConnector { int index = 0; FlowPane cssLayoutWidgetContainer = getWidget().panel; - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { VCaption childCaption = childToCaption.get(child); if (childCaption != null) { cssLayoutWidgetContainer.addOrMove(childCaption, index++); diff --git a/src/com/vaadin/terminal/gwt/client/ui/customcomponent/CustomComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/customcomponent/CustomComponentConnector.java index 981818fc69..5001711d6c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/customcomponent/CustomComponentConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/customcomponent/CustomComponentConnector.java @@ -28,8 +28,8 @@ public class CustomComponentConnector extends super.onConnectorHierarchyChange(event); ComponentConnector newChild = null; - if (getChildren().size() == 1) { - newChild = getChildren().get(0); + if (getChildComponents().size() == 1) { + newChild = getChildComponents().get(0); } VCustomComponent customComponent = getWidget(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/customlayout/CustomLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/customlayout/CustomLayoutConnector.java index ca24cfc91a..f8861caf92 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/customlayout/CustomLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/customlayout/CustomLayoutConnector.java @@ -75,7 +75,7 @@ public class CustomLayoutConnector extends AbstractLayoutConnector implements updateHtmlTemplate(); // For all contained widgets - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { String location = getState().getChildLocations().get(child); try { getWidget().setWidget(child.getWidget(), location); diff --git a/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java index cdac73a771..ca21947a6c 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/formlayout/FormLayoutConnector.java @@ -46,9 +46,9 @@ public class FormLayoutConnector extends AbstractLayoutConnector { int childId = 0; - formLayoutTable.setRowCount(getChildren().size()); + formLayoutTable.setRowCount(getChildComponents().size()); - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { Widget childWidget = child.getWidget(); Caption caption = formLayoutTable.getCaption(childWidget); diff --git a/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java index 50afbc5913..2cd82313c2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/gridlayout/GridLayoutConnector.java @@ -63,7 +63,7 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector layout.spacingMeasureElement); // Unregister caption size dependencies - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { Cell cell = layout.widgetToCell.get(child.getWidget()); cell.slot.setCaption(null); } @@ -155,7 +155,7 @@ public class GridLayoutConnector extends AbstractComponentContainerConnector if (needCaptionUpdate) { needCaptionUpdate = false; - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { updateCaption(child); } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/GreetAgainRpc.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/GreetAgainRpc.java new file mode 100644 index 0000000000..0bfb8f3c32 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/GreetAgainRpc.java @@ -0,0 +1,12 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui.helloworldfeature; + +import com.vaadin.terminal.gwt.client.communication.ClientRpc; + +public interface GreetAgainRpc extends ClientRpc { + + public void greetAgain(); + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldExtensionConnector.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldExtensionConnector.java new file mode 100644 index 0000000000..ff444fece5 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldExtensionConnector.java @@ -0,0 +1,48 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui.helloworldfeature; + +import com.google.gwt.user.client.Window; +import com.vaadin.terminal.gwt.client.ServerConnector; +import com.vaadin.terminal.gwt.client.Util; +import com.vaadin.terminal.gwt.client.VConsole; +import com.vaadin.terminal.gwt.client.communication.RpcProxy; +import com.vaadin.terminal.gwt.client.ui.AbstractConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; +import com.vaadin.ui.HelloWorldExtension; + +@Connect(HelloWorldExtension.class) +public class HelloWorldExtensionConnector extends AbstractConnector { + HelloWorldRpc rpc = RpcProxy.create(HelloWorldRpc.class, this); + + @Override + public HelloWorldState getState() { + return (HelloWorldState) super.getState(); + } + + @Override + protected void init() { + registerRpc(GreetAgainRpc.class, new GreetAgainRpc() { + public void greetAgain() { + greet(); + } + }); + } + + @Override + public void setParent(ServerConnector parent) { + super.setParent(parent); + greet(); + } + + private void greet() { + String msg = getState().getGreeting() + " from " + + Util.getConnectorString(this) + " attached to " + + Util.getConnectorString(getParent()); + VConsole.log(msg); + + String response = Window.prompt(msg, ""); + rpc.onMessageSent(response); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldRpc.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldRpc.java new file mode 100644 index 0000000000..0289713390 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldRpc.java @@ -0,0 +1,10 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui.helloworldfeature; + +import com.vaadin.terminal.gwt.client.communication.ServerRpc; + +public interface HelloWorldRpc extends ServerRpc { + public void onMessageSent(String message); +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldState.java b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldState.java new file mode 100644 index 0000000000..9524a5e9aa --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/helloworldfeature/HelloWorldState.java @@ -0,0 +1,18 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui.helloworldfeature; + +import com.vaadin.terminal.gwt.client.communication.SharedState; + +public class HelloWorldState extends SharedState { + private String greeting = "Hello world"; + + public String getGreeting() { + return greeting; + } + + public void setGreeting(String greeting) { + this.greeting = greeting; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/layout/LayoutDependencyTree.java b/src/com/vaadin/terminal/gwt/client/ui/layout/LayoutDependencyTree.java index 1ca8933ff2..18843057f3 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/layout/LayoutDependencyTree.java +++ b/src/com/vaadin/terminal/gwt/client/ui/layout/LayoutDependencyTree.java @@ -13,6 +13,7 @@ import java.util.Set; import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.ComponentContainerConnector; import com.vaadin.terminal.gwt.client.ComponentState; +import com.vaadin.terminal.gwt.client.ServerConnector; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.VConsole; import com.vaadin.terminal.gwt.client.ui.ManagedLayout; @@ -154,9 +155,9 @@ public class LayoutDependencyTree { needsSize.add(connector); } if (!isRelativeInDirection(connector, direction)) { - ComponentConnector parent = connector.getParent(); - if (parent != null) { - needsSize.add(parent); + ServerConnector parent = connector.getParent(); + if (parent instanceof ComponentConnector) { + needsSize.add((ComponentConnector) parent); } } @@ -193,7 +194,7 @@ public class LayoutDependencyTree { if (connector instanceof ComponentContainerConnector) { ComponentContainerConnector container = (ComponentContainerConnector) connector; - for (ComponentConnector child : container.getChildren()) { + for (ComponentConnector child : container.getChildComponents()) { if (isRelativeInDirection(child, direction)) { resized.add(child); } @@ -246,16 +247,15 @@ public class LayoutDependencyTree { private LayoutDependency findPotentiallyChangedScrollbar() { ComponentConnector currentConnector = connector; while (true) { - ComponentContainerConnector parent = currentConnector - .getParent(); - if (parent == null) { + ServerConnector parent = currentConnector.getParent(); + if (!(parent instanceof ComponentConnector)) { return null; } if (parent instanceof MayScrollChildren) { return getDependency(currentConnector, getOppositeDirection()); } - currentConnector = parent; + currentConnector = (ComponentConnector) parent; } } @@ -504,12 +504,11 @@ public class LayoutDependencyTree { public ComponentConnector getScrollingBoundary(ComponentConnector connector) { LayoutDependency dependency = getDependency(connector, HORIZONTAL); if (!dependency.scrollingParentCached) { - ComponentContainerConnector parent = dependency.connector - .getParent(); + ServerConnector parent = dependency.connector.getParent(); if (parent instanceof MayScrollChildren) { dependency.scrollingBoundary = connector; - } else if (parent != null) { - dependency.scrollingBoundary = getScrollingBoundary(parent); + } else if (parent instanceof ComponentConnector) { + dependency.scrollingBoundary = getScrollingBoundary((ComponentConnector) parent); } else { // No scrolling parent } diff --git a/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java b/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java index d15766db21..9a89553fd2 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/orderedlayout/AbstractOrderedLayoutConnector.java @@ -61,7 +61,7 @@ public abstract class AbstractOrderedLayoutConnector extends lm.unregisterDependency(this, layout.spacingMeasureElement); // Unregister child caption listeners - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { VLayoutSlot slot = layout.getSlotForChild(child.getWidget()); slot.setCaption(null); } @@ -105,7 +105,7 @@ public abstract class AbstractOrderedLayoutConnector extends VMeasuringOrderedLayout layout = getWidget(); - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { VLayoutSlot slot = layout.getSlotForChild(child.getWidget()); AlignmentInfo alignment = new AlignmentInfo(getState() @@ -285,7 +285,7 @@ public abstract class AbstractOrderedLayoutConnector extends int currentIndex = 0; VMeasuringOrderedLayout layout = getWidget(); - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { Widget childWidget = child.getWidget(); VLayoutSlot slot = layout.getSlotForChild(childWidget); diff --git a/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java b/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java index 35a0ede390..5b97fc110f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/panel/PanelConnector.java @@ -226,8 +226,8 @@ public class PanelConnector extends AbstractComponentContainerConnector super.onConnectorHierarchyChange(event); // We always have 1 child, unless the child is hidden Widget newChildWidget = null; - if (getChildren().size() == 1) { - ComponentConnector newChild = getChildren().get(0); + if (getChildComponents().size() == 1) { + ComponentConnector newChild = getChildComponents().get(0); newChildWidget = newChild.getWidget(); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java b/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java index e02bcc9330..9be41a9623 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/root/RootConnector.java @@ -329,7 +329,7 @@ public class RootConnector extends AbstractComponentContainerConnector */ @Deprecated public boolean hasSubWindow(WindowConnector wc) { - return getChildren().contains(wc); + return getChildComponents().contains(wc); } /** @@ -340,7 +340,7 @@ public class RootConnector extends AbstractComponentContainerConnector */ public List getSubWindows() { ArrayList windows = new ArrayList(); - for (ComponentConnector child : getChildren()) { + for (ComponentConnector child : getChildComponents()) { if (child instanceof WindowConnector) { windows.add((WindowConnector) child); } @@ -380,7 +380,7 @@ public class RootConnector extends AbstractComponentContainerConnector onChildSizeChange(); } - for (ComponentConnector c : getChildren()) { + for (ComponentConnector c : getChildComponents()) { if (c instanceof WindowConnector) { WindowConnector wc = (WindowConnector) c; wc.setWindowOrderAndPosition(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java index a2f1f26c15..10e5dbe37a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/splitpanel/AbstractSplitPanelConnector.java @@ -143,7 +143,7 @@ public abstract class AbstractSplitPanelConnector extends splitPanel.setSplitPosition(splitPanel.position); splitPanel.updateSizes(); // Report relative sizes in other direction for quicker propagation - List children = getChildren(); + List children = getChildComponents(); for (ComponentConnector child : children) { reportOtherDimension(child); } diff --git a/src/com/vaadin/terminal/gwt/client/ui/table/TableConnector.java b/src/com/vaadin/terminal/gwt/client/ui/table/TableConnector.java index 73bc5da83f..ada0f2424f 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/table/TableConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/table/TableConnector.java @@ -16,6 +16,7 @@ import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.DirectionalManagedLayout; import com.vaadin.terminal.gwt.client.Paintable; +import com.vaadin.terminal.gwt.client.ServerConnector; import com.vaadin.terminal.gwt.client.UIDL; import com.vaadin.terminal.gwt.client.Util; import com.vaadin.terminal.gwt.client.ui.AbstractComponentContainerConnector; @@ -283,8 +284,11 @@ public class TableConnector extends AbstractComponentContainerConnector Scheduler.get().scheduleFinally(new ScheduledCommand() { public void execute() { getLayoutManager().setNeedsMeasure(TableConnector.this); - getLayoutManager().setNeedsMeasure( - TableConnector.this.getParent()); + ServerConnector parent = getParent(); + if (parent instanceof ComponentConnector) { + getLayoutManager().setNeedsMeasure( + (ComponentConnector) parent); + } getLayoutManager().setNeedsVerticalLayout( TableConnector.this); getLayoutManager().layoutNow(); diff --git a/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java b/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java index 3a37baafbb..83de039f0b 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/window/WindowConnector.java @@ -201,8 +201,8 @@ public class WindowConnector extends AbstractComponentContainerConnector // We always have 1 child, unless the child is hidden Widget newChildWidget = null; ComponentConnector newChild = null; - if (getChildren().size() == 1) { - newChild = getChildren().get(0); + if (getChildComponents().size() == 1) { + newChild = getChildComponents().get(0); newChildWidget = newChild.getWidget(); } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java index 5b2be308a3..1acc9d128a 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractApplicationPortlet.java @@ -67,7 +67,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet private static final Logger logger = Logger .getLogger(AbstractApplicationPortlet.class.getName()); - public static class WrappedHttpAndPortletRequest extends + private static class WrappedHttpAndPortletRequest extends WrappedPortletRequest { public WrappedHttpAndPortletRequest(PortletRequest request, @@ -112,7 +112,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } } - public static class WrappedGateinRequest extends + private static class WrappedGateinRequest extends WrappedHttpAndPortletRequest { public WrappedGateinRequest(PortletRequest request, DeploymentConfiguration deploymentConfiguration) { @@ -134,7 +134,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } } - public static class WrappedLiferayRequest extends + private static class WrappedLiferayRequest extends WrappedHttpAndPortletRequest { public WrappedLiferayRequest(PortletRequest request, @@ -169,7 +169,7 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } - public static class AbstractApplicationPortletWrapper implements Callback { + private static class AbstractApplicationPortletWrapper implements Callback { private final AbstractApplicationPortlet portlet; @@ -500,7 +500,20 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet AbstractApplicationPortletWrapper portletWrapper = new AbstractApplicationPortletWrapper( this); - WrappedPortletRequest wrappedRequest = createWrappedRequest(request); + WrappedPortletRequest wrappedRequest; + + String portalInfo = request.getPortalContext().getPortalInfo() + .toLowerCase(); + if (portalInfo.contains("liferay")) { + wrappedRequest = new WrappedLiferayRequest(request, + getDeploymentConfiguration()); + } else if (portalInfo.contains("gatein")) { + wrappedRequest = new WrappedGateinRequest(request, + getDeploymentConfiguration()); + } else { + wrappedRequest = new WrappedPortletRequest(request, + getDeploymentConfiguration()); + } WrappedPortletResponse wrappedResponse = new WrappedPortletResponse( response, getDeploymentConfiguration()); @@ -699,30 +712,6 @@ public abstract class AbstractApplicationPortlet extends GenericPortlet } } - /** - * Wraps the request in a (possibly portal specific) wrapped portlet - * request. - * - * @param request - * The original PortletRequest - * @return A wrapped version of the PorletRequest - */ - protected WrappedPortletRequest createWrappedRequest(PortletRequest request) { - String portalInfo = request.getPortalContext().getPortalInfo() - .toLowerCase(); - if (portalInfo.contains("liferay")) { - return new WrappedLiferayRequest(request, - getDeploymentConfiguration()); - } else if (portalInfo.contains("gatein")) { - return new WrappedGateinRequest(request, - getDeploymentConfiguration()); - } else { - return new WrappedPortletRequest(request, - getDeploymentConfiguration()); - } - - } - private DeploymentConfiguration getDeploymentConfiguration() { return deploymentConfiguration; } diff --git a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java index c08d70aa37..186126c9c6 100644 --- a/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java +++ b/src/com/vaadin/terminal/gwt/server/AbstractCommunicationManager.java @@ -49,6 +49,7 @@ import com.vaadin.Version; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; +import com.vaadin.terminal.AbstractClientConnector; import com.vaadin.terminal.CombinedRequest; import com.vaadin.terminal.LegacyPaint; import com.vaadin.terminal.PaintException; @@ -74,7 +75,6 @@ import com.vaadin.ui.AbstractField; import com.vaadin.ui.Component; import com.vaadin.ui.DirtyConnectorTracker; import com.vaadin.ui.HasComponents; -import com.vaadin.ui.Panel; import com.vaadin.ui.Root; import com.vaadin.ui.Window; @@ -769,7 +769,7 @@ public abstract class AbstractCommunicationManager implements Serializable { logger.log(Level.FINE, "* Creating response to client"); if (repaintAll) { getClientCache(root).clear(); - rootConnectorTracker.markAllComponentsDirty(); + rootConnectorTracker.markAllConnectorsDirty(); // Reset sent locales locales = null; @@ -777,7 +777,7 @@ public abstract class AbstractCommunicationManager implements Serializable { } dirtyVisibleConnectors - .addAll(getDirtyVisibleComponents(rootConnectorTracker)); + .addAll(getDirtyVisibleConnectors(rootConnectorTracker)); logger.log(Level.FINE, "Found " + dirtyVisibleConnectors.size() + " dirty connectors to paint"); @@ -786,7 +786,7 @@ public abstract class AbstractCommunicationManager implements Serializable { ((Component) connector).updateState(); } } - rootConnectorTracker.markAllComponentsClean(); + rootConnectorTracker.markAllConnectorsClean(); outWriter.print("\"changes\":["); @@ -893,26 +893,24 @@ public abstract class AbstractCommunicationManager implements Serializable { outWriter.print("\"hierarchy\":"); JSONObject hierarchyInfo = new JSONObject(); - for (Connector connector : dirtyVisibleConnectors) { - if (connector instanceof HasComponents) { - HasComponents parent = (HasComponents) connector; - String parentConnectorId = parent.getConnectorId(); - JSONArray children = new JSONArray(); - - for (Component child : getChildComponents(parent)) { - if (isVisible(child)) { - children.put(child.getConnectorId()); - } - } - try { - hierarchyInfo.put(parentConnectorId, children); - } catch (JSONException e) { - throw new PaintException( - "Failed to send hierarchy information about " - + parentConnectorId + " to the client: " - + e.getMessage(), e); + for (ClientConnector connector : dirtyVisibleConnectors) { + String connectorId = connector.getConnectorId(); + JSONArray children = new JSONArray(); + + for (ClientConnector child : AbstractClientConnector + .getAllChildrenIteratable(connector)) { + if (isVisible(child)) { + children.put(child.getConnectorId()); } } + try { + hierarchyInfo.put(connectorId, children); + } catch (JSONException e) { + throw new PaintException( + "Failed to send hierarchy information about " + + connectorId + " to the client: " + + e.getMessage(), e); + } } outWriter.append(hierarchyInfo.toString()); outWriter.print(", "); // close hierarchy @@ -1222,6 +1220,30 @@ public abstract class AbstractCommunicationManager implements Serializable { return cache; } + /** + * Checks if the connector is visible in context. For Components, + * {@link #isVisible(Component)} is used. For other types of connectors, the + * contextual visibility of its first Component ancestor is used. If no + * Component ancestor is found, the connector is not visible. + * + * @param connector + * The connector to check + * @return true if the connector is visible to the client, + * false otherwise + */ + static boolean isVisible(ClientConnector connector) { + if (connector instanceof Component) { + return isVisible((Component) connector); + } else { + ClientConnector parent = connector.getParent(); + if (parent == null) { + return false; + } else { + return isVisible(parent); + } + } + } + /** * Checks if the component is visible in context, i.e. returns false if the * child is hidden, the parent is hidden or the parent says the child should @@ -1256,30 +1278,6 @@ public abstract class AbstractCommunicationManager implements Serializable { } - public static Iterable getChildComponents(HasComponents cc) { - // TODO This must be moved to Root/Panel - if (cc instanceof Root) { - Root root = (Root) cc; - List children = new ArrayList(); - if (root.getContent() != null) { - children.add(root.getContent()); - } - for (Window w : root.getWindows()) { - children.add(w); - } - return children; - } else if (cc instanceof Panel) { - // This is so wrong.. (#2924) - if (((Panel) cc).getContent() == null) { - return Collections.emptyList(); - } else { - return Collections.singleton((Component) ((Panel) cc) - .getContent()); - } - } - return cc; - } - /** * Collects all pending RPC calls from listed {@link ClientConnector}s and * clears their RPC queues. @@ -2016,16 +2014,16 @@ public abstract class AbstractCommunicationManager implements Serializable { * root window for which dirty components is to be fetched * @return */ - private ArrayList getDirtyVisibleComponents( + private ArrayList getDirtyVisibleConnectors( DirtyConnectorTracker dirtyConnectorTracker) { - ArrayList dirtyComponents = new ArrayList(); - for (Component c : dirtyConnectorTracker.getDirtyComponents()) { + ArrayList dirtyConnectors = new ArrayList(); + for (ClientConnector c : dirtyConnectorTracker.getDirtyConnectors()) { if (isVisible(c)) { - dirtyComponents.add(c); + dirtyConnectors.add(c); } } - return dirtyComponents; + return dirtyConnectors; } /** diff --git a/src/com/vaadin/terminal/gwt/server/ClientConnector.java b/src/com/vaadin/terminal/gwt/server/ClientConnector.java index 7e74c26fb1..6830aa8e14 100644 --- a/src/com/vaadin/terminal/gwt/server/ClientConnector.java +++ b/src/com/vaadin/terminal/gwt/server/ClientConnector.java @@ -3,10 +3,16 @@ */ package com.vaadin.terminal.gwt.server; +import java.util.Iterator; import java.util.List; +import com.vaadin.terminal.AbstractClientConnector; +import com.vaadin.terminal.Extension; import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.terminal.gwt.client.communication.SharedState; +import com.vaadin.ui.Component; +import com.vaadin.ui.ComponentContainer; +import com.vaadin.ui.Root; /** * Interface implemented by all connectors that are capable of communicating @@ -44,4 +50,94 @@ public interface ClientConnector extends Connector, RpcTarget { */ public Class getStateType(); + public ClientConnector getParent(); + + /** + * Requests that the connector should be repainted as soon as possible. + */ + public void requestRepaint(); + + /** + * Causes a repaint of this connector, and all connectors below it. + * + * This should only be used in special cases, e.g when the state of a + * descendant depends on the state of a ancestor. + */ + public void requestRepaintAll(); + + /** + * Sets the parent connector of the connector. + * + *

+ * This method automatically calls {@link #attach()} if the parent becomes + * attached to the application, regardless of whether it was attached + * previously. Conversely, if the parent is {@code null} and the connector + * is attached to the application, {@link #detach()} is called for the + * connector. + *

+ *

+ * This method is rarely called directly. One of the + * {@link ComponentContainer#addComponent(Component)} or + * {@link AbstractClientConnector#addFeature(Feature)} methods is normally + * used for adding connectors to a container and it will call this method + * implicitly. + *

+ * + *

+ * It is not possible to change the parent without first setting the parent + * to {@code null}. + *

+ * + * @param parent + * the parent connector + * @throws IllegalStateException + * if a parent is given even though the connector already has a + * parent + */ + public void setParent(ClientConnector parent); + + /** + * Notifies the connector that it is connected to an application. + * + *

+ * The caller of this method is {@link #setParent(ClientConnector)} if the + * parent is itself already attached to the application. If not, the parent + * will call the {@link #attach()} for all its children when it is attached + * to the application. This method is always called before the connector is + * painted for the first time. + *

+ * + *

+ * The attachment logic is implemented in {@link AbstractClientConnector}. + *

+ * + * @see #getApplication() + */ + public void attach(); + + /** + * Notifies the component that it is detached from the application. + * + *

+ * The {@link #getApplication()} and {@link #getRoot()} methods might return + * null after this method is called. + *

+ * + *

+ * This method must call {@link Root#componentDetached(Component)} to let + * the Root know that a new Component has been attached. + *

+ * * + *

+ * The caller of this method is {@link #setParent(Component)} if the parent + * is in the application. When the parent is detached from the application + * it is its response to call {@link #detach()} for all the children and to + * detach itself from the terminal. + *

+ */ + public void detach(); + + public Iterator getExtensionIterator(); + + public void removeExtension(Extension feature); } diff --git a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java b/src/com/vaadin/terminal/gwt/server/DragAndDropService.java index f6c96557ea..e2358bcbb9 100644 --- a/src/com/vaadin/terminal/gwt/server/DragAndDropService.java +++ b/src/com/vaadin/terminal/gwt/server/DragAndDropService.java @@ -4,6 +4,7 @@ package com.vaadin.terminal.gwt.server; import java.io.PrintWriter; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.logging.Logger; @@ -17,6 +18,7 @@ import com.vaadin.event.dd.DropTarget; import com.vaadin.event.dd.TargetDetails; import com.vaadin.event.dd.TargetDetailsImpl; import com.vaadin.event.dd.acceptcriteria.AcceptCriterion; +import com.vaadin.terminal.Extension; import com.vaadin.terminal.PaintException; import com.vaadin.terminal.VariableOwner; import com.vaadin.terminal.gwt.client.communication.SharedState; @@ -242,4 +244,44 @@ public class DragAndDropService implements VariableOwner, ClientConnector { public Class getStateType() { return SharedState.class; } + + public void requestRepaint() { + // TODO Auto-generated method stub + + } + + public ClientConnector getParent() { + // TODO Auto-generated method stub + return null; + } + + public void requestRepaintAll() { + // TODO Auto-generated method stub + + } + + public void setParent(ClientConnector parent) { + // TODO Auto-generated method stub + + } + + public void attach() { + // TODO Auto-generated method stub + + } + + public void detach() { + // TODO Auto-generated method stub + + } + + public Iterator getExtensionIterator() { + // TODO Auto-generated method stub + return null; + } + + public void removeExtension(Extension feature) { + // TODO Auto-generated method stub + + } } diff --git a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java index def334290e..1cde164618 100644 --- a/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java +++ b/src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java @@ -26,6 +26,7 @@ import com.vaadin.terminal.ThemeResource; import com.vaadin.terminal.VariableOwner; import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.ui.Alignment; +import com.vaadin.ui.Component; import com.vaadin.ui.CustomLayout; /** @@ -399,7 +400,7 @@ public class JsonPaintTarget implements PaintTarget { } - public void addAttribute(String name, ClientConnector value) + public void addAttribute(String name, Component value) throws PaintException { final String id = value.getConnectorId(); addAttribute(name, id); @@ -468,7 +469,7 @@ public class JsonPaintTarget implements PaintTarget { } public void addVariable(VariableOwner owner, String name, - ClientConnector value) throws PaintException { + Component value) throws PaintException { tag.addVariable(new StringVariable(owner, name, value.getConnectorId())); } @@ -645,7 +646,7 @@ public class JsonPaintTarget implements PaintTarget { * @see com.vaadin.terminal.PaintTarget#startPaintable(com.vaadin.terminal * .Paintable, java.lang.String) */ - public PaintStatus startPaintable(ClientConnector connector, String tagName) + public PaintStatus startPaintable(Component connector, String tagName) throws PaintException { boolean topLevelPaintable = openPaintables.isEmpty(); @@ -670,7 +671,7 @@ public class JsonPaintTarget implements PaintTarget { return PaintStatus.PAINTING; } - public void endPaintable(ClientConnector paintable) throws PaintException { + public void endPaintable(Component paintable) throws PaintException { logger.fine("endPaintable for " + paintable.getClass().getName() + "@" + Integer.toHexString(paintable.hashCode())); diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java index f0d6f0453b..f0f3df20b0 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/CustomWidgetMapGenerator.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.HashSet; import com.vaadin.terminal.gwt.client.ComponentConnector; +import com.vaadin.terminal.gwt.client.ServerConnector; import com.vaadin.terminal.gwt.client.ui.Connect; import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle; @@ -25,8 +26,7 @@ public abstract class CustomWidgetMapGenerator extends WidgetMapGenerator { private Collection> deferredPaintables = new HashSet>(); @Override - protected LoadStyle getLoadStyle( - Class connector) { + protected LoadStyle getLoadStyle(Class connector) { if (eagerPaintables == null) { init(); } diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java index 8a1dfee3b5..084e1c3857 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/EagerWidgetMapGenerator.java @@ -3,7 +3,7 @@ */ package com.vaadin.terminal.gwt.widgetsetutils; -import com.vaadin.terminal.gwt.client.ComponentConnector; +import com.vaadin.terminal.gwt.client.ServerConnector; import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle; /** @@ -23,8 +23,7 @@ import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle; public class EagerWidgetMapGenerator extends WidgetMapGenerator { @Override - protected LoadStyle getLoadStyle( - Class connector) { + protected LoadStyle getLoadStyle(Class connector) { return LoadStyle.EAGER; } } diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java index 729a999a21..f8366beb46 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/LazyWidgetMapGenerator.java @@ -3,7 +3,7 @@ */ package com.vaadin.terminal.gwt.widgetsetutils; -import com.vaadin.terminal.gwt.client.ComponentConnector; +import com.vaadin.terminal.gwt.client.ServerConnector; import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle; /** @@ -16,8 +16,7 @@ import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle; */ public class LazyWidgetMapGenerator extends WidgetMapGenerator { @Override - protected LoadStyle getLoadStyle( - Class connector) { + protected LoadStyle getLoadStyle(Class connector) { return LoadStyle.LAZY; } diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java index 07efcda91b..2688775435 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/SerializerMapGenerator.java @@ -203,6 +203,7 @@ public class SerializerMapGenerator extends Generator { // Generate serializer classes for each subclass of SharedState JClassType serializerType = typeOracle.findType(SharedState.class .getName()); + types.add(serializerType); JClassType[] serializerSubtypes = serializerType.getSubtypes(); for (JClassType type : serializerSubtypes) { types.add(type); diff --git a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java index 6d4289b173..b264a9c7fe 100644 --- a/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java +++ b/src/com/vaadin/terminal/gwt/widgetsetutils/WidgetMapGenerator.java @@ -22,8 +22,8 @@ import com.google.gwt.core.ext.typeinfo.JClassType; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.user.rebind.ClassSourceFileComposerFactory; import com.google.gwt.user.rebind.SourceWriter; -import com.vaadin.terminal.gwt.client.ComponentConnector; import com.vaadin.terminal.gwt.client.Connector; +import com.vaadin.terminal.gwt.client.ServerConnector; import com.vaadin.terminal.gwt.client.ui.Connect; import com.vaadin.terminal.gwt.client.ui.Connect.LoadStyle; import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector; @@ -71,7 +71,7 @@ import com.vaadin.terminal.gwt.server.ClientConnector; */ public class WidgetMapGenerator extends Generator { - private static String componentConnectorClassName = ComponentConnector.class + private static String serverConnectorClassName = ServerConnector.class .getName(); private String packageName; @@ -115,7 +115,7 @@ public class WidgetMapGenerator extends Generator { return; } logger.log(Type.INFO, - "Detecting Vaadin components in classpath to generate WidgetMapImpl.java ..."); + "Detecting Vaadin connectors in classpath to generate WidgetMapImpl.java ..."); Date date = new Date(); // init composer, set class properties, create source writer @@ -128,7 +128,7 @@ public class WidgetMapGenerator extends Generator { SourceWriter sourceWriter = composer.createSourceWriter(context, printWriter); - Collection> connectors = getUsedConnectors(context + Collection> connectors = getUsedConnectors(context .getTypeOracle()); validateConnectors(logger, connectors); @@ -149,12 +149,11 @@ public class WidgetMapGenerator extends Generator { } private void validateConnectors(TreeLogger logger, - Collection> connectors) { + Collection> connectors) { - Iterator> iter = connectors - .iterator(); + Iterator> iter = connectors.iterator(); while (iter.hasNext()) { - Class connectorClass = iter.next(); + Class connectorClass = iter.next(); Connect annotation = connectorClass.getAnnotation(Connect.class); if (!ClientConnector.class.isAssignableFrom(annotation.value())) { logger.log( @@ -173,13 +172,13 @@ public class WidgetMapGenerator extends Generator { } private void logConnectors(TreeLogger logger, GeneratorContext context, - Collection> connectors) { + Collection> connectors) { logger.log(Type.INFO, "Widget set will contain implementations for following component connectors: "); TreeSet classNames = new TreeSet(); HashMap loadStyle = new HashMap(); - for (Class connectorClass : connectors) { + for (Class connectorClass : connectors) { String className = connectorClass.getCanonicalName(); classNames.add(className); if (getLoadStyle(connectorClass) == LoadStyle.DEFERRED) { @@ -208,16 +207,16 @@ public class WidgetMapGenerator extends Generator { * widgetset */ @SuppressWarnings("unchecked") - private Collection> getUsedConnectors( + private Collection> getUsedConnectors( TypeOracle typeOracle) { JClassType connectorType = typeOracle.findType(Connector.class .getName()); - Collection> connectors = new HashSet>(); + Collection> connectors = new HashSet>(); for (JClassType jClassType : connectorType.getSubtypes()) { Connect annotation = jClassType.getAnnotation(Connect.class); if (annotation != null) { try { - Class clazz = (Class) Class + Class clazz = (Class) Class .forName(jClassType.getQualifiedSourceName()); connectors.add(clazz); } catch (ClassNotFoundException e) { @@ -242,15 +241,14 @@ public class WidgetMapGenerator extends Generator { * @return true iff the widget for given component should be lazy loaded by * the client side engine */ - protected LoadStyle getLoadStyle( - Class connector) { + protected LoadStyle getLoadStyle(Class connector) { Connect annotation = connector.getAnnotation(Connect.class); return annotation.loadStyle(); } private void generateInstantiatorMethod( SourceWriter sourceWriter, - Collection> connectorsHavingComponentAnnotation) { + Collection> connectorsHavingComponentAnnotation) { Collection> deferredWidgets = new LinkedList>(); @@ -258,16 +256,16 @@ public class WidgetMapGenerator extends Generator { // lookup with index than with the hashmap sourceWriter.println("public void ensureInstantiator(Class classType) {"); + + serverConnectorClassName + "> classType) {"); sourceWriter.println("if(!instmap.containsKey(classType)){"); boolean first = true; - ArrayList> lazyLoadedWidgets = new ArrayList>(); + ArrayList> lazyLoadedConnectors = new ArrayList>(); - HashSet> connectorsWithInstantiator = new HashSet>(); + HashSet> connectorsWithInstantiator = new HashSet>(); - for (Class class1 : connectorsHavingComponentAnnotation) { - Class clientClass = class1; + for (Class class1 : connectorsHavingComponentAnnotation) { + Class clientClass = class1; if (connectorsWithInstantiator.contains(clientClass)) { continue; } @@ -284,7 +282,7 @@ public class WidgetMapGenerator extends Generator { + ".class) {"); String instantiator = "new WidgetInstantiator() {\n public " - + componentConnectorClassName + + serverConnectorClassName + " get() {\n return GWT.create(" + clientClass.getName() + ".class );\n}\n}\n"; @@ -298,7 +296,7 @@ public class WidgetMapGenerator extends Generator { + clientClass.getName() + ".class," + instantiator + ");}});\n"); - lazyLoadedWidgets.add(class1); + lazyLoadedConnectors.add(class1); if (loadStyle == LoadStyle.DEFERRED) { deferredWidgets.add(class1); @@ -321,8 +319,8 @@ public class WidgetMapGenerator extends Generator { sourceWriter.println("}"); sourceWriter.println("public Class[] getDeferredLoadedWidgets() {"); + + serverConnectorClassName + + ">[] getDeferredLoadedConnectors() {"); sourceWriter.println("return new Class[] {"); first = true; @@ -344,11 +342,11 @@ public class WidgetMapGenerator extends Generator { // TODO an index of last ensured widget in array - sourceWriter.println("public " + componentConnectorClassName - + " instantiate(Class classType) {"); sourceWriter.indent(); - sourceWriter.println(componentConnectorClassName + sourceWriter.println(serverConnectorClassName + " p = super.instantiate(classType); if(p!= null) return p;"); sourceWriter.println("return instmap.get(classType).get();"); @@ -365,17 +363,17 @@ public class WidgetMapGenerator extends Generator { */ private void generateImplementationDetector( SourceWriter sourceWriter, - Collection> paintablesHavingWidgetAnnotation) { + Collection> paintablesHavingWidgetAnnotation) { sourceWriter .println("public Class " + "getConnectorClassForServerSideClassName(String fullyQualifiedName) {"); sourceWriter.indent(); sourceWriter .println("fullyQualifiedName = fullyQualifiedName.intern();"); - for (Class connectorClass : paintablesHavingWidgetAnnotation) { + for (Class connectorClass : paintablesHavingWidgetAnnotation) { Class clientConnectorClass = getClientConnectorClass(connectorClass); sourceWriter.print("if ( fullyQualifiedName == \""); sourceWriter.print(clientConnectorClass.getName()); @@ -393,7 +391,7 @@ public class WidgetMapGenerator extends Generator { } private static Class getClientConnectorClass( - Class connectorClass) { + Class connectorClass) { Connect annotation = connectorClass.getAnnotation(Connect.class); return (Class) annotation.value(); } diff --git a/src/com/vaadin/ui/AbsoluteLayout.java b/src/com/vaadin/ui/AbsoluteLayout.java index 9ba005f75a..7d8c402fc9 100644 --- a/src/com/vaadin/ui/AbsoluteLayout.java +++ b/src/com/vaadin/ui/AbsoluteLayout.java @@ -161,7 +161,8 @@ public class AbsoluteLayout extends AbstractLayout implements // connectorId unless the component is attached to the application so // the String->String map cannot be populated in internal* either. Map connectorToPosition = new HashMap(); - for (Component c : this) { + for (Iterator ci = getComponentIterator(); ci.hasNext();) { + Component c = ci.next(); connectorToPosition.put(c.getConnectorId(), getPosition(c) .getCSSString()); } diff --git a/src/com/vaadin/ui/AbstractComponent.java b/src/com/vaadin/ui/AbstractComponent.java index 554d7806f9..25695e3c0c 100644 --- a/src/com/vaadin/ui/AbstractComponent.java +++ b/src/com/vaadin/ui/AbstractComponent.java @@ -5,20 +5,13 @@ package com.vaadin.ui; import java.io.Serializable; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; import java.util.Locale; -import java.util.Map; -import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -27,18 +20,14 @@ import com.vaadin.event.ActionManager; import com.vaadin.event.EventRouter; import com.vaadin.event.MethodEventSource; import com.vaadin.event.ShortcutListener; +import com.vaadin.terminal.AbstractClientConnector; import com.vaadin.terminal.ErrorMessage; import com.vaadin.terminal.Resource; import com.vaadin.terminal.Terminal; import com.vaadin.terminal.gwt.client.ComponentState; -import com.vaadin.terminal.gwt.client.communication.ClientRpc; -import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.terminal.gwt.server.ClientMethodInvocation; +import com.vaadin.terminal.gwt.server.ClientConnector; import com.vaadin.terminal.gwt.server.ComponentSizeValidator; import com.vaadin.terminal.gwt.server.ResourceReference; -import com.vaadin.terminal.gwt.server.RpcManager; -import com.vaadin.terminal.gwt.server.RpcTarget; -import com.vaadin.terminal.gwt.server.ServerRpcManager; import com.vaadin.tools.ReflectTools; /** @@ -53,7 +42,8 @@ import com.vaadin.tools.ReflectTools; * @since 3.0 */ @SuppressWarnings("serial") -public abstract class AbstractComponent implements Component, MethodEventSource { +public abstract class AbstractComponent extends AbstractClientConnector + implements Component, MethodEventSource { /* Private members */ @@ -63,11 +53,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource */ private Object applicationData; - /** - * The container this component resides in. - */ - private HasComponents parent = null; - /** * The EventRouter used for the event model. */ @@ -88,11 +73,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource */ private boolean delayedFocus; - /** - * List of repaint request listeners or null if not listened at all. - */ - private LinkedList repaintRequestListeners = null; - /* Sizeable fields */ private float width = SIZE_UNDEFINED; @@ -110,31 +90,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource */ private ActionManager actionManager; - /** - * A map from client to server RPC interface class to the RPC call manager - * that handles incoming RPC calls for that interface. - */ - private Map, RpcManager> rpcManagerMap = new HashMap, RpcManager>(); - - /** - * A map from server to client RPC interface class to the RPC proxy that - * sends ourgoing RPC calls for that interface. - */ - private Map, ClientRpc> rpcProxyMap = new HashMap, ClientRpc>(); - - /** - * Shared state object to be communicated from the server to the client when - * modified. - */ - private ComponentState sharedState; - - /** - * Pending RPC method invocations to be sent. - */ - private ArrayList pendingInvocations = new ArrayList(); - - private String connectorId; - /* Constructor */ /** @@ -287,6 +242,7 @@ public abstract class AbstractComponent implements Component, MethodEventSource if (locale != null) { return locale; } + HasComponents parent = getParent(); if (parent != null) { return parent.getLocale(); } @@ -378,21 +334,18 @@ public abstract class AbstractComponent implements Component, MethodEventSource * * @see com.vaadin.terminal.gwt.client.Connector#isConnectorEnabled() */ + @Override public boolean isConnectorEnabled() { - if (getParent() == null) { - // No parent -> the component cannot receive updates from the client + if (!isVisible()) { + return false; + } else if (!isEnabled()) { + return false; + } else if (!super.isConnectorEnabled()) { + return false; + } else if (!getParent().isComponentVisible(this)) { return false; } else { - boolean thisEnabledAndVisible = isEnabled() && isVisible(); - if (!thisEnabledAndVisible) { - return false; - } - - if (!getParent().isConnectorEnabled()) { - return false; - } - - return getParent().isComponentVisible(this); + return true; } } @@ -529,8 +482,20 @@ public abstract class AbstractComponent implements Component, MethodEventSource * Gets the component's parent component. Don't add a JavaDoc comment here, * we use the default documentation from implemented interface. */ + @Override public HasComponents getParent() { - return parent; + return (HasComponents) super.getParent(); + } + + @Override + public void setParent(ClientConnector parent) { + if (parent == null || parent instanceof HasComponents) { + super.setParent(parent); + } else { + throw new IllegalArgumentException( + "The parent of a Component must implement HasComponents, which " + + parent.getClass() + " doesn't do."); + } } /** @@ -558,36 +523,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource return null; } - /* - * Sets the parent component. Don't add a JavaDoc comment here, we use the - * default documentation from implemented interface. - */ - public void setParent(HasComponents parent) { - - // If the parent is not changed, don't do anything - if (parent == this.parent) { - return; - } - - if (parent != null && this.parent != null) { - throw new IllegalStateException(getClass().getName() - + " already has a parent."); - } - - // Send detach event if the component have been connected to a window - if (getApplication() != null) { - detach(); - } - - // Connect to new parent - this.parent = parent; - - // Send attach event if connected to a window - if (getApplication() != null) { - attach(); - } - } - /** * Gets the error message for this component. * @@ -648,12 +583,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource * Gets the parent window of the component. Don't add a JavaDoc comment * here, we use the default documentation from implemented interface. */ + @Override public Root getRoot() { - if (parent == null) { - return null; - } else { - return parent.getRoot(); - } + // Just make method from implemented Component interface public + return super.getRoot(); } /* @@ -661,9 +594,9 @@ public abstract class AbstractComponent implements Component, MethodEventSource * comment here, we use the default documentation from implemented * interface. */ + @Override public void attach() { - getRoot().componentAttached(this); - requestRepaint(); + super.attach(); if (delayedFocus) { focus(); } @@ -674,13 +607,13 @@ public abstract class AbstractComponent implements Component, MethodEventSource * Detach the component from application. Don't add a JavaDoc comment here, * we use the default documentation from implemented interface. */ + @Override public void detach() { if (actionManager != null) { // Remove any existing viewer. Root cast is just to make the // compiler happy actionManager.setViewer((Root) null); } - getRoot().componentDetached(this); } /** @@ -717,12 +650,10 @@ public abstract class AbstractComponent implements Component, MethodEventSource * @return the parent application of the component or null. * @see #attach() */ + @Override public Application getApplication() { - if (parent == null) { - return null; - } else { - return parent.getApplication(); - } + // Just make method inherited from Component interface public + return super.getApplication(); } /** @@ -762,11 +693,9 @@ public abstract class AbstractComponent implements Component, MethodEventSource * * @return updated component shared state */ + @Override public ComponentState getState() { - if (null == sharedState) { - sharedState = createState(); - } - return sharedState; + return (ComponentState) super.getState(); } /* @@ -801,95 +730,15 @@ public abstract class AbstractComponent implements Component, MethodEventSource } } - /** - * Creates the shared state bean to be used in server to client - * communication. - *

- * By default a state object of the defined return type of - * {@link #getState()} is created. Subclasses can override this method and - * return a new instance of the correct state class but this should rarely - * be necessary. - *

- *

- * No configuration of the values of the state should be performed in - * {@link #createState()}. - * - * @since 7.0 - * - * @return new shared state object - */ - protected ComponentState createState() { - try { - return getStateType().newInstance(); - } catch (Exception e) { - throw new RuntimeException( - "Error creating state of type " + getStateType().getName() - + " for " + getClass().getName(), e); - } - } - - /* (non-Javadoc) - * @see com.vaadin.terminal.gwt.server.ClientConnector#getStateType() - */ - public Class getStateType() { - try { - Method m = getClass().getMethod("getState", (Class[]) null); - Class type = (Class) m - .getReturnType(); - return type; - } catch (Exception e) { - throw new RuntimeException("Error finding state type for " - + getClass().getName(), e); - } - } - /* Documentation copied from interface */ + @Override public void requestRepaint() { // Invisible components (by flag in this particular component) do not // need repaints if (!getState().isVisible()) { return; } - - fireRequestRepaintEvent(); - } - - /** - * Fires the repaint request event. - * - * @param alreadyNotified - */ - // Notify listeners only once - private void fireRequestRepaintEvent() { - // Notify the listeners - if (repaintRequestListeners != null - && !repaintRequestListeners.isEmpty()) { - final Object[] listeners = repaintRequestListeners.toArray(); - final RepaintRequestEvent event = new RepaintRequestEvent(this); - for (int i = 0; i < listeners.length; i++) { - ((RepaintRequestListener) listeners[i]).repaintRequested(event); - } - } - } - - /* Documentation copied from interface */ - public void addListener(RepaintRequestListener listener) { - if (repaintRequestListeners == null) { - repaintRequestListeners = new LinkedList(); - } - if (!repaintRequestListeners.contains(listener)) { - repaintRequestListeners.add(listener); - } - } - - /* Documentation copied from interface */ - public void removeListener(RepaintRequestListener listener) { - if (repaintRequestListeners != null) { - repaintRequestListeners.remove(listener); - if (repaintRequestListeners.isEmpty()) { - repaintRequestListeners = null; - } - } + super.requestRepaint(); } /* General event framework */ @@ -1155,15 +1004,6 @@ public abstract class AbstractComponent implements Component, MethodEventSource * are found. */ public Collection getListeners(Class eventType) { - if (eventType.isAssignableFrom(RepaintRequestEvent.class)) { - // RepaintRequestListeners are not stored in eventRouter - if (repaintRequestListeners == null) { - return Collections.EMPTY_LIST; - } else { - return Collections - .unmodifiableCollection(repaintRequestListeners); - } - } if (eventRouter == null) { return Collections.EMPTY_LIST; } @@ -1512,159 +1352,4 @@ public abstract class AbstractComponent implements Component, MethodEventSource actionManager.removeAction(shortcut); } } - - /** - * Registers an RPC interface implementation for this component. - * - * A component can listen to multiple RPC interfaces, and subclasses can - * register additional implementations. - * - * @since 7.0 - * - * @param implementation - * RPC interface implementation - * @param rpcInterfaceType - * RPC interface class for which the implementation should be - * registered - */ - protected void registerRpc(T implementation, Class rpcInterfaceType) { - rpcManagerMap.put(rpcInterfaceType, new ServerRpcManager( - implementation, rpcInterfaceType)); - } - - /** - * Registers an RPC interface implementation for this component. - * - * A component can listen to multiple RPC interfaces, and subclasses can - * register additional implementations. - * - * @since 7.0 - * - * @param implementation - * RPC interface implementation. Also used to deduce the type. - */ - protected void registerRpc(T implementation) { - Class cls = implementation.getClass(); - Class[] interfaces = cls.getInterfaces(); - while (interfaces.length == 0) { - // Search upwards until an interface is found. It must be found as T - // extends ServerRpc - cls = cls.getSuperclass(); - interfaces = cls.getInterfaces(); - } - if (interfaces.length != 1 - || !(ServerRpc.class.isAssignableFrom(interfaces[0]))) { - throw new RuntimeException( - "Use registerRpc(T implementation, Class rpcInterfaceType) if the Rpc implementation implements more than one interface"); - } - Class type = (Class) interfaces[0]; - registerRpc(implementation, type); - } - - /** - * Returns an RPC proxy for a given server to client RPC interface for this - * component. - * - * TODO more javadoc, subclasses, ... - * - * @param rpcInterface - * RPC interface type - * - * @since 7.0 - */ - public T getRpcProxy(final Class rpcInterface) { - // create, initialize and return a dynamic proxy for RPC - try { - if (!rpcProxyMap.containsKey(rpcInterface)) { - Class proxyClass = (Class) Proxy.getProxyClass( - rpcInterface.getClassLoader(), rpcInterface); - Constructor constructor = proxyClass - .getConstructor(InvocationHandler.class); - T rpcProxy = constructor.newInstance(new RpcInvoicationHandler( - rpcInterface)); - // cache the proxy - rpcProxyMap.put(rpcInterface, rpcProxy); - } - return (T) rpcProxyMap.get(rpcInterface); - } catch (Exception e) { - // TODO exception handling? - throw new RuntimeException(e); - } - } - - private class RpcInvoicationHandler implements InvocationHandler, - Serializable { - - private String rpcInterfaceName; - - public RpcInvoicationHandler(Class rpcInterface) { - rpcInterfaceName = rpcInterface.getName().replaceAll("\\$", "."); - } - - public Object invoke(Object proxy, Method method, Object[] args) - throws Throwable { - addMethodInvocationToQueue(rpcInterfaceName, method, args); - // TODO no need to do full repaint if only RPC calls - requestRepaint(); - return null; - } - - } - - /** - * For internal use: adds a method invocation to the pending RPC call queue. - * - * @param interfaceName - * RPC interface name - * @param methodName - * RPC method name - * @param parameters - * RPC vall parameters - * - * @since 7.0 - */ - protected void addMethodInvocationToQueue(String interfaceName, - Method method, Object[] parameters) { - // add to queue - pendingInvocations.add(new ClientMethodInvocation(this, interfaceName, - method, parameters)); - } - - /** - * @see RpcTarget#getRpcManager(Class) - * - * @param rpcInterface - * RPC interface for which a call was made - * @return RPC Manager handling calls for the interface - * - * @since 7.0 - */ - public RpcManager getRpcManager(Class rpcInterface) { - return rpcManagerMap.get(rpcInterface); - } - - public List retrievePendingRpcCalls() { - if (pendingInvocations.isEmpty()) { - return Collections.emptyList(); - } else { - List result = pendingInvocations; - pendingInvocations = new ArrayList(); - return Collections.unmodifiableList(result); - } - } - - public String getConnectorId() { - if (connectorId == null) { - if (getApplication() == null) { - throw new RuntimeException( - "Component must be attached to an application when getConnectorId() is called for the first time"); - } - connectorId = getApplication().createConnectorId(this); - } - return connectorId; - } - - private Logger getLogger() { - return Logger.getLogger(AbstractComponent.class.getName()); - } } diff --git a/src/com/vaadin/ui/AbstractComponentContainer.java b/src/com/vaadin/ui/AbstractComponentContainer.java index 1c857a03cd..8ef458b704 100644 --- a/src/com/vaadin/ui/AbstractComponentContainer.java +++ b/src/com/vaadin/ui/AbstractComponentContainer.java @@ -71,36 +71,6 @@ public abstract class AbstractComponentContainer extends AbstractComponent } } - /** - * Notifies all contained components that the container is attached to a - * window. - * - * @see com.vaadin.ui.Component#attach() - */ - @Override - public void attach() { - super.attach(); - - for (final Iterator i = getComponentIterator(); i.hasNext();) { - (i.next()).attach(); - } - } - - /** - * Notifies all contained components that the container is detached from a - * window. - * - * @see com.vaadin.ui.Component#detach() - */ - @Override - public void detach() { - super.detach(); - - for (final Iterator i = getComponentIterator(); i.hasNext();) { - (i.next()).detach(); - } - } - /* Events */ private static final Method COMPONENT_ATTACHED_METHOD; @@ -355,46 +325,6 @@ public abstract class AbstractComponentContainer extends AbstractComponent true); } - public void requestRepaintAll() { - requestRepaintAll(this); - } - - /** - * Helper that implements the logic needed by requestRepaintAll. Calls - * requestRepaintAll/requestRepaint for the component container and all its - * children recursively. - * - * @param container - */ - public static void requestRepaintAll(HasComponents container) { - container.requestRepaint(); - if (container instanceof Panel) { - Panel p = (Panel) container; - // #2924 Panel is invalid, really invalid. - // Panel.getComponentIterator returns the children of content, not - // of Panel... - if (p.getContent() != null) { - p.getContent().requestRepaint(); - } - } - for (Iterator childIterator = container - .getComponentIterator(); childIterator.hasNext();) { - Component c = childIterator.next(); - if (c instanceof HasComponents) { - requestRepaintAll((HasComponents) c); - } else { - c.requestRepaint(); - } - } - } - - /** - * Returns an iterator for the child components. - * - * @return An iterator for the child components. - * @see #getComponentIterator() - * @since 7.0.0 - */ public Iterator iterator() { return getComponentIterator(); } diff --git a/src/com/vaadin/ui/Component.java b/src/com/vaadin/ui/Component.java index 3632c4ca5e..ce6df9854f 100644 --- a/src/com/vaadin/ui/Component.java +++ b/src/com/vaadin/ui/Component.java @@ -304,40 +304,9 @@ public interface Component extends ClientConnector, Sizeable, Serializable { *

* * @return the parent component - * @see #setParent(Component) */ public HasComponents getParent(); - /** - * Sets the parent component of the component. - * - *

- * This method automatically calls {@link #attach()} if the parent becomes - * attached to the application, regardless of whether it was attached - * previously. Conversely, if the parent is {@code null} and the component - * is attached to the application, {@link #detach()} is called for the - * component. - *

- *

- * This method is rarely called directly. The - * {@link ComponentContainer#addComponent(Component)} method is normally - * used for adding components to a container and it will call this method - * implicitly. - *

- * - *

- * It is not possible to change the parent without first setting the parent - * to {@code null}. - *

- * - * @param parent - * the parent component - * @throws IllegalStateException - * if a parent is given even though the component already has a - * parent - */ - public void setParent(HasComponents parent); - /** * Tests whether the component is in the read-only mode. The user can not * change the value of a read-only component. As only {@link Field} @@ -564,15 +533,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable { public Application getApplication(); /** - * Notifies the component that it is connected to an application. - * - *

- * The caller of this method is {@link #setParent(Component)} if the parent - * is itself already attached to the application. If not, the parent will - * call the {@link #attach()} for all its children when it is attached to - * the application. This method is always called before the component is - * painted for the first time. - *

+ * {@inheritDoc} * *

* Reimplementing the {@code attach()} method is useful for tasks that need @@ -624,37 +585,9 @@ public interface Component extends ClientConnector, Sizeable, Serializable { * } * } * - * - *

- * The attachment logic is implemented in {@link AbstractComponent}. - *

- * - * @see #getApplication() */ public void attach(); - /** - * Notifies the component that it is detached from the application. - * - *

- * The {@link #getApplication()} and {@link #getRoot()} methods might return - * null after this method is called. - *

- * - *

- * This method must call {@link Root#componentDetached(Component)} to let - * the Root know that a new Component has been attached. - *

- * * - *

- * The caller of this method is {@link #setParent(Component)} if the parent - * is in the application. When the parent is detached from the application - * it is its response to call {@link #detach()} for all the children and to - * detach itself from the terminal. - *

- */ - public void detach(); - /** * Gets the locale of the component. * @@ -719,75 +652,6 @@ public interface Component extends ClientConnector, Sizeable, Serializable { */ public String getDebugId(); - /** - * Requests that the component should be repainted as soon as possible. - */ - public void requestRepaint(); - - /** - * Repaint request event is thrown when the connector needs to be repainted. - * This is typically done when the paint method would return - * dissimilar UIDL from the previous call of the method. - */ - @SuppressWarnings("serial") - public static class RepaintRequestEvent extends EventObject { - - /** - * Constructs a new event. - * - * @param source - * the paintable needing repaint. - */ - public RepaintRequestEvent(ClientConnector source) { - super(source); - } - - /** - * Gets the connector needing repainting. - * - * @return Paintable for which the paint method will return - * dissimilar UIDL from the previous call of the method. - */ - public ClientConnector getConnector() { - return (ClientConnector) getSource(); - } - } - - /** - * Listens repaint requests. The repaintRequested method is - * called when the paintable needs to be repainted. This is typically done - * when the paint method would return dissimilar UIDL from the - * previous call of the method. - */ - public interface RepaintRequestListener extends Serializable { - - /** - * Receives repaint request events. - * - * @param event - * the repaint request event specifying the paintable source. - */ - public void repaintRequested(RepaintRequestEvent event); - } - - /** - * Adds repaint request listener. In order to assure that no repaint - * requests are missed, the new repaint listener should paint the paintable - * right after adding itself as listener. - * - * @param listener - * the listener to be added. - */ - public void addListener(RepaintRequestListener listener); - - /** - * Removes repaint request listener. - * - * @param listener - * the listener to be removed. - */ - public void removeListener(RepaintRequestListener listener); - /* Component event framework */ /** diff --git a/src/com/vaadin/ui/CssLayout.java b/src/com/vaadin/ui/CssLayout.java index 0a2656af31..e8ec6bd041 100644 --- a/src/com/vaadin/ui/CssLayout.java +++ b/src/com/vaadin/ui/CssLayout.java @@ -11,9 +11,9 @@ import com.vaadin.event.LayoutEvents.LayoutClickListener; import com.vaadin.event.LayoutEvents.LayoutClickNotifier; import com.vaadin.terminal.gwt.client.Connector; import com.vaadin.terminal.gwt.client.MouseEventDetails; +import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler; import com.vaadin.terminal.gwt.client.ui.csslayout.CssLayoutServerRpc; import com.vaadin.terminal.gwt.client.ui.csslayout.CssLayoutState; -import com.vaadin.terminal.gwt.client.ui.LayoutClickEventHandler; /** * CssLayout is a layout component that can be used in browser environment only. @@ -185,7 +185,8 @@ public class CssLayout extends AbstractLayout implements LayoutClickNotifier { public void updateState() { super.updateState(); getState().getChildCss().clear(); - for (Component child : this) { + for (Iterator ci = getComponentIterator(); ci.hasNext();) { + Component child = ci.next(); String componentCssString = getCss(child); if (componentCssString != null) { getState().getChildCss().put(child, componentCssString); diff --git a/src/com/vaadin/ui/CustomField.java b/src/com/vaadin/ui/CustomField.java index 806ee91335..269f24fb2c 100644 --- a/src/com/vaadin/ui/CustomField.java +++ b/src/com/vaadin/ui/CustomField.java @@ -63,11 +63,9 @@ public abstract class CustomField extends AbstractField implements @Override public void attach() { root = getContent(); - super.attach(); getContent().setParent(this); - getContent().attach(); - fireComponentAttachEvent(getContent()); + super.attach(); } /** @@ -79,7 +77,6 @@ public abstract class CustomField extends AbstractField implements @Override public void detach() { super.detach(); - getContent().detach(); } /** @@ -154,10 +151,6 @@ public abstract class CustomField extends AbstractField implements return (null != getContent()) ? 1 : 0; } - public void requestRepaintAll() { - AbstractComponentContainer.requestRepaintAll(this); - } - /** * Fires the component attached event. This should be called by the * addComponent methods after the component have been added to this diff --git a/src/com/vaadin/ui/DirtyConnectorTracker.java b/src/com/vaadin/ui/DirtyConnectorTracker.java index 84df7e7c7c..a4e509422c 100644 --- a/src/com/vaadin/ui/DirtyConnectorTracker.java +++ b/src/com/vaadin/ui/DirtyConnectorTracker.java @@ -9,10 +9,8 @@ import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; -import com.vaadin.terminal.gwt.server.AbstractCommunicationManager; +import com.vaadin.terminal.AbstractClientConnector; import com.vaadin.terminal.gwt.server.ClientConnector; -import com.vaadin.ui.Component.RepaintRequestEvent; -import com.vaadin.ui.Component.RepaintRequestListener; /** * A class that tracks dirty {@link ClientConnector}s. A {@link ClientConnector} @@ -25,8 +23,8 @@ import com.vaadin.ui.Component.RepaintRequestListener; * @since 7.0.0 * */ -public class DirtyConnectorTracker implements RepaintRequestListener { - private Set dirtyComponents = new HashSet(); +public class DirtyConnectorTracker { + private Set dirtyConnectors = new HashSet(); private Root root; /** @@ -43,90 +41,72 @@ public class DirtyConnectorTracker implements RepaintRequestListener { this.root = root; } - public void repaintRequested(RepaintRequestEvent event) { - markDirty((Component) event.getConnector()); - } - - public void componentAttached(Component component) { - component.addListener(this); - markDirty(component); - } - - private void markDirty(Component component) { + public void markDirty(ClientConnector connector) { if (getLogger().isLoggable(Level.FINE)) { - if (!dirtyComponents.contains(component)) { + if (!dirtyConnectors.contains(connector)) { getLogger() - .fine(getDebugInfo(component) + " " + "is now dirty"); + .fine(getDebugInfo(connector) + " " + "is now dirty"); } } - dirtyComponents.add(component); + dirtyConnectors.add(connector); } - private void markClean(Component component) { + public void markClean(ClientConnector connector) { if (getLogger().isLoggable(Level.FINE)) { - if (dirtyComponents.contains(component)) { + if (dirtyConnectors.contains(connector)) { getLogger().fine( - getDebugInfo(component) + " " + "is no longer dirty"); + getDebugInfo(connector) + " " + "is no longer dirty"); } } - dirtyComponents.remove(component); + dirtyConnectors.remove(connector); } - private String getDebugInfo(Component component) { - String message = getObjectString(component); - if (component.getParent() != null) { - message += " (parent: " + getObjectString(component.getParent()) + private String getDebugInfo(ClientConnector connector) { + String message = getObjectString(connector); + if (connector.getParent() != null) { + message += " (parent: " + getObjectString(connector.getParent()) + ")"; } return message; } - private String getObjectString(Object component) { - return component.getClass().getName() + "@" - + Integer.toHexString(component.hashCode()); + private String getObjectString(Object connector) { + return connector.getClass().getName() + "@" + + Integer.toHexString(connector.hashCode()); } - public void componentDetached(Component component) { - component.removeListener(this); - markClean(component); + public void markAllConnectorsDirty() { + markConnectorsDirtyRecursively(root); + getLogger().fine("All connectors are now dirty"); } - public void markAllComponentsDirty() { - markComponentsDirtyRecursively(root); - getLogger().fine("All components are now dirty"); - } - - public void markAllComponentsClean() { - dirtyComponents.clear(); - getLogger().fine("All components are now clean"); + public void markAllConnectorsClean() { + dirtyConnectors.clear(); + getLogger().fine("All connectors are now clean"); } /** - * Marks all visible components dirty, starting from the given component and + * Marks all visible connectors dirty, starting from the given connector and * going downwards in the hierarchy. * * @param c * The component to start iterating downwards from */ - private void markComponentsDirtyRecursively(Component c) { - if (!c.isVisible()) { + private void markConnectorsDirtyRecursively(ClientConnector c) { + if (c instanceof Component && !((Component) c).isVisible()) { return; } markDirty(c); - if (c instanceof HasComponents) { - HasComponents container = (HasComponents) c; - for (Component child : AbstractCommunicationManager - .getChildComponents(container)) { - markComponentsDirtyRecursively(child); - } + for (ClientConnector child : AbstractClientConnector + .getAllChildrenIteratable(c)) { + markConnectorsDirtyRecursively(child); } - } - public Collection getDirtyComponents() { - return dirtyComponents; + public Collection getDirtyConnectors() { + return dirtyConnectors; } } diff --git a/src/com/vaadin/ui/Form.java b/src/com/vaadin/ui/Form.java index 5f5516b21f..39b12e67e2 100644 --- a/src/com/vaadin/ui/Form.java +++ b/src/com/vaadin/ui/Form.java @@ -1411,10 +1411,6 @@ public class Form extends AbstractField implements Item.Editor, return new ComponentIterator(); } - public void requestRepaintAll() { - AbstractComponentContainer.requestRepaintAll(this); - } - public int getComponentCount() { int count = 0; if (getLayout() != null) { diff --git a/src/com/vaadin/ui/HasComponents.java b/src/com/vaadin/ui/HasComponents.java index eca89ddcd2..3ebd63bff2 100644 --- a/src/com/vaadin/ui/HasComponents.java +++ b/src/com/vaadin/ui/HasComponents.java @@ -21,7 +21,10 @@ public interface HasComponents extends Component, Iterable { * container. * * @return the component iterator. + * + * @deprecated Use {@link #iterator()} instead. */ + @Deprecated public Iterator getComponentIterator(); /** @@ -43,12 +46,4 @@ public interface HasComponents extends Component, Iterable { */ public boolean isComponentVisible(Component childComponent); - /** - * Causes a repaint of this component, and all components below it. - * - * This should only be used in special cases, e.g when the state of a - * descendant depends on the state of a ancestor. - */ - public void requestRepaintAll(); - } diff --git a/src/com/vaadin/ui/HelloWorldExtension.java b/src/com/vaadin/ui/HelloWorldExtension.java new file mode 100644 index 0000000000..6d9ce9bcf1 --- /dev/null +++ b/src/com/vaadin/ui/HelloWorldExtension.java @@ -0,0 +1,38 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.ui; + +import com.vaadin.terminal.AbstractExtension; +import com.vaadin.terminal.gwt.client.ui.helloworldfeature.GreetAgainRpc; +import com.vaadin.terminal.gwt.client.ui.helloworldfeature.HelloWorldRpc; +import com.vaadin.terminal.gwt.client.ui.helloworldfeature.HelloWorldState; + +public class HelloWorldExtension extends AbstractExtension { + + public HelloWorldExtension() { + registerRpc(new HelloWorldRpc() { + public void onMessageSent(String message) { + getRoot().showNotification(message); + } + }); + } + + @Override + public HelloWorldState getState() { + return (HelloWorldState) super.getState(); + } + + public void setGreeting(String greeting) { + getState().setGreeting(greeting); + requestRepaint(); + } + + public String getGreeting() { + return getState().getGreeting(); + } + + public void greetAgain() { + getRpcProxy(GreetAgainRpc.class).greetAgain(); + } +} diff --git a/src/com/vaadin/ui/Panel.java b/src/com/vaadin/ui/Panel.java index a0fd84bbef..37e03ffb37 100644 --- a/src/com/vaadin/ui/Panel.java +++ b/src/com/vaadin/ui/Panel.java @@ -193,15 +193,6 @@ public class Panel extends AbstractComponentContainer implements Scrollable, } } - @Override - public void requestRepaintAll() { - // Panel has odd structure, delegate to layout - requestRepaint(); - if (getContent() != null) { - getContent().requestRepaintAll(); - } - } - /** * Adds the component into this container. * @@ -354,35 +345,6 @@ public class Panel extends AbstractComponentContainer implements Scrollable, } } - /** - * Notifies the component that it is connected to an application. - * - * @see com.vaadin.ui.Component#attach() - */ - @Override - public void attach() { - getRoot().componentAttached(this); - // can't call parent here as this is Panels hierarchy is a hack - requestRepaint(); - if (content != null) { - content.attach(); - } - } - - /** - * Notifies the component that it is detached from the application. - * - * @see com.vaadin.ui.Component#detach() - */ - @Override - public void detach() { - // can't call parent here as this is Panels hierarchy is a hack - if (content != null) { - content.detach(); - } - getRoot().componentDetached(this); - } - /** * Removes all components from this container. * diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java index 9c3aef4152..0ba8ef27fb 100644 --- a/src/com/vaadin/ui/Root.java +++ b/src/com/vaadin/ui/Root.java @@ -1584,12 +1584,4 @@ public abstract class Root extends AbstractComponentContainer implements return dirtyConnectorTracker; } - public void componentAttached(Component component) { - getDirtyConnectorTracker().componentAttached(component); - } - - public void componentDetached(Component component) { - getDirtyConnectorTracker().componentDetached(component); - } - } diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index 299eace16d..e41c3d2a42 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -3705,13 +3705,6 @@ public class Table extends AbstractSelect implements Action.Container, super.attach(); refreshRenderedCells(); - - if (visibleComponents != null) { - for (final Iterator i = visibleComponents.iterator(); i - .hasNext();) { - i.next().attach(); - } - } } /** @@ -3722,13 +3715,6 @@ public class Table extends AbstractSelect implements Action.Container, @Override public void detach() { super.detach(); - - if (visibleComponents != null) { - for (final Iterator i = visibleComponents.iterator(); i - .hasNext();) { - i.next().detach(); - } - } } /** @@ -4453,10 +4439,6 @@ public class Table extends AbstractSelect implements Action.Container, } } - public void requestRepaintAll() { - AbstractComponentContainer.requestRepaintAll(this); - } - /** * Sets the drag start mode of the Table. Drag start mode controls how Table * behaves as a drag source. diff --git a/tests/server-side/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java b/tests/server-side/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java index b1c4a8f4be..1903e66f92 100644 --- a/tests/server-side/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java +++ b/tests/server-side/com/vaadin/tests/server/component/abstractcomponent/TestAbstractComponentStyleNames.java @@ -58,5 +58,4 @@ public class TestAbstractComponentStyleNames extends TestCase { return new AbstractComponent() { }; } - } diff --git a/tests/server-side/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java b/tests/server-side/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java index 0749dc299e..c6af98a873 100644 --- a/tests/server-side/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java +++ b/tests/server-side/com/vaadin/tests/server/component/textfield/TextFieldWithPropertyFormatter.java @@ -9,8 +9,6 @@ import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.util.ObjectProperty; import com.vaadin.data.util.PropertyFormatter; -import com.vaadin.ui.Component.RepaintRequestEvent; -import com.vaadin.ui.Component.RepaintRequestListener; import com.vaadin.ui.TextField; public class TextFieldWithPropertyFormatter extends TestCase { @@ -30,7 +28,13 @@ public class TextFieldWithPropertyFormatter extends TestCase { protected void setUp() throws Exception { super.setUp(); - field = new TextField(); + field = new TextField() { + @Override + public void requestRepaint() { + repainted++; + super.requestRepaint(); + } + }; formatter = new PropertyFormatter() { @@ -61,11 +65,6 @@ public class TextFieldWithPropertyFormatter extends TestCase { }; field.addListener(listener); - field.addListener(new RepaintRequestListener() { - public void repaintRequested(RepaintRequestEvent event) { - repainted++; - } - }); listenerCalled = 0; repainted = 0; } diff --git a/tests/testbench/com/vaadin/tests/features/HelloWorldFeatureTest.java b/tests/testbench/com/vaadin/tests/features/HelloWorldFeatureTest.java new file mode 100644 index 0000000000..3d26b92648 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/features/HelloWorldFeatureTest.java @@ -0,0 +1,38 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.tests.features; + +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.HelloWorldExtension; + +public class HelloWorldFeatureTest extends AbstractTestRoot { + + @Override + protected void setup(WrappedRequest request) { + final HelloWorldExtension extension = new HelloWorldExtension(); + extension.setGreeting("Kind words"); + addExtension(extension); + + addComponent(new Button("Greet again", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + extension.greetAgain(); + } + })); + } + + @Override + protected String getTestDescription() { + return "Testing basic Feature"; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} -- 2.39.5