summaryrefslogtreecommitdiffstats
path: root/server/src/com/vaadin/ui
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/com/vaadin/ui')
-rw-r--r--server/src/com/vaadin/ui/AbstractComponent.java22
-rw-r--r--server/src/com/vaadin/ui/AbstractEmbedded.java84
-rw-r--r--server/src/com/vaadin/ui/Button.java4
-rw-r--r--server/src/com/vaadin/ui/Component.java16
-rw-r--r--server/src/com/vaadin/ui/ConnectorTracker.java51
-rw-r--r--server/src/com/vaadin/ui/EmbeddedBrowser.java19
-rw-r--r--server/src/com/vaadin/ui/Flash.java136
-rw-r--r--server/src/com/vaadin/ui/Image.java94
-rw-r--r--server/src/com/vaadin/ui/LoginForm.java4
-rw-r--r--server/src/com/vaadin/ui/Select.java14
-rw-r--r--server/src/com/vaadin/ui/Slider.java172
-rw-r--r--server/src/com/vaadin/ui/UI.java (renamed from server/src/com/vaadin/ui/Root.java)388
-rw-r--r--server/src/com/vaadin/ui/Window.java28
13 files changed, 715 insertions, 317 deletions
diff --git a/server/src/com/vaadin/ui/AbstractComponent.java b/server/src/com/vaadin/ui/AbstractComponent.java
index b1393488f7..a52a07f266 100644
--- a/server/src/com/vaadin/ui/AbstractComponent.java
+++ b/server/src/com/vaadin/ui/AbstractComponent.java
@@ -557,16 +557,6 @@ public abstract class AbstractComponent extends AbstractClientConnector
}
/*
- * 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() {
- // Just make method from implemented Component interface public
- return super.getRoot();
- }
-
- /*
* Notify the component that it's attached to a window. Don't add a JavaDoc
* comment here, we use the default documentation from implemented
* interface.
@@ -588,9 +578,9 @@ public abstract class AbstractComponent extends AbstractClientConnector
public void detach() {
super.detach();
if (actionManager != null) {
- // Remove any existing viewer. Root cast is just to make the
+ // Remove any existing viewer. UI cast is just to make the
// compiler happy
- actionManager.setViewer((Root) null);
+ actionManager.setViewer((UI) null);
}
}
@@ -601,7 +591,7 @@ public abstract class AbstractComponent extends AbstractClientConnector
if (this instanceof Focusable) {
final Application app = getApplication();
if (app != null) {
- getRoot().setFocusedComponent((Focusable) this);
+ getUI().setFocusedComponent((Focusable) this);
delayedFocus = false;
} else {
delayedFocus = true;
@@ -1304,19 +1294,19 @@ public abstract class AbstractComponent extends AbstractClientConnector
/**
* Set a viewer for the action manager to be the parent sub window (if the
- * component is in a window) or the root (otherwise). This is still a
+ * component is in a window) or the UI (otherwise). This is still a
* simplification of the real case as this should be handled by the parent
* VOverlay (on the client side) if the component is inside an VOverlay
* component.
*/
private void setActionManagerViewer() {
- if (actionManager != null && getRoot() != null) {
+ if (actionManager != null && getUI() != null) {
// Attached and has action manager
Window w = findAncestor(Window.class);
if (w != null) {
actionManager.setViewer(w);
} else {
- actionManager.setViewer(getRoot());
+ actionManager.setViewer(getUI());
}
}
diff --git a/server/src/com/vaadin/ui/AbstractEmbedded.java b/server/src/com/vaadin/ui/AbstractEmbedded.java
new file mode 100644
index 0000000000..9396af5c44
--- /dev/null
+++ b/server/src/com/vaadin/ui/AbstractEmbedded.java
@@ -0,0 +1,84 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import com.vaadin.shared.ui.AbstractEmbeddedState;
+import com.vaadin.terminal.Resource;
+import com.vaadin.terminal.gwt.server.ResourceReference;
+
+/**
+ * Abstract base for embedding components.
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+@SuppressWarnings("serial")
+public abstract class AbstractEmbedded extends AbstractComponent {
+
+ @Override
+ public AbstractEmbeddedState getState() {
+ return (AbstractEmbeddedState) super.getState();
+ }
+
+ /**
+ * Sets the object source resource. The dimensions are assumed if possible.
+ * The type is guessed from resource.
+ *
+ * @param source
+ * the source to set.
+ */
+ public void setSource(Resource source) {
+ if (source == null) {
+ getState().setSource(null);
+ } else {
+ getState().setSource(new ResourceReference(source));
+ }
+ requestRepaint();
+ }
+
+ /**
+ * Get the object source resource.
+ *
+ * @return the source
+ */
+ public Resource getSource() {
+ ResourceReference ref = ((ResourceReference) getState().getSource());
+ if (ref == null) {
+ return null;
+ } else {
+ return ref.getResource();
+ }
+ }
+
+ /**
+ * Sets this component's alternate text that can be presented instead of the
+ * component's normal content for accessibility purposes.
+ *
+ * @param altText
+ * A short, human-readable description of this component's
+ * content.
+ */
+ public void setAlternateText(String altText) {
+ if (altText != getState().getAlternateText()
+ || (altText != null && !altText.equals(getState()
+ .getAlternateText()))) {
+ getState().setAlternateText(altText);
+ requestRepaint();
+ }
+ }
+
+ /**
+ * Gets this component's alternate text that can be presented instead of the
+ * component's normal content for accessibility purposes.
+ *
+ * @returns Alternate text
+ */
+ public String getAlternateText() {
+ return getState().getAlternateText();
+ }
+
+}
diff --git a/server/src/com/vaadin/ui/Button.java b/server/src/com/vaadin/ui/Button.java
index 8546d8f830..68b9f1392f 100644
--- a/server/src/com/vaadin/ui/Button.java
+++ b/server/src/com/vaadin/ui/Button.java
@@ -472,6 +472,10 @@ public class Button extends AbstractComponent implements
* Determines if a button is automatically disabled when clicked. If this is
* set to true the button will be automatically disabled when clicked,
* typically to prevent (accidental) extra clicks on a button.
+ * <p>
+ * Note that this is only used when the click comes from the user, not when
+ * calling {@link #click()}.
+ * </p>
*
* @param disableOnClick
* true to disable button when it is clicked, false otherwise
diff --git a/server/src/com/vaadin/ui/Component.java b/server/src/com/vaadin/ui/Component.java
index 89e282d4e1..400dd66cac 100644
--- a/server/src/com/vaadin/ui/Component.java
+++ b/server/src/com/vaadin/ui/Component.java
@@ -507,18 +507,18 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
public void setIcon(Resource icon);
/**
- * Gets the Root the component is attached to.
+ * Gets the UI the component is attached to.
*
* <p>
- * If the component is not attached to a Root through a component
+ * If the component is not attached to a UI through a component
* containment hierarchy, <code>null</code> is returned.
* </p>
*
- * @return the Root of the component or <code>null</code> if it is not
- * attached to a Root
+ * @return the UI of the component or <code>null</code> if it is not
+ * attached to a UI
*/
@Override
- public Root getRoot();
+ public UI getUI();
/**
* Gets the application object to which the component is attached.
@@ -548,7 +548,7 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
* <p>
* Reimplementing the {@code attach()} method is useful for tasks that need
* to get a reference to the parent, window, or application object with the
- * {@link #getParent()}, {@link #getRoot()}, and {@link #getApplication()}
+ * {@link #getParent()}, {@link #getUI()}, and {@link #getApplication()}
* methods. A component does not yet know these objects in the constructor,
* so in such case, the methods will return {@code null}. For example, the
* following is invalid:
@@ -574,8 +574,8 @@ public interface Component extends ClientConnector, Sizeable, Serializable {
* {@link #setParent(Component)}.
* </p>
* <p>
- * This method must call {@link Root#componentAttached(Component)} to let
- * the Root know that a new Component has been attached.
+ * This method must call {@link UI#componentAttached(Component)} to let
+ * the UI know that a new Component has been attached.
* </p>
*
*
diff --git a/server/src/com/vaadin/ui/ConnectorTracker.java b/server/src/com/vaadin/ui/ConnectorTracker.java
index 72879e0a25..b44189f838 100644
--- a/server/src/com/vaadin/ui/ConnectorTracker.java
+++ b/server/src/com/vaadin/ui/ConnectorTracker.java
@@ -26,11 +26,12 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import com.vaadin.terminal.AbstractClientConnector;
+import com.vaadin.terminal.gwt.server.AbstractCommunicationManager;
import com.vaadin.terminal.gwt.server.ClientConnector;
/**
* A class which takes care of book keeping of {@link ClientConnector}s for a
- * Root.
+ * UI.
* <p>
* Provides {@link #getConnector(String)} which can be used to lookup a
* connector from its id. This is for framework use only and should not be
@@ -54,7 +55,7 @@ public class ConnectorTracker implements Serializable {
private Set<ClientConnector> dirtyConnectors = new HashSet<ClientConnector>();
private Set<ClientConnector> uninitializedConnectors = new HashSet<ClientConnector>();
- private Root root;
+ private UI uI;
private Map<ClientConnector, Object> diffStates = new HashMap<ClientConnector, Object>();
/**
@@ -68,15 +69,15 @@ public class ConnectorTracker implements Serializable {
}
/**
- * Creates a new ConnectorTracker for the given root. A tracker is always
- * attached to a root and the root cannot be changed during the lifetime of
- * a {@link ConnectorTracker}.
+ * Creates a new ConnectorTracker for the given uI. A tracker is always
+ * attached to a uI and the uI cannot be changed during the lifetime of a
+ * {@link ConnectorTracker}.
*
- * @param root
- * The root to attach to. Cannot be null.
+ * @param uI
+ * The uI to attach to. Cannot be null.
*/
- public ConnectorTracker(Root root) {
- this.root = root;
+ public ConnectorTracker(UI uI) {
+ this.uI = uI;
}
/**
@@ -210,8 +211,8 @@ public class ConnectorTracker implements Serializable {
while (iterator.hasNext()) {
String connectorId = iterator.next();
ClientConnector connector = connectorIdToConnector.get(connectorId);
- if (getRootForConnector(connector) != root) {
- // If connector is no longer part of this root,
+ if (getUIForConnector(connector) != uI) {
+ // If connector is no longer part of this uI,
// remove it from the map. If it is re-attached to the
// application at some point it will be re-added through
// registerConnector(connector)
@@ -226,28 +227,36 @@ public class ConnectorTracker implements Serializable {
uninitializedConnectors.remove(connector);
diffStates.remove(connector);
iterator.remove();
+ } else if (!AbstractCommunicationManager.isVisible(connector)
+ && !uninitializedConnectors.contains(connector)) {
+ uninitializedConnectors.add(connector);
+ diffStates.remove(connector);
+ getLogger().fine(
+ "cleanConnectorMap removed state for "
+ + getConnectorAndParentInfo(connector)
+ + " as it is not visible");
}
}
}
/**
- * Finds the root that the connector is attached to.
+ * Finds the uI that the connector is attached to.
*
* @param connector
* The connector to lookup
- * @return The root the connector is attached to or null if it is not
- * attached to any root.
+ * @return The uI the connector is attached to or null if it is not attached
+ * to any uI.
*/
- private Root getRootForConnector(ClientConnector connector) {
+ private UI getUIForConnector(ClientConnector connector) {
if (connector == null) {
return null;
}
if (connector instanceof Component) {
- return ((Component) connector).getRoot();
+ return ((Component) connector).getUI();
}
- return getRootForConnector(connector.getParent());
+ return getUIForConnector(connector.getParent());
}
/**
@@ -330,15 +339,15 @@ public class ConnectorTracker implements Serializable {
}
/**
- * Mark all connectors in this root as dirty.
+ * Mark all connectors in this uI as dirty.
*/
public void markAllConnectorsDirty() {
- markConnectorsDirtyRecursively(root);
+ markConnectorsDirtyRecursively(uI);
getLogger().fine("All connectors are now dirty");
}
/**
- * Mark all connectors in this root as clean.
+ * Mark all connectors in this uI as clean.
*/
public void markAllConnectorsClean() {
dirtyConnectors.clear();
@@ -370,7 +379,7 @@ public class ConnectorTracker implements Serializable {
* client in the following request.
* </p>
*
- * @return A collection of all dirty connectors for this root. This list may
+ * @return A collection of all dirty connectors for this uI. This list may
* contain invisible connectors.
*/
public Collection<ClientConnector> getDirtyConnectors() {
diff --git a/server/src/com/vaadin/ui/EmbeddedBrowser.java b/server/src/com/vaadin/ui/EmbeddedBrowser.java
new file mode 100644
index 0000000000..4e2ae18de8
--- /dev/null
+++ b/server/src/com/vaadin/ui/EmbeddedBrowser.java
@@ -0,0 +1,19 @@
+package com.vaadin.ui;
+
+import com.vaadin.shared.ui.embeddedbrowser.EmbeddedBrowserState;
+
+/**
+ * Component for embedding browser "iframe".
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+public class EmbeddedBrowser extends AbstractEmbedded {
+
+ @Override
+ public EmbeddedBrowserState getState() {
+ return (EmbeddedBrowserState) super.getState();
+ }
+}
diff --git a/server/src/com/vaadin/ui/Flash.java b/server/src/com/vaadin/ui/Flash.java
new file mode 100644
index 0000000000..0e6cf63a91
--- /dev/null
+++ b/server/src/com/vaadin/ui/Flash.java
@@ -0,0 +1,136 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import java.util.HashMap;
+
+import com.vaadin.shared.ui.flash.FlashState;
+
+/**
+ * Component for embedding flash objects.
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+@SuppressWarnings("serial")
+public class Flash extends AbstractEmbedded {
+
+ @Override
+ public FlashState getState() {
+ return (FlashState) super.getState();
+ }
+
+ /**
+ * This attribute specifies the base path used to resolve relative URIs
+ * specified by the classid, data, and archive attributes. When absent, its
+ * default value is the base URI of the current document.
+ *
+ * @param codebase
+ * The base path
+ */
+ public void setCodebase(String codebase) {
+ if (codebase != getState().getCodebase()
+ || (codebase != null && !codebase.equals(getState()
+ .getCodebase()))) {
+ getState().setCodebase(codebase);
+ requestRepaint();
+ }
+ }
+
+ /**
+ * This attribute specifies the content type of data expected when
+ * downloading the object specified by classid. This attribute is optional
+ * but recommended when classid is specified since it allows the user agent
+ * to avoid loading information for unsupported content types. When absent,
+ * it defaults to the value of the type attribute.
+ *
+ * @param codetype
+ * the codetype to set.
+ */
+ public void setCodetype(String codetype) {
+ if (codetype != getState().getCodetype()
+ || (codetype != null && !codetype.equals(getState()
+ .getCodetype()))) {
+ getState().setCodetype(codetype);
+ requestRepaint();
+ }
+ }
+
+ /**
+ * This attribute may be used to specify a space-separated list of URIs for
+ * archives containing resources relevant to the object, which may include
+ * the resources specified by the classid and data attributes. Preloading
+ * archives will generally result in reduced load times for objects.
+ * Archives specified as relative URIs should be interpreted relative to the
+ * codebase attribute.
+ *
+ * @param archive
+ * Space-separated list of URIs with resources relevant to the
+ * object
+ */
+ public void setArchive(String archive) {
+ if (archive != getState().getArchive()
+ || (archive != null && !archive.equals(getState().getArchive()))) {
+ getState().setArchive(archive);
+ requestRepaint();
+ }
+ }
+
+ public void setStandby(String standby) {
+ if (standby != getState().getStandby()
+ || (standby != null && !standby.equals(getState().getStandby()))) {
+ getState().setStandby(standby);
+ requestRepaint();
+ }
+ }
+
+ /**
+ * Sets an object parameter. Parameters are optional information, and they
+ * are passed to the instantiated object. Parameters are are stored as name
+ * value pairs. This overrides the previous value assigned to this
+ * parameter.
+ *
+ * @param name
+ * the name of the parameter.
+ * @param value
+ * the value of the parameter.
+ */
+ public void setParameter(String name, String value) {
+ if (getState().getEmbedParams() == null) {
+ getState().setEmbedParams(new HashMap<String, String>());
+ }
+ getState().getEmbedParams().put(name, value);
+ requestRepaint();
+ }
+
+ /**
+ * Gets the value of an object parameter. Parameters are optional
+ * information, and they are passed to the instantiated object. Parameters
+ * are are stored as name value pairs.
+ *
+ * @return the Value of parameter or null if not found.
+ */
+ public String getParameter(String name) {
+ return getState().getEmbedParams() != null ? getState()
+ .getEmbedParams().get(name) : null;
+ }
+
+ /**
+ * Removes an object parameter from the list.
+ *
+ * @param name
+ * the name of the parameter to remove.
+ */
+ public void removeParameter(String name) {
+ if (getState().getEmbedParams() == null) {
+ return;
+ }
+ getState().getEmbedParams().remove(name);
+ requestRepaint();
+ }
+
+}
diff --git a/server/src/com/vaadin/ui/Image.java b/server/src/com/vaadin/ui/Image.java
new file mode 100644
index 0000000000..b0dbc9e629
--- /dev/null
+++ b/server/src/com/vaadin/ui/Image.java
@@ -0,0 +1,94 @@
+/*
+@VaadinApache2LicenseForJavaFiles@
+ */
+
+package com.vaadin.ui;
+
+import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.event.MouseEvents.ClickListener;
+import com.vaadin.shared.EventId;
+import com.vaadin.shared.MouseEventDetails;
+import com.vaadin.shared.ui.image.ImageServerRpc;
+import com.vaadin.shared.ui.image.ImageState;
+import com.vaadin.terminal.Resource;
+
+/**
+ * Component for embedding images.
+ *
+ * @author Vaadin Ltd.
+ * @version
+ * @VERSION@
+ * @since 7.0
+ */
+@SuppressWarnings("serial")
+public class Image extends AbstractEmbedded {
+
+ protected ImageServerRpc rpc = new ImageServerRpc() {
+ @Override
+ public void click(MouseEventDetails mouseDetails) {
+ fireEvent(new ClickEvent(Image.this, mouseDetails));
+ }
+ };
+
+ /**
+ * Creates a new empty Image.
+ */
+ public Image() {
+ registerRpc(rpc);
+ }
+
+ /**
+ * Creates a new empty Image with caption.
+ *
+ * @param caption
+ */
+ public Image(String caption) {
+ this();
+ setCaption(caption);
+ }
+
+ /**
+ * Creates a new Image whose contents is loaded from given resource. The
+ * dimensions are assumed if possible. The type is guessed from resource.
+ *
+ * @param caption
+ * @param source
+ * the Source of the embedded object.
+ */
+ public Image(String caption, Resource source) {
+ this(caption);
+ setSource(source);
+ }
+
+ @Override
+ public ImageState getState() {
+ return (ImageState) super.getState();
+ }
+
+ /**
+ * Add a click listener to the component. The listener is called whenever
+ * the user clicks inside the component. Depending on the content the event
+ * may be blocked and in that case no event is fired.
+ *
+ * Use {@link #removeListener(ClickListener)} to remove the listener.
+ *
+ * @param listener
+ * The listener to add
+ */
+ public void addListener(ClickListener listener) {
+ addListener(EventId.CLICK_EVENT_IDENTIFIER, ClickEvent.class, listener,
+ ClickListener.clickMethod);
+ }
+
+ /**
+ * Remove a click listener from the component. The listener should earlier
+ * have been added using {@link #addListener(ClickListener)}.
+ *
+ * @param listener
+ * The listener to remove
+ */
+ public void removeListener(ClickListener listener) {
+ removeListener(EventId.CLICK_EVENT_IDENTIFIER, ClickEvent.class,
+ listener);
+ }
+}
diff --git a/server/src/com/vaadin/ui/LoginForm.java b/server/src/com/vaadin/ui/LoginForm.java
index bb7767084c..1c154699d8 100644
--- a/server/src/com/vaadin/ui/LoginForm.java
+++ b/server/src/com/vaadin/ui/LoginForm.java
@@ -99,8 +99,8 @@ public class LoginForm extends CustomComponent {
throws IOException {
String requestPathInfo = request.getRequestPathInfo();
if ("/loginHandler".equals(requestPathInfo)) {
- // Ensure Root.getCurrent() works in listeners
- Root.setCurrent(getRoot());
+ // Ensure UI.getCurrent() works in listeners
+ UI.setCurrent(getUI());
response.setCacheTime(-1);
response.setContentType("text/html; charset=utf-8");
diff --git a/server/src/com/vaadin/ui/Select.java b/server/src/com/vaadin/ui/Select.java
index 20345b55e0..6ff7c9c9bc 100644
--- a/server/src/com/vaadin/ui/Select.java
+++ b/server/src/com/vaadin/ui/Select.java
@@ -654,7 +654,7 @@ public class Select extends AbstractSelect implements AbstractSelect.Filtering,
if (filterstring != null) {
filterstring = filterstring.toLowerCase();
}
- optionRepaint();
+ requestRepaint();
} else if (isNewItemsAllowed()) {
// New option entered (and it is allowed)
final String newitem = (String) variables.get("newitem");
@@ -682,18 +682,6 @@ public class Select extends AbstractSelect implements AbstractSelect.Filtering,
}
@Override
- public void markAsDirty() {
- super.markAsDirty();
- optionRequest = false;
- prevfilterstring = filterstring;
- filterstring = null;
- }
-
- private void optionRepaint() {
- super.markAsDirty();
- }
-
- @Override
public void setFilteringMode(int filteringMode) {
this.filteringMode = filteringMode;
}
diff --git a/server/src/com/vaadin/ui/Slider.java b/server/src/com/vaadin/ui/Slider.java
index d4e2db4853..a0b1d01b01 100644
--- a/server/src/com/vaadin/ui/Slider.java
+++ b/server/src/com/vaadin/ui/Slider.java
@@ -16,11 +16,9 @@
package com.vaadin.ui;
-import java.util.Map;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.Vaadin6Component;
+import com.vaadin.shared.ui.slider.SliderOrientation;
+import com.vaadin.shared.ui.slider.SliderServerRpc;
+import com.vaadin.shared.ui.slider.SliderState;
/**
* A component for selecting a numerical value within a range.
@@ -41,9 +39,9 @@ import com.vaadin.terminal.Vaadin6Component;
* vl.addComponent(volumeIndicator);
* volumeIndicator.setValue("Current volume:" + 50.0);
* slider.addListener(this);
- *
+ *
* }
- *
+ *
* public void setVolume(double d) {
* volumeIndicator.setValue("Current volume: " + d);
* }
@@ -58,28 +56,29 @@ import com.vaadin.terminal.Vaadin6Component;
*
* @author Vaadin Ltd.
*/
-public class Slider extends AbstractField<Double> implements Vaadin6Component {
-
- public static final int ORIENTATION_HORIZONTAL = 0;
-
- public static final int ORIENTATION_VERTICAL = 1;
+public class Slider extends AbstractField<Double> {
- /** Minimum value of slider */
- private double min = 0;
+ private SliderServerRpc rpc = new SliderServerRpc() {
- /** Maximum value of slider */
- private double max = 100;
+ @Override
+ public void valueChanged(double value) {
- /**
- * Resolution, how many digits are considered relevant after the decimal
- * point. Must be a non-negative value
- */
- private int resolution = 0;
+ try {
+ setValue(value, true);
+ } catch (final ValueOutOfBoundsException e) {
+ // Convert to nearest bound
+ double out = e.getValue().doubleValue();
+ if (out < getState().getMinValue()) {
+ out = getState().getMinValue();
+ }
+ if (out > getState().getMaxValue()) {
+ out = getState().getMaxValue();
+ }
+ Slider.super.setValue(new Double(out), false);
+ }
+ }
- /**
- * Slider orientation (horizontal/vertical), defaults .
- */
- private int orientation = ORIENTATION_HORIZONTAL;
+ };
/**
* Default slider constructor. Sets all values to defaults and the slide
@@ -88,7 +87,8 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
*/
public Slider() {
super();
- super.setValue(new Double(min));
+ registerRpc(rpc);
+ super.setValue(new Double(getState().getMinValue()));
}
/**
@@ -153,13 +153,18 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
setCaption(caption);
}
+ @Override
+ public SliderState getState() {
+ return (SliderState) super.getState();
+ }
+
/**
* Gets the maximum slider value
*
* @return the largest value the slider can have
*/
public double getMax() {
- return max;
+ return getState().getMaxValue();
}
/**
@@ -170,11 +175,10 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
* The new maximum slider value
*/
public void setMax(double max) {
- this.max = max;
+ getState().setMaxValue(max);
if (getValue() > max) {
setValue(max);
}
- markAsDirty();
}
/**
@@ -183,7 +187,7 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
* @return the smallest value the slider can have
*/
public double getMin() {
- return min;
+ return getState().getMinValue();
}
/**
@@ -194,33 +198,32 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
* The new minimum slider value
*/
public void setMin(double min) {
- this.min = min;
+ getState().setMinValue(min);
if (getValue() < min) {
setValue(min);
}
- markAsDirty();
}
/**
* Get the current orientation of the slider (horizontal or vertical).
*
- * @return {@link #ORIENTATION_HORIZONTAL} or
- * {@link #ORIENTATION_HORIZONTAL}
+ * @return {@link SliderOrientation#HORIZONTAL} or
+ * {@link SliderOrientation#VERTICAL}
*/
- public int getOrientation() {
- return orientation;
+ public SliderOrientation getOrientation() {
+ return getState().getOrientation();
}
/**
* Set the orientation of the slider.
*
- * @param The
- * new orientation, either {@link #ORIENTATION_HORIZONTAL} or
- * {@link #ORIENTATION_VERTICAL}
+ * @param orientation
+ * The new orientation, either
+ * {@link SliderOrientation#HORIZONTAL} or
+ * {@link SliderOrientation#VERTICAL}
*/
- public void setOrientation(int orientation) {
- this.orientation = orientation;
- markAsDirty();
+ public void setOrientation(SliderOrientation orientation) {
+ getState().setOrientation(orientation);
}
/**
@@ -230,21 +233,24 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
* @return resolution
*/
public int getResolution() {
- return resolution;
+ return getState().getResolution();
}
/**
* Set a new resolution for the slider. The resolution is the number of
* digits after the decimal point.
*
+ * @throws IllegalArgumentException
+ * if resolution is negative.
+ *
* @param resolution
*/
public void setResolution(int resolution) {
if (resolution < 0) {
- return;
+ throw new IllegalArgumentException(
+ "Cannot set a negative resolution to Slider");
}
- this.resolution = resolution;
- markAsDirty();
+ getState().setResolution(resolution);
}
/**
@@ -261,87 +267,36 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
@Override
protected void setValue(Double value, boolean repaintIsNotNeeded) {
final double v = value.doubleValue();
+ final int resolution = getResolution();
double newValue;
+
if (resolution > 0) {
// Round up to resolution
newValue = (int) (v * Math.pow(10, resolution));
newValue = newValue / Math.pow(10, resolution);
- if (min > newValue || max < newValue) {
+ if (getMin() > newValue || getMax() < newValue) {
throw new ValueOutOfBoundsException(value);
}
} else {
newValue = (int) v;
- if (min > newValue || max < newValue) {
+ if (getMin() > newValue || getMax() < newValue) {
throw new ValueOutOfBoundsException(value);
}
}
+
+ getState().setValue(newValue);
super.setValue(newValue, repaintIsNotNeeded);
}
@Override
- public void setValue(Object newFieldValue)
- throws com.vaadin.data.Property.ReadOnlyException {
- if (newFieldValue != null && newFieldValue instanceof Number
- && !(newFieldValue instanceof Double)) {
+ public void setValue(Object newFieldValue) {
+ if (newFieldValue instanceof Number) {
// Support setting all types of Numbers
newFieldValue = ((Number) newFieldValue).doubleValue();
}
-
- super.setValue(newFieldValue);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
-
- target.addAttribute("min", min);
- if (max > min) {
- target.addAttribute("max", max);
- } else {
- target.addAttribute("max", min);
- }
- target.addAttribute("resolution", resolution);
-
- if (resolution > 0) {
- target.addVariable(this, "value", getValue().doubleValue());
- } else {
- target.addVariable(this, "value", getValue().intValue());
- }
-
- if (orientation == ORIENTATION_VERTICAL) {
- target.addAttribute("vertical", true);
- }
-
- }
-
- /**
- * Invoked when the value of a variable has changed. Slider listeners are
- * notified if the slider value has changed.
- *
- * @param source
- * @param variables
- */
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- if (variables.containsKey("value")) {
- final Object value = variables.get("value");
- final Double newValue = new Double(value.toString());
- if (newValue != null && newValue != getValue()
- && !newValue.equals(getValue())) {
- try {
- setValue(newValue, true);
- } catch (final ValueOutOfBoundsException e) {
- // Convert to nearest bound
- double out = e.getValue().doubleValue();
- if (out < min) {
- out = min;
- }
- if (out > max) {
- out = max;
- }
- super.setValue(new Double(out), false);
- }
- }
- }
+ setValue(newFieldValue);
+ // The cast is safe if the above call returned without throwing
+ getState().setValue((Double) newFieldValue);
}
/**
@@ -373,7 +328,6 @@ public class Slider extends AbstractField<Double> implements Vaadin6Component {
public Double getValue() {
return value;
}
-
}
@Override
diff --git a/server/src/com/vaadin/ui/Root.java b/server/src/com/vaadin/ui/UI.java
index 67f2e04a65..17a028bcdf 100644
--- a/server/src/com/vaadin/ui/Root.java
+++ b/server/src/com/vaadin/ui/UI.java
@@ -16,11 +16,13 @@
package com.vaadin.ui;
+import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.EventListener;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
@@ -35,9 +37,9 @@ import com.vaadin.event.MouseEvents.ClickListener;
import com.vaadin.shared.EventId;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.ui.BorderStyle;
-import com.vaadin.shared.ui.root.RootConstants;
-import com.vaadin.shared.ui.root.RootServerRpc;
-import com.vaadin.shared.ui.root.RootState;
+import com.vaadin.shared.ui.ui.UIConstants;
+import com.vaadin.shared.ui.ui.UIServerRpc;
+import com.vaadin.shared.ui.ui.UIState;
import com.vaadin.terminal.Page;
import com.vaadin.terminal.Page.BrowserWindowResizeEvent;
import com.vaadin.terminal.Page.BrowserWindowResizeListener;
@@ -47,27 +49,28 @@ import com.vaadin.terminal.Resource;
import com.vaadin.terminal.Vaadin6Component;
import com.vaadin.terminal.WrappedRequest;
import com.vaadin.terminal.WrappedRequest.BrowserDetails;
-import com.vaadin.ui.Window.CloseListener;
+import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
+import com.vaadin.tools.ReflectTools;
/**
- * The topmost component in any component hierarchy. There is one root for every
- * Vaadin instance in a browser window. A root may either represent an entire
+ * The topmost component in any component hierarchy. There is one UI for every
+ * Vaadin instance in a browser window. A UI may either represent an entire
* browser window (or tab) or some part of a html page where a Vaadin
* application is embedded.
* <p>
- * The root is the server side entry point for various client side features that
+ * The UI is the server side entry point for various client side features that
* are not represented as components added to a layout, e.g notifications, sub
* windows, and executing javascript in the browser.
* </p>
* <p>
- * When a new application instance is needed, typically because the user opens
- * the application in a browser window,
- * {@link Application#gerRoot(WrappedRequest)} is invoked to get a root. That
- * method does by default create a root according to the
- * {@value Application#ROOT_PARAMETER} parameter from web.xml.
+ * When a new UI instance is needed, typically because the user opens a URL in a
+ * browser window which points to {@link AbstractApplicationServlet},
+ * {@link Application#getUIForRequest(WrappedRequest)} is invoked to get a UI.
+ * That method does by default create a UI according to the
+ * {@value Application#UI_PARAMETER} parameter from web.xml.
* </p>
* <p>
- * After a root has been created by the application, it is initialized using
+ * After a UI has been created by the application, it is initialized using
* {@link #init(WrappedRequest)}. This method is intended to be overridden by
* the developer to add components to the user interface and initialize
* non-component functionality. The component hierarchy is initialized by
@@ -76,27 +79,27 @@ import com.vaadin.ui.Window.CloseListener;
* </p>
* <p>
* If a {@link EagerInit} annotation is present on a class extending
- * <code>Root</code>, the framework will use a faster initialization method
- * which will not ensure that {@link BrowserDetails} are present in the
+ * <code>UI</code>, the framework will use a faster initialization method which
+ * will not ensure that {@link BrowserDetails} are present in the
* {@link WrappedRequest} passed to the init method.
* </p>
*
* @see #init(WrappedRequest)
- * @see Application#getRoot(WrappedRequest)
+ * @see Application#getUI(WrappedRequest)
*
* @since 7.0
*/
-public abstract class Root extends AbstractComponentContainer implements
+public abstract class UI extends AbstractComponentContainer implements
Action.Container, Action.Notifier, Vaadin6Component {
/**
- * Helper class to emulate the main window from Vaadin 6 using roots. This
+ * Helper class to emulate the main window from Vaadin 6 using UIs. This
* class should be used in the same way as Window used as a browser level
* window in Vaadin 6 with {@link com.vaadin.Application.LegacyApplication}
*/
@Deprecated
@EagerInit
- public static class LegacyWindow extends Root {
+ public static class LegacyWindow extends UI {
private String name;
/**
@@ -210,11 +213,11 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Opens the given resource in this root. The contents of this Root is
+ * Opens the given resource in this UI. The contents of this UI is
* replaced by the {@code Resource}.
*
* @param resource
- * the resource to show in this root
+ * the resource to show in this UI
*
* @deprecated As of 7.0, use getPage().open instead
*/
@@ -294,9 +297,9 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Adds a new {@link BrowserWindowResizeListener} to this root. The
+ * Adds a new {@link BrowserWindowResizeListener} to this UI. The
* listener will be notified whenever the browser window within which
- * this root resides is resized.
+ * this UI resides is resized.
*
* @param resizeListener
* the listener to add
@@ -312,7 +315,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Removes a {@link BrowserWindowResizeListener} from this root. The
+ * Removes a {@link BrowserWindowResizeListener} from this UI. The
* listener will no longer be notified when the browser window is
* resized.
*
@@ -326,7 +329,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Gets the last known height of the browser window in which this root
+ * Gets the last known height of the browser window in which this UI
* resides.
*
* @return the browser window height in pixels
@@ -338,7 +341,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Gets the last known width of the browser window in which this root
+ * Gets the last known width of the browser window in which this UI
* resides.
*
* @return the browser window width in pixels
@@ -389,12 +392,48 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * The application to which this root belongs
+ * Event fired when a UI is removed from the application.
+ */
+ public static class CloseEvent extends Event {
+
+ private static final String CLOSE_EVENT_IDENTIFIER = "uiClose";
+
+ public CloseEvent(UI source) {
+ super(source);
+ }
+
+ public UI getUI() {
+ return (UI) getSource();
+ }
+ }
+
+ /**
+ * Interface for listening {@link UI.CloseEvent UI close events}.
+ *
+ */
+ public interface CloseListener extends EventListener {
+
+ public static final Method closeMethod = ReflectTools.findMethod(
+ CloseListener.class, "click", CloseEvent.class);
+
+ /**
+ * Called when a CloseListener is notified of a CloseEvent.
+ * {@link UI#getCurrent()} returns <code>event.getUI()</code> within
+ * this method.
+ *
+ * @param event
+ * The close event that was fired.
+ */
+ public void close(CloseEvent event);
+ }
+
+ /**
+ * The application to which this UI belongs
*/
private Application application;
/**
- * List of windows in this root.
+ * List of windows in this UI.
*/
private final LinkedHashSet<Window> windows = new LinkedHashSet<Window>();
@@ -405,13 +444,13 @@ public abstract class Root extends AbstractComponentContainer implements
private Component scrollIntoView;
/**
- * The id of this root, used to find the server side instance of the root
- * form which a request originates. A negative value indicates that the root
- * id has not yet been assigned by the Application.
+ * The id of this UI, used to find the server side instance of the UI form
+ * which a request originates. A negative value indicates that the UI id has
+ * not yet been assigned by the Application.
*
- * @see Application#nextRootId
+ * @see Application#nextUIId
*/
- private int rootId = -1;
+ private int uiId = -1;
/**
* Keeps track of the Actions added to this component, and manages the
@@ -420,19 +459,19 @@ public abstract class Root extends AbstractComponentContainer implements
protected ActionManager actionManager;
/**
- * Thread local for keeping track of the current root.
+ * Thread local for keeping track of the current UI.
*/
- private static final ThreadLocal<Root> currentRoot = new ThreadLocal<Root>();
+ private static final ThreadLocal<UI> currentUI = new ThreadLocal<UI>();
/** Identifies the click event */
private ConnectorTracker connectorTracker = new ConnectorTracker(this);
private Page page = new Page(this);
- private RootServerRpc rpc = new RootServerRpc() {
+ private UIServerRpc rpc = new UIServerRpc() {
@Override
public void click(MouseEventDetails mouseDetails) {
- fireEvent(new ClickEvent(Root.this, mouseDetails));
+ fireEvent(new ClickEvent(UI.this, mouseDetails));
}
@Override
@@ -444,80 +483,89 @@ public abstract class Root extends AbstractComponentContainer implements
};
/**
- * Creates a new empty root without a caption. This root will have a
+ * Timestamp keeping track of the last heartbeat of this UI. Updated to the
+ * current time whenever the application receives a heartbeat or UIDL
+ * request from the client for this UI.
+ */
+ private long lastHeartbeat = System.currentTimeMillis();
+
+ private long lastUidlRequest = System.currentTimeMillis();
+
+ /**
+ * Creates a new empty UI without a caption. This UI will have a
* {@link VerticalLayout} with margins enabled as its content.
*/
- public Root() {
+ public UI() {
this((ComponentContainer) null);
}
/**
- * Creates a new root with the given component container as its content.
+ * Creates a new UI with the given component container as its content.
*
* @param content
- * the content container to use as this roots content.
+ * the content container to use as this UIs content.
*
* @see #setContent(ComponentContainer)
*/
- public Root(ComponentContainer content) {
+ public UI(ComponentContainer content) {
registerRpc(rpc);
setSizeFull();
setContent(content);
}
/**
- * Creates a new empty root with the given caption. This root will have a
+ * Creates a new empty UI with the given caption. This UI will have a
* {@link VerticalLayout} with margins enabled as its content.
*
* @param caption
- * the caption of the root, used as the page title if there's
+ * the caption of the UI, used as the page title if there's
* nothing but the application on the web page
*
* @see #setCaption(String)
*/
- public Root(String caption) {
+ public UI(String caption) {
this((ComponentContainer) null);
setCaption(caption);
}
/**
- * Creates a new root with the given caption and content.
+ * Creates a new UI with the given caption and content.
*
* @param caption
- * the caption of the root, used as the page title if there's
+ * the caption of the UI, used as the page title if there's
* nothing but the application on the web page
* @param content
- * the content container to use as this roots content.
+ * the content container to use as this UIs content.
*
* @see #setContent(ComponentContainer)
* @see #setCaption(String)
*/
- public Root(String caption, ComponentContainer content) {
+ public UI(String caption, ComponentContainer content) {
this(content);
setCaption(caption);
}
@Override
- protected RootState getState() {
- return (RootState) super.getState();
+ protected UIState getState() {
+ return (UIState) super.getState();
}
@Override
- public Class<? extends RootState> getStateType() {
+ public Class<? extends UIState> getStateType() {
// This is a workaround for a problem with creating the correct state
// object during build
- return RootState.class;
+ return UIState.class;
}
/**
* Overridden to return a value instead of referring to the parent.
*
- * @return this root
+ * @return this UI
*
- * @see com.vaadin.ui.AbstractComponent#getRoot()
+ * @see com.vaadin.ui.AbstractComponent#getUI()
*/
@Override
- public Root getRoot() {
+ public UI getUI() {
return this;
}
@@ -542,9 +590,9 @@ public abstract class Root extends AbstractComponentContainer implements
if (pendingFocus != null) {
// ensure focused component is still attached to this main window
- if (pendingFocus.getRoot() == this
- || (pendingFocus.getRoot() != null && pendingFocus
- .getRoot().getParent() == this)) {
+ if (pendingFocus.getUI() == this
+ || (pendingFocus.getUI() != null && pendingFocus.getUI()
+ .getParent() == this)) {
target.addAttribute("focused", pendingFocus);
}
pendingFocus = null;
@@ -555,7 +603,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
if (isResizeLazy()) {
- target.addAttribute(RootConstants.RESIZE_LAZY, true);
+ target.addAttribute(UIConstants.RESIZE_LAZY, true);
}
}
@@ -571,6 +619,16 @@ public abstract class Root extends AbstractComponentContainer implements
fireEvent(new ClickEvent(this, mouseDetails));
}
+ /**
+ * For internal use only.
+ */
+ public void fireCloseEvent() {
+ UI current = UI.getCurrent();
+ UI.setCurrent(this);
+ fireEvent(new CloseEvent(this));
+ UI.setCurrent(current);
+ }
+
@Override
@SuppressWarnings("unchecked")
public void changeVariables(Object source, Map<String, Object> variables) {
@@ -584,9 +642,9 @@ public abstract class Root extends AbstractComponentContainer implements
actionManager.handleActions(variables, this);
}
- if (variables.containsKey(RootConstants.FRAGMENT_VARIABLE)) {
+ if (variables.containsKey(UIConstants.FRAGMENT_VARIABLE)) {
String fragment = (String) variables
- .get(RootConstants.FRAGMENT_VARIABLE);
+ .get(UIConstants.FRAGMENT_VARIABLE);
getPage().setFragment(fragment, true);
}
}
@@ -622,7 +680,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Sets the application to which this root is assigned. It is not legal to
+ * Sets the application to which this UI is assigned. It is not legal to
* change the application once it has been set nor to set a
* <code>null</code> application.
* <p>
@@ -652,46 +710,46 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Sets the id of this root within its application. The root id is used to
- * route requests to the right root.
+ * Sets the id of this UI within its application. The UI id is used to route
+ * requests to the right UI.
* <p>
* This method is mainly intended for internal use by the framework.
* </p>
*
- * @param rootId
- * the id of this root
+ * @param uiId
+ * the id of this UI
*
* @throws IllegalStateException
- * if the root id has already been set
+ * if the UI id has already been set
*
- * @see #getRootId()
+ * @see #getUIId()
*/
- public void setRootId(int rootId) {
- if (this.rootId != -1) {
- throw new IllegalStateException("Root id has already been defined");
+ public void setUIId(int uiId) {
+ if (this.uiId != -1) {
+ throw new IllegalStateException("UI id has already been defined");
}
- this.rootId = rootId;
+ this.uiId = uiId;
}
/**
- * Gets the id of the root, used to identify this root within its
- * application when processing requests. The root id should be present in
- * every request to the server that originates from this root.
- * {@link Application#getRootForRequest(WrappedRequest)} uses this id to
- * find the route to which the request belongs.
+ * Gets the id of the UI, used to identify this UI within its application
+ * when processing requests. The UI id should be present in every request to
+ * the server that originates from this UI.
+ * {@link Application#getUIForRequest(WrappedRequest)} uses this id to find
+ * the route to which the request belongs.
*
* @return
*/
- public int getRootId() {
- return rootId;
+ public int getUIId() {
+ return uiId;
}
/**
- * Adds a window as a subwindow inside this root. To open a new browser
- * window or tab, you should instead use {@link open(Resource)} with an url
+ * Adds a window as a subwindow inside this UI. To open a new browser window
+ * or tab, you should instead use {@link open(Resource)} with an url
* pointing to this application and ensure
- * {@link Application#getRoot(WrappedRequest)} returns an appropriate root
- * for the request.
+ * {@link Application#getUI(WrappedRequest)} returns an appropriate UI for
+ * the request.
*
* @param window
* @throws IllegalArgumentException
@@ -727,7 +785,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Remove the given subwindow from this root.
+ * Remove the given subwindow from this UI.
*
* Since Vaadin 6.5, {@link CloseListener}s are called also when explicitly
* removing a window by calling this method.
@@ -741,7 +799,7 @@ public abstract class Root extends AbstractComponentContainer implements
*/
public boolean removeWindow(Window window) {
if (!windows.remove(window)) {
- // Window window is not a subwindow of this root.
+ // Window window is not a subwindow of this UI.
return false;
}
window.setParent(null);
@@ -752,7 +810,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Gets all the windows added to this root.
+ * Gets all the windows added to this UI.
*
* @return an unmodifiable collection of windows
*/
@@ -792,28 +850,28 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Scrolls any component between the component and root to a suitable
- * position so the component is visible to the user. The given component
- * must belong to this root.
+ * Scrolls any component between the component and UI to a suitable position
+ * so the component is visible to the user. The given component must belong
+ * to this UI.
*
* @param component
* the component to be scrolled into view
* @throws IllegalArgumentException
- * if {@code component} does not belong to this root
+ * if {@code component} does not belong to this UI
*/
public void scrollIntoView(Component component)
throws IllegalArgumentException {
- if (component.getRoot() != this) {
+ if (component.getUI() != this) {
throw new IllegalArgumentException(
- "The component where to scroll must belong to this root.");
+ "The component where to scroll must belong to this UI.");
}
scrollIntoView = component;
markAsDirty();
}
/**
- * Gets the content of this root. The content is a component container that
- * serves as the outermost item of the visual contents of this root.
+ * Gets the content of this UI. The content is a component container that
+ * serves as the outermost item of the visual contents of this UI.
*
* @return a component container to use as content
*
@@ -837,15 +895,15 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Sets the content of this root. The content is a component container that
- * serves as the outermost item of the visual contents of this root. If no
+ * Sets the content of this UI. The content is a component container that
+ * serves as the outermost item of the visual contents of this UI. If no
* content has been set, a {@link VerticalLayout} with margins enabled will
* be used by default - see {@link #createDefaultLayout()}. The content can
* also be set in a constructor.
*
* @return a component container to use as content
*
- * @see #Root(ComponentContainer)
+ * @see #UI(ComponentContainer)
* @see #createDefaultLayout()
*/
public void setContent(ComponentContainer content) {
@@ -863,11 +921,11 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Adds a component to this root. The component is not added directly to the
- * root, but instead to the content container ({@link #getContent()}).
+ * Adds a component to this UI. The component is not added directly to the
+ * UI, but instead to the content container ({@link #getContent()}).
*
* @param component
- * the component to add to this root
+ * the component to add to this UI
*
* @see #getContent()
*/
@@ -878,7 +936,7 @@ public abstract class Root extends AbstractComponentContainer implements
/**
* This implementation removes the component from the content container (
- * {@link #getContent()}) instead of from the actual root.
+ * {@link #getContent()}) instead of from the actual UI.
*/
@Override
public void removeComponent(Component component) {
@@ -887,7 +945,7 @@ public abstract class Root extends AbstractComponentContainer implements
/**
* This implementation removes the components from the content container (
- * {@link #getContent()}) instead of from the actual root.
+ * {@link #getContent()}) instead of from the actual UI.
*/
@Override
public void removeAllComponents() {
@@ -910,56 +968,55 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Initializes this root. This method is intended to be overridden by
+ * Initializes this UI. This method is intended to be overridden by
* subclasses to build the view and configure non-component functionality.
* Performing the initialization in a constructor is not suggested as the
- * state of the root is not properly set up when the constructor is invoked.
+ * state of the UI is not properly set up when the constructor is invoked.
* <p>
* The {@link WrappedRequest} can be used to get information about the
- * request that caused this root to be created. By default, the
+ * request that caused this UI to be created. By default, the
* {@link BrowserDetails} will be available in the request. If the browser
* details are not required, loading the application in the browser can take
* some shortcuts giving a faster initial rendering. This can be indicated
- * by adding the {@link EagerInit} annotation to the Root class.
+ * by adding the {@link EagerInit} annotation to the UI class.
* </p>
*
* @param request
- * the wrapped request that caused this root to be created
+ * the wrapped request that caused this UI to be created
*/
protected abstract void init(WrappedRequest request);
/**
- * Sets the thread local for the current root. This method is used by the
+ * Sets the thread local for the current UI. This method is used by the
* framework to set the current application whenever a new request is
* processed and it is cleared when the request has been processed.
* <p>
* The application developer can also use this method to define the current
- * root outside the normal request handling, e.g. when initiating custom
+ * UI outside the normal request handling, e.g. when initiating custom
* background threads.
* </p>
*
- * @param root
- * the root to register as the current root
+ * @param uI
+ * the UI to register as the current UI
*
* @see #getCurrent()
* @see ThreadLocal
*/
- public static void setCurrent(Root root) {
- currentRoot.set(root);
+ public static void setCurrent(UI ui) {
+ currentUI.set(ui);
}
/**
- * Gets the currently used root. The current root is automatically defined
- * when processing requests to the server. In other cases, (e.g. from
- * background threads), the current root is not automatically defined.
+ * Gets the currently used UI. The current UI is automatically defined when
+ * processing requests to the server. In other cases, (e.g. from background
+ * threads), the current UI is not automatically defined.
*
- * @return the current root instance if available, otherwise
- * <code>null</code>
+ * @return the current UI instance if available, otherwise <code>null</code>
*
- * @see #setCurrent(Root)
+ * @see #setCurrent(UI)
*/
- public static Root getCurrent() {
- return currentRoot.get();
+ public static UI getCurrent() {
+ return currentUI.get();
}
public void setScrollTop(int scrollTop) {
@@ -1027,10 +1084,10 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Add a click listener to the Root. The listener is called whenever the
- * user clicks inside the Root. Also when the click targets a component
- * inside the Root, provided the targeted component does not prevent the
- * click event from propagating.
+ * Add a click listener to the UI. The listener is called whenever the user
+ * clicks inside the UI. Also when the click targets a component inside the
+ * UI, provided the targeted component does not prevent the click event from
+ * propagating.
*
* Use {@link #removeListener(ClickListener)} to remove the listener.
*
@@ -1043,7 +1100,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Remove a click listener from the Root. The listener should earlier have
+ * Remove a click listener from the UI. The listener should earlier have
* been added using {@link #addListener(ClickListener)}.
*
* @param listener
@@ -1054,9 +1111,33 @@ public abstract class Root extends AbstractComponentContainer implements
listener);
}
+ /**
+ * Adds a close listener to the UI. The listener is called when the UI is
+ * removed from the application.
+ *
+ * @param listener
+ * The listener to add.
+ */
+ public void addListener(CloseListener listener) {
+ addListener(CloseEvent.CLOSE_EVENT_IDENTIFIER, CloseEvent.class,
+ listener, CloseListener.closeMethod);
+ }
+
+ /**
+ * Removes a close listener from the UI if it has previously been added with
+ * {@link #addListener(ClickListener)}. Otherwise, has no effect.
+ *
+ * @param listener
+ * The listener to remove.
+ */
+ public void removeListener(CloseListener listener) {
+ removeListener(CloseEvent.CLOSE_EVENT_IDENTIFIER, CloseEvent.class,
+ listener);
+ }
+
@Override
public boolean isConnectorEnabled() {
- // TODO How can a Root be invisible? What does it mean?
+ // TODO How can a UI be invisible? What does it mean?
return isVisible() && isEnabled();
}
@@ -1069,7 +1150,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Setting the caption of a Root is not supported. To set the title of the
+ * Setting the caption of a UI is not supported. To set the title of the
* HTML page, use Page.setTitle
*
* @deprecated as of 7.0.0, use {@link Page#setTitle(String)}
@@ -1078,11 +1159,11 @@ public abstract class Root extends AbstractComponentContainer implements
@Deprecated
public void setCaption(String caption) {
throw new IllegalStateException(
- "You can not set the title of a Root. To set the title of the HTML page, use Page.setTitle");
+ "You can not set the title of a UI. To set the title of the HTML page, use Page.setTitle");
}
/**
- * Shows a notification message on the middle of the root. The message
+ * Shows a notification message on the middle of the UI. The message
* automatically disappears ("humanized message").
*
* Care should be taken to to avoid XSS vulnerabilities as the caption is
@@ -1105,7 +1186,7 @@ public abstract class Root extends AbstractComponentContainer implements
}
/**
- * Shows a notification message the root. The position and behavior of the
+ * Shows a notification message the UI. The position and behavior of the
* message depends on the type, which is one of the basic types defined in
* {@link Notification}, for instance Notification.TYPE_WARNING_MESSAGE.
*
@@ -1132,8 +1213,8 @@ public abstract class Root extends AbstractComponentContainer implements
/**
* Shows a notification consisting of a bigger caption and a smaller
- * description on the middle of the root. The message automatically
- * disappears ("humanized message").
+ * description on the middle of the UI. The message automatically disappears
+ * ("humanized message").
*
* Care should be taken to to avoid XSS vulnerabilities as the caption and
* description are rendered as html.
@@ -1238,4 +1319,43 @@ public abstract class Root extends AbstractComponentContainer implements
getPage().showNotification(notification);
}
+ /**
+ * Returns the timestamp (milliseconds since the epoch) of the last received
+ * heartbeat for this UI.
+ *
+ * @see #heartbeat()
+ * @see Application#closeInactiveUIs()
+ *
+ * @return The time the last heartbeat request occurred.
+ */
+ public long getLastHeartbeatTime() {
+ return lastHeartbeat;
+ }
+
+ /**
+ * Returns the timestamp (milliseconds since the epoch) of the last received
+ * UIDL request for this UI.
+ *
+ * @return
+ */
+ public long getLastUidlRequestTime() {
+ return lastUidlRequest;
+ }
+
+ /**
+ * Sets the last heartbeat request timestamp for this UI. Called by the
+ * framework whenever the application receives a valid heartbeat request for
+ * this UI.
+ */
+ public void setLastHeartbeatTime(long lastHeartbeat) {
+ this.lastHeartbeat = lastHeartbeat;
+ }
+
+ /**
+ * Sets the last UIDL request timestamp for this UI. Called by the framework
+ * whenever the application receives a valid UIDL request for this UI.
+ */
+ public void setLastUidlRequestTime(long lastUidlRequest) {
+ this.lastUidlRequest = lastUidlRequest;
+ }
}
diff --git a/server/src/com/vaadin/ui/Window.java b/server/src/com/vaadin/ui/Window.java
index d79588cc63..6102350566 100644
--- a/server/src/com/vaadin/ui/Window.java
+++ b/server/src/com/vaadin/ui/Window.java
@@ -40,8 +40,8 @@ import com.vaadin.terminal.Vaadin6Component;
/**
* A component that represents a floating popup window that can be added to a
- * {@link Root}. A window is added to a {@code Root} using
- * {@link Root#addWindow(Window)}. </p>
+ * {@link UI}. A window is added to a {@code UI} using
+ * {@link UI#addWindow(Window)}. </p>
* <p>
* The contents of a window is set using {@link #setContent(ComponentContainer)}
* or by using the {@link #Window(String, ComponentContainer)} constructor. The
@@ -57,7 +57,7 @@ import com.vaadin.terminal.Vaadin6Component;
* </p>
* <p>
* In Vaadin versions prior to 7.0.0, Window was also used as application level
- * windows. This function is now covered by the {@link Root} class.
+ * windows. This function is now covered by the {@link UI} class.
* </p>
*
* @author Vaadin Ltd.
@@ -222,14 +222,14 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
* </p>
*/
public void close() {
- Root root = getRoot();
+ UI uI = getUI();
- // Don't do anything if not attached to a root
- if (root != null) {
+ // Don't do anything if not attached to a UI
+ if (uI != null) {
// focus is restored to the parent window
- root.focus();
- // subwindow is removed from the root
- root.removeWindow(this);
+ uI.focus();
+ // subwindow is removed from the UI
+ uI.removeWindow(this);
}
}
@@ -470,22 +470,22 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier,
* If there are currently several windows visible, calling this method makes
* this window topmost.
* <p>
- * This method can only be called if this window connected a root. Else an
+ * This method can only be called if this window connected a UI. Else an
* illegal state exception is thrown. Also if there are modal windows and
* this window is not modal, and illegal state exception is thrown.
* <p>
*/
public void bringToFront() {
- Root root = getRoot();
- if (root == null) {
+ UI uI = getUI();
+ if (uI == null) {
throw new IllegalStateException(
"Window must be attached to parent before calling bringToFront method.");
}
int maxBringToFront = -1;
- for (Window w : root.getWindows()) {
+ for (Window w : uI.getWindows()) {
if (!isModal() && w.isModal()) {
throw new IllegalStateException(
- "The root contains modal windows, non-modal window cannot be brought to front.");
+ "The UI contains modal windows, non-modal window cannot be brought to front.");
}
if (w.bringToFront != null) {
maxBringToFront = Math.max(maxBringToFront,