summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/ui
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2011-12-07 16:34:59 +0200
committerLeif Åstrand <leif@vaadin.com>2011-12-07 16:34:59 +0200
commit94d133023f8b43e0e185b43d7c329c6eac3be4b8 (patch)
tree9a2d847b09d3fde69e94bcec26fca4f0da3b2b24 /src/com/vaadin/ui
parent7491f0fd006b8ef26d7dd2a50bf18300d8b4e7e1 (diff)
downloadvaadin-framework-94d133023f8b43e0e185b43d7c329c6eac3be4b8.tar.gz
vaadin-framework-94d133023f8b43e0e185b43d7c329c6eac3be4b8.zip
URI fragment support in Root (#8048)
Diffstat (limited to 'src/com/vaadin/ui')
-rw-r--r--src/com/vaadin/ui/Root.java152
-rw-r--r--src/com/vaadin/ui/UriFragmentUtility.java153
2 files changed, 151 insertions, 154 deletions
diff --git a/src/com/vaadin/ui/Root.java b/src/com/vaadin/ui/Root.java
index bcc9c443c3..03bb1023ac 100644
--- a/src/com/vaadin/ui/Root.java
+++ b/src/com/vaadin/ui/Root.java
@@ -5,6 +5,7 @@
package com.vaadin.ui;
import java.io.Serializable;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -73,6 +74,67 @@ public class Root extends AbstractComponentContainer implements
Action.Container, Action.Notifier {
/**
+ * Listener that listens changes in URI fragment.
+ */
+ public interface FragmentChangedListener extends Serializable {
+ public void fragmentChanged(FragmentChangedEvent event);
+ }
+
+ /**
+ * Event fired when uri fragment changes.
+ */
+ public class FragmentChangedEvent extends Component.Event {
+
+ /**
+ * The new uri fragment
+ */
+ private final String fragment;
+
+ /**
+ * Creates a new instance of UriFragmentReader change event.
+ *
+ * @param source
+ * the Source of the event.
+ */
+ public FragmentChangedEvent(Root source, String fragment) {
+ super(source);
+ this.fragment = fragment;
+ }
+
+ /**
+ * Gets the root in which the fragment has changed.
+ *
+ * @return the root in which the fragment has changed
+ */
+ public Root getRoot() {
+ return (Root) getComponent();
+ }
+
+ /**
+ * Get the new fragment
+ *
+ * @return the new fragment
+ */
+ public String getFragment() {
+ return fragment;
+ }
+ }
+
+ private static final Method FRAGMENT_CHANGED_METHOD;
+
+ static {
+ try {
+ FRAGMENT_CHANGED_METHOD = FragmentChangedListener.class
+ .getDeclaredMethod("fragmentChanged",
+ new Class[] { FragmentChangedEvent.class });
+ } catch (final java.lang.NoSuchMethodException e) {
+ // This should never happen
+ throw new java.lang.RuntimeException(
+ "Internal error finding methods in FragmentChangedListener");
+ }
+ }
+
+ /**
* A border style used for opening resources in a window without a border.
*/
public static final int BORDER_NONE = 0;
@@ -303,6 +365,10 @@ public class Root extends AbstractComponentContainer implements
if (actionManager != null) {
actionManager.paintActions(null, target);
}
+
+ if (fragment != null) {
+ target.addAttribute(VView.FRAGMENT_VARIABLE, fragment);
+ }
}
@Override
@@ -313,6 +379,11 @@ public class Root extends AbstractComponentContainer implements
if (actionManager != null) {
actionManager.handleActions(variables, this);
}
+
+ if (variables.containsKey(VView.FRAGMENT_VARIABLE)) {
+ String fragment = (String) variables.get(VView.FRAGMENT_VARIABLE);
+ setFragment(fragment, true);
+ }
}
public Iterator<Component> getComponentIterator() {
@@ -466,6 +537,11 @@ public class Root extends AbstractComponentContainer implements
private Focusable pendingFocus;
/**
+ * The current URI fragment.
+ */
+ private String fragment;
+
+ /**
* This method is used by Component.Focusable objects to request focus to
* themselves. Focus renders must be handled at window level (instead of
* Component.Focusable) due we want the last focused component to be focused
@@ -792,6 +868,24 @@ public class Root extends AbstractComponentContainer implements
}
/**
+ * Internal initialization method, should not be overridden. This method is
+ * not declared as final because that would break compatibility with e.g.
+ * CDI.
+ *
+ * @param request
+ * the initialization request
+ */
+ public void doInit(WrappedRequest request) {
+ BrowserDetails browserDetails = request.getBrowserDetails();
+ if (browserDetails != null) {
+ fragment = browserDetails.getUriFragmet();
+ }
+
+ // Call the init overridden by the application developer
+ init(request);
+ }
+
+ /**
* Initializes this root. 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
@@ -807,7 +901,7 @@ public class Root extends AbstractComponentContainer implements
* @param request
* the wrapped request that caused this root to be created
*/
- public void init(WrappedRequest request) {
+ protected void init(WrappedRequest request) {
// Default implementation doesn't do anything
}
@@ -1100,6 +1194,62 @@ public class Root extends AbstractComponentContainer implements
listener);
}
+ public void addListener(FragmentChangedListener listener) {
+ addListener(FragmentChangedEvent.class, listener,
+ FRAGMENT_CHANGED_METHOD);
+ }
+
+ public void removeListener(FragmentChangedListener listener) {
+ removeListener(FragmentChangedEvent.class, listener,
+ FRAGMENT_CHANGED_METHOD);
+ }
+
+ /**
+ * Sets URI fragment. Optionally fires a {@link FragmentChangedEvent}
+ *
+ * @param newFragment
+ * id of the new fragment
+ * @param fireEvent
+ * true to fire event
+ * @see FragmentChangedEvent
+ * @see FragmentChangedListener
+ */
+ public void setFragment(String newFragment, boolean fireEvents) {
+ if (newFragment == null) {
+ throw new NullPointerException("The fragment may not be null");
+ }
+ if (!newFragment.equals(fragment)) {
+ fragment = newFragment;
+ if (fireEvents) {
+ fireEvent(new FragmentChangedEvent(this, newFragment));
+ }
+ requestRepaint();
+ }
+ }
+
+ /**
+ * Sets URI fragment. This method fires a {@link FragmentChangedEvent}
+ *
+ * @param newFragment
+ * id of the new fragment
+ * @see FragmentChangedEvent
+ * @see FragmentChangedListener
+ */
+ public void setFragment(String newFragment) {
+ setFragment(newFragment, true);
+ }
+
+ /**
+ * Gets currently set URI fragment.
+ * <p>
+ * To listen changes in fragment, hook a {@link FragmentChangedListener}.
+ *
+ * @return the current fragment in browser uri or null if not known
+ */
+ public String getFragment() {
+ return fragment;
+ }
+
public void addListener(ResizeListener resizeListener) {
throw new RuntimeException("Not yet implemented");
}
diff --git a/src/com/vaadin/ui/UriFragmentUtility.java b/src/com/vaadin/ui/UriFragmentUtility.java
deleted file mode 100644
index de21aff9ea..0000000000
--- a/src/com/vaadin/ui/UriFragmentUtility.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
-@ITMillApache2LicenseForJavaFiles@
- */
-package com.vaadin.ui;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import com.vaadin.terminal.PaintException;
-import com.vaadin.terminal.PaintTarget;
-import com.vaadin.terminal.gwt.client.ui.VUriFragmentUtility;
-import com.vaadin.ui.ClientWidget.LoadStyle;
-
-/**
- * Experimental web browser dependent component for URI fragment (part after
- * hash mark "#") reading and writing.
- *
- * Component can be used to workaround common ajax web applications pitfalls:
- * bookmarking a program state and back button.
- *
- */
-@SuppressWarnings("serial")
-@ClientWidget(value = VUriFragmentUtility.class, loadStyle = LoadStyle.EAGER)
-public class UriFragmentUtility extends AbstractComponent {
-
- /**
- * Listener that listens changes in URI fragment.
- */
- public interface FragmentChangedListener extends Serializable {
-
- public void fragmentChanged(FragmentChangedEvent source);
-
- }
-
- /**
- * Event fired when uri fragment changes.
- */
- public class FragmentChangedEvent extends Component.Event {
-
- /**
- * Creates a new instance of UriFragmentReader change event.
- *
- * @param source
- * the Source of the event.
- */
- public FragmentChangedEvent(Component source) {
- super(source);
- }
-
- /**
- * Gets the UriFragmentReader where the event occurred.
- *
- * @return the Source of the event.
- */
- public UriFragmentUtility getUriFragmentUtility() {
- return (UriFragmentUtility) getSource();
- }
- }
-
- private static final Method FRAGMENT_CHANGED_METHOD;
-
- static {
- try {
- FRAGMENT_CHANGED_METHOD = FragmentChangedListener.class
- .getDeclaredMethod("fragmentChanged",
- new Class[] { FragmentChangedEvent.class });
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in FragmentChangedListener");
- }
- }
-
- public void addListener(FragmentChangedListener listener) {
- addListener(FragmentChangedEvent.class, listener,
- FRAGMENT_CHANGED_METHOD);
- }
-
- public void removeListener(FragmentChangedListener listener) {
- removeListener(FragmentChangedEvent.class, listener,
- FRAGMENT_CHANGED_METHOD);
- }
-
- private String fragment;
-
- public UriFragmentUtility() {
- // immediate by default
- setImmediate(true);
- }
-
- @Override
- public void paintContent(PaintTarget target) throws PaintException {
- super.paintContent(target);
- target.addVariable(this, "fragment", fragment);
- }
-
- @Override
- public void changeVariables(Object source, Map<String, Object> variables) {
- super.changeVariables(source, variables);
- fragment = (String) variables.get("fragment");
- fireEvent(new FragmentChangedEvent(this));
- }
-
- /**
- * Gets currently set URI fragment.
- * <p>
- * To listen changes in fragment, hook a {@link FragmentChangedListener}.
- * <p>
- * Note that initial URI fragment that user used to enter the application
- * will be read after application init. It fires FragmentChangedEvent only
- * if it is not the same as on server side.
- *
- * @return the current fragment in browser uri or null if not known
- */
- public String getFragment() {
- return fragment;
- }
-
- /**
- * Sets URI fragment. Optionally fires a {@link FragmentChangedEvent}
- *
- * @param newFragment
- * id of the new fragment
- * @param fireEvent
- * true to fire event
- * @see FragmentChangedEvent
- * @see FragmentChangedListener
- */
- public void setFragment(String newFragment, boolean fireEvent) {
- if ((newFragment == null && fragment != null)
- || (newFragment != null && !newFragment.equals(fragment))) {
- fragment = newFragment;
- if (fireEvent) {
- fireEvent(new FragmentChangedEvent(this));
- }
- requestRepaint();
- }
- }
-
- /**
- * Sets URI fragment. This method fires a {@link FragmentChangedEvent}
- *
- * @param newFragment
- * id of the new fragment
- * @see FragmentChangedEvent
- * @see FragmentChangedListener
- */
- public void setFragment(String newFragment) {
- setFragment(newFragment, true);
- }
-
-}