diff options
author | Ahmed Ashour <asashour@yahoo.com> | 2017-09-27 12:44:01 +0200 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-09-27 13:44:01 +0300 |
commit | 9f9efe0058397992fda43e104c90b79039d41c0f (patch) | |
tree | 6903fb464d96fb1f8f6a4e92c1308833388fd210 /server | |
parent | 94c57dea3848635e0ae42fae464e23301f9e7c2c (diff) | |
download | vaadin-framework-9f9efe0058397992fda43e104c90b79039d41c0f.tar.gz vaadin-framework-9f9efe0058397992fda43e104c90b79039d41c0f.zip |
Support addCloseListener for Notification (#10027)
Converts Notification to an Extension and adds support for listening to the closing of notifications.
Fixes #888
Diffstat (limited to 'server')
-rw-r--r-- | server/src/main/java/com/vaadin/server/Page.java | 74 | ||||
-rw-r--r-- | server/src/main/java/com/vaadin/server/PaintTarget.java | 20 | ||||
-rw-r--r-- | server/src/main/java/com/vaadin/ui/Notification.java | 201 | ||||
-rw-r--r-- | server/src/main/java/com/vaadin/ui/Window.java | 2 |
4 files changed, 173 insertions, 124 deletions
diff --git a/server/src/main/java/com/vaadin/server/Page.java b/server/src/main/java/com/vaadin/server/Page.java index 3e95de0c4b..d458839e4c 100644 --- a/server/src/main/java/com/vaadin/server/Page.java +++ b/server/src/main/java/com/vaadin/server/Page.java @@ -311,12 +311,6 @@ public class Page implements Serializable { private final LinkedList<OpenResource> openList = new LinkedList<>(); /** - * A list of notifications that are waiting to be sent to the client. - * Cleared (set to null) when the notifications have been sent. - */ - private List<Notification> notifications; - - /** * Event fired when the URI fragment of a <code>Page</code> changes. * * @see Page#addUriFragmentChangedListener(UriFragmentChangedListener) @@ -937,45 +931,6 @@ public class Page implements Serializable { openList.clear(); } - // Paint notifications - if (notifications != null) { - target.startTag("notifications"); - for (final Notification n : notifications) { - target.startTag("notification"); - if (n.getCaption() != null) { - target.addAttribute( - UIConstants.ATTRIBUTE_NOTIFICATION_CAPTION, - n.getCaption()); - } - if (n.getDescription() != null) { - target.addAttribute( - UIConstants.ATTRIBUTE_NOTIFICATION_MESSAGE, - n.getDescription()); - } - if (n.getIcon() != null) { - target.addAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_ICON, - n.getIcon()); - } - if (!n.isHtmlContentAllowed()) { - target.addAttribute( - UIConstants.NOTIFICATION_HTML_CONTENT_NOT_ALLOWED, - true); - } - target.addAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_POSITION, - n.getPosition().ordinal()); - target.addAttribute(UIConstants.ATTRIBUTE_NOTIFICATION_DELAY, - n.getDelayMsec()); - if (n.getStyleName() != null) { - target.addAttribute( - UIConstants.ATTRIBUTE_NOTIFICATION_STYLE, - n.getStyleName()); - } - target.endTag("notification"); - } - target.endTag("notifications"); - notifications = null; - } - if (newPushState != null) { target.addAttribute(UIConstants.ATTRIBUTE_PUSH_STATE, newPushState); newPushState = null; @@ -1342,20 +1297,6 @@ public class Page implements Serializable { } /** - * Internal helper method to actually add a notification. - * - * @param notification - * the notification to add - */ - private void addNotification(Notification notification) { - if (notifications == null) { - notifications = new LinkedList<>(); - } - notifications.add(notification); - uI.markAsDirty(); - } - - /** * Shows a notification message. * * @see Notification @@ -1367,7 +1308,7 @@ public class Page implements Serializable { */ @Deprecated public void showNotification(Notification notification) { - addNotification(notification); + notification.show(this); } /** @@ -1469,11 +1410,22 @@ public class Page implements Serializable { * @since 8.1 */ public Collection<Dependency> getPendingDependencies() { - ArrayList<Dependency> copy = new ArrayList<>(); + List<Dependency> copy = new ArrayList<>(); if (pendingDependencies != null) { copy.addAll(pendingDependencies); } pendingDependencies = null; return copy; } + + /** + * Returns the {@link UI} of this {@link Page}. + * + * @return the {@link UI} of this {@link Page}. + * + * @since + */ + public UI getUI() { + return uI; + } } diff --git a/server/src/main/java/com/vaadin/server/PaintTarget.java b/server/src/main/java/com/vaadin/server/PaintTarget.java index 6d531abc2c..0719fb26aa 100644 --- a/server/src/main/java/com/vaadin/server/PaintTarget.java +++ b/server/src/main/java/com/vaadin/server/PaintTarget.java @@ -39,7 +39,7 @@ public interface PaintTarget extends Serializable { * @param sectionTagName * the name of the tag. * @param sectionData - * the scetion data. + * the section data. * @throws PaintException * if the paint operation failed. */ @@ -145,7 +145,7 @@ public interface PaintTarget extends Serializable { public void endTag(String tagName) throws PaintException; /** - * Adds a boolean attribute to component. Atributes must be added before any + * Adds a boolean attribute to component. Attributes must be added before any * content is written. * * @param name @@ -159,7 +159,7 @@ public interface PaintTarget extends Serializable { public void addAttribute(String name, boolean value) throws PaintException; /** - * Adds a integer attribute to component. Atributes must be added before any + * Adds a integer attribute to component. Attributes must be added before any * content is written. * * @param name @@ -173,7 +173,7 @@ public interface PaintTarget extends Serializable { public void addAttribute(String name, int value) throws PaintException; /** - * Adds a resource attribute to component. Atributes must be added before + * Adds a resource attribute to component. Attributes must be added before * any content is written. * * @param name @@ -222,7 +222,7 @@ public interface PaintTarget extends Serializable { StreamVariable value) throws PaintException; /** - * Adds a long attribute to component. Atributes must be added before any + * Adds a long attribute to component. Attributes must be added before any * content is written. * * @param name @@ -236,7 +236,7 @@ public interface PaintTarget extends Serializable { public void addAttribute(String name, long value) throws PaintException; /** - * Adds a float attribute to component. Atributes must be added before any + * Adds a float attribute to component. Attributes must be added before any * content is written. * * @param name @@ -250,7 +250,7 @@ public interface PaintTarget extends Serializable { public void addAttribute(String name, float value) throws PaintException; /** - * Adds a double attribute to component. Atributes must be added before any + * Adds a double attribute to component. Attributes must be added before any * content is written. * * @param name @@ -264,7 +264,7 @@ public interface PaintTarget extends Serializable { public void addAttribute(String name, double value) throws PaintException; /** - * Adds a string attribute to component. Atributes must be added before any + * Adds a string attribute to component. Attributes must be added before any * content is written. * * @param name @@ -318,7 +318,7 @@ public interface PaintTarget extends Serializable { throws PaintException; /** - * Adds a int type variable. + * Adds an int type variable. * * @param owner * the Listener for variable changes. @@ -434,7 +434,7 @@ public interface PaintTarget extends Serializable { throws PaintException; /** - * Adds a upload stream type variable. + * Adds an upload stream type variable. * * @param owner * the Listener for variable changes. diff --git a/server/src/main/java/com/vaadin/ui/Notification.java b/server/src/main/java/com/vaadin/ui/Notification.java index 9ec031799f..15637ef3b0 100644 --- a/server/src/main/java/com/vaadin/ui/Notification.java +++ b/server/src/main/java/com/vaadin/ui/Notification.java @@ -17,10 +17,17 @@ package com.vaadin.ui; import java.io.Serializable; +import java.lang.reflect.Method; +import com.vaadin.event.ConnectorEvent; +import com.vaadin.server.AbstractExtension; import com.vaadin.server.Page; import com.vaadin.server.Resource; +import com.vaadin.server.ResourceReference; import com.vaadin.shared.Position; +import com.vaadin.shared.Registration; +import com.vaadin.shared.ui.notification.NotificationServerRpc; +import com.vaadin.shared.ui.notification.NotificationState; /** * A notification message, used to display temporary messages to the user - for @@ -61,7 +68,15 @@ import com.vaadin.shared.Position; * </p> * */ -public class Notification implements Serializable { +public class Notification extends AbstractExtension implements Serializable { + + /** + * The server RPC. + */ + protected NotificationServerRpc rpc = () -> { + fireEvent(new CloseEvent(Notification.this)); + }; + public enum Type { HUMANIZED_MESSAGE("humanized"), WARNING_MESSAGE( "warning"), ERROR_MESSAGE("error"), TRAY_NOTIFICATION("tray"), @@ -113,14 +128,6 @@ public class Notification implements Serializable { public static final int DELAY_FOREVER = -1; public static final int DELAY_NONE = 0; - private String caption; - private String description; - private Resource icon; - private Position position = Position.MIDDLE_CENTER; - private int delayMsec = 0; - private String styleName; - private boolean htmlContentAllowed; - /** * Creates a "humanized" notification message. * @@ -199,28 +206,29 @@ public class Notification implements Serializable { */ public Notification(String caption, String description, Type type, boolean htmlContentAllowed) { - this.caption = caption; - this.description = description; - this.htmlContentAllowed = htmlContentAllowed; + registerRpc(rpc); + setCaption(caption); + setDescription(description); + setHtmlContentAllowed(htmlContentAllowed); setType(type); } private void setType(Type type) { - styleName = type.getStyle(); + setStyleName(type.getStyle()); switch (type) { case WARNING_MESSAGE: - delayMsec = 1500; + setDelayMsec(1500); break; case ERROR_MESSAGE: - delayMsec = -1; + setDelayMsec(DELAY_FOREVER); break; case TRAY_NOTIFICATION: - delayMsec = 3000; - position = Position.BOTTOM_RIGHT; + setDelayMsec(3000); + setPosition(Position.BOTTOM_RIGHT); break; case ASSISTIVE_NOTIFICATION: - delayMsec = 3000; - position = Position.ASSISTIVE; + setDelayMsec(3000); + setPosition(Position.ASSISTIVE); break; case HUMANIZED_MESSAGE: default: @@ -234,35 +242,36 @@ public class Notification implements Serializable { * @return The message caption */ public String getCaption() { - return caption; + return getState(false).caption; } /** - * Sets the caption part of the notification message + * Sets the caption part of the notification message. * * @param caption * The message caption */ public void setCaption(String caption) { - this.caption = caption; + getState().caption = caption; } /** * Gets the description part of the notification message. * - * @return The message description. + * @return The message description */ public String getDescription() { - return description; + return getState(false).description; } /** * Sets the description part of the notification message. * * @param description + * The message description */ public void setDescription(String description) { - this.description = description; + getState().description = description; } /** @@ -271,17 +280,21 @@ public class Notification implements Serializable { * @return The position */ public Position getPosition() { - return position; + return getState(false).position; } /** * Sets the position of the notification message. * * @param position - * The desired notification position + * The desired notification position, + * not {@code null} */ public void setPosition(Position position) { - this.position = position; + if (position == null) { + throw new IllegalArgumentException("Position can not be null"); + } + getState().position = position; } /** @@ -290,7 +303,7 @@ public class Notification implements Serializable { * @return The message icon */ public Resource getIcon() { - return icon; + return getResource("icon"); } /** @@ -300,46 +313,47 @@ public class Notification implements Serializable { * The desired message icon */ public void setIcon(Resource icon) { - this.icon = icon; + setResource("icon", icon); } /** * Gets the delay before the notification disappears. * - * @return the delay in msec, -1 indicates the message has to be clicked. + * @return the delay in milliseconds, {@value #DELAY_FOREVER} + * indicates the message has to be clicked. */ public int getDelayMsec() { - return delayMsec; + return getState(false).delay; } /** * Sets the delay before the notification disappears. * * @param delayMsec - * the desired delay in msec, -1 to require the user to click the - * message + * the desired delay in milliseconds, {@value #DELAY_FOREVER} + * to require the user to click the message */ public void setDelayMsec(int delayMsec) { - this.delayMsec = delayMsec; + getState().delay = delayMsec; } /** * Sets the style name for the notification message. * * @param styleName - * The desired style name. + * The desired style name */ public void setStyleName(String styleName) { - this.styleName = styleName; + getState().styleName = styleName; } /** * Gets the style name for the notification message. * - * @return + * @return The style name */ public String getStyleName() { - return styleName; + return getState(false).styleName; } /** @@ -353,18 +367,19 @@ public class Notification implements Serializable { * text */ public void setHtmlContentAllowed(boolean htmlContentAllowed) { - this.htmlContentAllowed = htmlContentAllowed; + getState().htmlContentAllowed = htmlContentAllowed; } /** - * Checks whether caption and description are interpreted as html or plain + * Checks whether caption and description are interpreted as HTML or plain * text. * - * @return true if the texts are used as html, false if used as plain text + * @return {@code true} if the texts are used as HTML, + * {@code false} if used as plain text * @see #setHtmlContentAllowed(boolean) */ public boolean isHtmlContentAllowed() { - return htmlContentAllowed; + return getState(false).htmlContentAllowed; } /** @@ -374,8 +389,17 @@ public class Notification implements Serializable { * The page on which the notification should be shown */ public void show(Page page) { - // TODO Can avoid deprecated API when Notification extends Extension - page.showNotification(this); + extend(page.getUI()); + } + + @Override + protected NotificationState getState() { + return (NotificationState) super.getState(); + } + + @Override + protected NotificationState getState(boolean markAsDirty) { + return (NotificationState) super.getState(markAsDirty); } /** @@ -389,16 +413,20 @@ public class Notification implements Serializable { * * @param caption * The message + * @return + * The Notification */ - public static void show(String caption) { - new Notification(caption).show(Page.getCurrent()); + public static Notification show(String caption) { + Notification notification = new Notification(caption); + notification.extend(UI.getCurrent()); + return notification; } /** * Shows a notification message the current page. 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. + * {@link Type#WARNING_MESSAGE}. * * The caption is rendered as plain text with HTML automatically escaped. * @@ -409,9 +437,13 @@ public class Notification implements Serializable { * The message * @param type * The message type + * @return + * The Notification */ - public static void show(String caption, Type type) { - new Notification(caption, type).show(Page.getCurrent()); + public static Notification show(String caption, Type type) { + Notification notification = new Notification(caption, type); + notification.extend(UI.getCurrent()); + return notification; } /** @@ -431,8 +463,73 @@ public class Notification implements Serializable { * The message description * @param type * The message type + * @return + * The Notification */ - public static void show(String caption, String description, Type type) { - new Notification(caption, description, type).show(Page.getCurrent()); + public static Notification show(String caption, String description, Type type) { + Notification notification = new Notification(caption, description, type); + notification.extend(UI.getCurrent()); + return notification; } + + /** + * Adds a CloseListener to the Notification. + * + * @param listener + * the CloseListener to add, not {@code null} + * @since + */ + public Registration addCloseListener(CloseListener listener) { + return addListener(CloseEvent.class, listener, CLOSE_METHOD); + } + + private static final Method CLOSE_METHOD; + static { + try { + CLOSE_METHOD = CloseListener.class + .getDeclaredMethod("notificationClose", CloseEvent.class); + } catch (final NoSuchMethodException e) { + // This should never happen + throw new RuntimeException( + "Internal error, notification close method not found"); + } + } + + public static class CloseEvent extends ConnectorEvent { + + /** + * @param source + */ + public CloseEvent(Notification source) { + super(source); + } + + /** + * Gets the Notification. + * + * @return The Notification + */ + public Notification getNotification() { + return (Notification) getSource(); + } + } + + /** + * An interface used for listening to Notification close events. Add the + * CloseListener to a Notification and + * {@link CloseListener#notificationClose(CloseEvent)} will be called whenever the + * Notification is closed. + */ + @FunctionalInterface + public interface CloseListener extends Serializable { + /** + * Use {@link CloseEvent#getNotification()} to get a reference to the + * {@link Notification} that was closed. + * + * @param e + * The triggered event + */ + public void notificationClose(CloseEvent e); + } + } diff --git a/server/src/main/java/com/vaadin/ui/Window.java b/server/src/main/java/com/vaadin/ui/Window.java index 5a9b19f421..cd0840e517 100644 --- a/server/src/main/java/com/vaadin/ui/Window.java +++ b/server/src/main/java/com/vaadin/ui/Window.java @@ -504,7 +504,7 @@ public class Window extends Panel * {@link Window} that was closed. * * @param e - * Event containing + * The triggered event */ public void windowClose(CloseEvent e); } |