diff options
author | Leif Åstrand <leif@vaadin.com> | 2011-12-07 16:34:59 +0200 |
---|---|---|
committer | Leif Åstrand <leif@vaadin.com> | 2011-12-07 16:34:59 +0200 |
commit | 94d133023f8b43e0e185b43d7c329c6eac3be4b8 (patch) | |
tree | 9a2d847b09d3fde69e94bcec26fca4f0da3b2b24 /src/com/vaadin/ui | |
parent | 7491f0fd006b8ef26d7dd2a50bf18300d8b4e7e1 (diff) | |
download | vaadin-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.java | 152 | ||||
-rw-r--r-- | src/com/vaadin/ui/UriFragmentUtility.java | 153 |
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); - } - -} |