diff options
7 files changed, 618 insertions, 64 deletions
diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 1a96230438..ede3cfa876 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -297,6 +297,15 @@ </init-param>
</servlet>
+ <servlet>
+ <servlet-name>NotificationDemo</servlet-name>
+ <servlet-class>com.itmill.toolkit.terminal.gwt.server.ApplicationServlet</servlet-class>
+ <init-param>
+ <param-name>application</param-name>
+ <param-value>com.itmill.toolkit.demo.NotificationDemo</param-value>
+ </init-param>
+ </servlet>
+
<servlet-mapping>
<servlet-name>TestForNativeWindowing</servlet-name>
@@ -433,6 +442,11 @@ <servlet-name>CachingDemo</servlet-name>
<url-pattern>/CachingDemo/*</url-pattern>
</servlet-mapping>
+
+ <servlet-mapping>
+ <servlet-name>NotificationDemo</servlet-name>
+ <url-pattern>/NotificationDemo/*</url-pattern>
+ </servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
diff --git a/src/com/itmill/toolkit/demo/NotificationDemo.java b/src/com/itmill/toolkit/demo/NotificationDemo.java new file mode 100644 index 0000000000..00cfd182dc --- /dev/null +++ b/src/com/itmill/toolkit/demo/NotificationDemo.java @@ -0,0 +1,82 @@ +package com.itmill.toolkit.demo; + +import com.itmill.toolkit.data.Item; +import com.itmill.toolkit.ui.Button; +import com.itmill.toolkit.ui.NativeSelect; +import com.itmill.toolkit.ui.RichTextArea; +import com.itmill.toolkit.ui.Select; +import com.itmill.toolkit.ui.TextField; +import com.itmill.toolkit.ui.Window; +import com.itmill.toolkit.ui.Button.ClickEvent; +import com.itmill.toolkit.ui.Button.ClickListener; + +/** + * Demonstrates the use of Notifications. + * + * @author IT Mill Ltd. + * @see com.itmill.toolkit.ui.Window + */ +public class NotificationDemo extends com.itmill.toolkit.Application { + + NativeSelect type; + TextField caption; + TextField message; + + /** + * The initialization method that is the only requirement for inheriting the + * com.itmill.toolkit.service.Application class. It will be automatically + * called by the framework when a user accesses the application. + */ + public void init() { + + /* + * - Create new window for the application - Give the window a visible + * title - Set the window to be the main window of the application + */ + Window main = new Window("Notification demo"); + setMainWindow(main); + + Window conf = new Window("Show Notification"); + conf.setWidth(450); + conf.setHeight(340); + main.addWindow(conf); + + type = new NativeSelect("Notification type"); + type.addContainerProperty("caption", String.class, null); + type.setNullSelectionAllowed(false); + type.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY); + type.setItemCaptionPropertyId("caption"); + Item i = type.addItem(new Integer( + Window.Notification.TYPE_HUMANIZED_MESSAGE)); + i.getItemProperty("caption").setValue("Humanized message"); + i = type.addItem(new Integer(Window.Notification.TYPE_WARNING_MESSAGE)); + i.getItemProperty("caption").setValue("Warning message"); + i = type.addItem(new Integer(Window.Notification.TYPE_ERROR_MESSAGE)); + i.getItemProperty("caption").setValue("Error message"); + i = type + .addItem(new Integer(Window.Notification.TYPE_TRAY_NOTIFICATION)); + i.getItemProperty("caption").setValue("Tray notification"); + type.setValue(new Integer(Window.Notification.TYPE_HUMANIZED_MESSAGE)); + conf.addComponent(type); + + caption = new TextField("Caption"); + caption.setValue("Saved!"); + caption.setColumns(20); + conf.addComponent(caption); + + message = new RichTextArea(); + message.setCaption("Message"); + message.setValue("Your stuff has been saved in <b>MyDocuments</b>."); + conf.addComponent(message); + + Button b = new Button("Show notification", new ClickListener() { + public void buttonClick(ClickEvent event) { + getMainWindow().showNotification((String) caption.getValue(), + (String) message.getValue(), + ((Integer) type.getValue()).intValue()); + } + + }); + conf.addComponent(b); + } +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/Notification.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/Notification.java new file mode 100644 index 0000000000..cd4740007e --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/Notification.java @@ -0,0 +1,229 @@ +package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.EventPreview;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.Widget;
+
+public class Notification extends PopupPanel {
+
+ public static final int CENTERED = 1;
+ public static final int CENTERED_TOP = 2;
+ public static final int CENTERED_BOTTOM = 3;
+ public static final int TOP_LEFT = 4;
+ public static final int TOP_RIGHT = 5;
+ public static final int BOTTOM_LEFT = 6;
+ public static final int BOTTOM_RIGHT = 7;
+
+ public static final int DELAY_FOREVER = -1;
+ public static final int DELAY_NONE = 0;
+
+ private static final String STYLENAME = "i-Notification";
+ private static final int mouseMoveThreshold = 7;
+ private static final int Z_INDEX_BASE = 20000;
+
+ private int startOpacity = 90;
+ private int fadeMsec = 400;
+ private int delayMsec = 1000;
+
+ private Timer fader;
+ private Timer delay;
+ private EventPreview eventPreview;
+
+ private String temporaryStyle;
+
+ public Notification() {
+ setStylePrimaryName(STYLENAME);
+ sinkEvents(Event.ONCLICK);
+ DOM.setStyleAttribute(getElement(), "zIndex", "" + Z_INDEX_BASE);
+ }
+
+ public Notification(int delayMsec) {
+ this();
+ this.delayMsec = delayMsec;
+ }
+
+ public Notification(int delayMsec, int fadeMsec, int startOpacity) {
+ this(delayMsec);
+ this.fadeMsec = fadeMsec;
+ this.startOpacity = startOpacity;
+ }
+
+ public void startDelay() {
+ DOM.removeEventPreview(eventPreview);
+ if (delayMsec > 0) {
+ delay = new Timer() {
+ public void run() {
+ fade();
+ }
+ };
+ delay.scheduleRepeating(delayMsec);
+ } else if (delayMsec == 0) {
+ fade();
+ }
+ }
+
+ public void show() {
+ show(CENTERED);
+ }
+
+ public void show(String style) {
+ show(CENTERED, style);
+ }
+
+ public void show(int position) {
+ show(position, null);
+ }
+
+ public void show(Widget widget, int position, String style) {
+ setWidget(widget);
+ show(position, style);
+ }
+
+ public void show(String html, int position, String style) {
+ setWidget(new HTML(html));
+ show(position, style);
+ }
+
+ public void show(int position, String style) {
+ hide();
+ setOpacity(getElement(), startOpacity);
+ if (style != null) {
+ this.temporaryStyle = style;
+ addStyleName(style);
+ }
+ super.show();
+ setPosition(position);
+
+ if (eventPreview == null) {
+ eventPreview = new EventPreview() {
+ int x = -1;
+ int y = -1;
+
+ public boolean onEventPreview(Event event) {
+ switch (DOM.eventGetType(event)) {
+ case Event.ONMOUSEMOVE:
+ if (x < 0) {
+ x = DOM.eventGetClientX(event);
+ y = DOM.eventGetClientY(event);
+ } else if (Math.abs(DOM.eventGetClientX(event) - x) > mouseMoveThreshold
+ || Math.abs(DOM.eventGetClientY(event) - y) > mouseMoveThreshold) {
+ startDelay();
+ }
+ break;
+ case Event.KEYEVENTS:
+ case Event.ONCLICK:
+ case Event.ONDBLCLICK:
+ case Event.ONSCROLL:
+ default:
+ startDelay();
+ }
+ return true;
+ }
+ };
+ }
+
+ DOM.addEventPreview(eventPreview);
+ }
+
+ public void hide() {
+ DOM.removeEventPreview(eventPreview);
+ cancelDelay();
+ cancelFade();
+ if (this.temporaryStyle != null) {
+ removeStyleName(this.temporaryStyle);
+ this.temporaryStyle = null;
+ }
+ super.hide();
+ }
+
+ public void fade() {
+ cancelDelay();
+ fader = new Timer() {
+ int opacity = startOpacity;
+
+ public void run() {
+ opacity -= 5;
+ setOpacity(getElement(), opacity);
+ if (opacity <= 0) {
+ cancel();
+ hide();
+ }
+ }
+ };
+ int msec = fadeMsec / (startOpacity / 5);
+ fader.scheduleRepeating(msec);
+ }
+
+ public void setPosition(int position) {
+ Element el = getElement();
+ DOM.setStyleAttribute(el, "top", null);
+ DOM.setStyleAttribute(el, "left", null);
+ DOM.setStyleAttribute(el, "bottom", null);
+ DOM.setStyleAttribute(el, "right", null);
+ switch (position) {
+ case TOP_LEFT:
+ DOM.setStyleAttribute(el, "top", "0px");
+ DOM.setStyleAttribute(el, "left", "0px");
+ break;
+ case TOP_RIGHT:
+ DOM.setStyleAttribute(el, "top", "0px");
+ DOM.setStyleAttribute(el, "right", "0px");
+ break;
+ case BOTTOM_RIGHT:
+ DOM.setStyleAttribute(el, "position", "absolute");
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ DOM.setStyleAttribute(el, "right", "0px");
+ break;
+ case BOTTOM_LEFT:
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ DOM.setStyleAttribute(el, "left", "0px");
+ break;
+ case CENTERED_TOP:
+ center();
+ DOM.setStyleAttribute(el, "top", "0px");
+ break;
+ case CENTERED_BOTTOM:
+ center();
+ DOM.setStyleAttribute(el, "top", null);
+ DOM.setStyleAttribute(el, "bottom", "0px");
+ break;
+ default:
+ case CENTERED:
+ center();
+ break;
+ }
+ }
+
+ private void cancelFade() {
+ if (fader != null) {
+ fader.cancel();
+ fader = null;
+ }
+ }
+
+ private void cancelDelay() {
+ if (delay != null) {
+ delay.cancel();
+ delay = null;
+ }
+ }
+
+ private void setOpacity(Element el, int opacity) {
+ DOM.setStyleAttribute(el, "opacity", "" + (opacity / 100.0));
+ DOM.setStyleAttribute(el, "filter", "Alpha(opacity=" + opacity + ")");
+
+ }
+
+ public void onBrowserEvent(Event event) {
+ DOM.removeEventPreview(eventPreview);
+ if (fader == null) {
+ fade();
+ }
+ }
+
+}
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/richtextarea/IRichTextArea.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/richtextarea/IRichTextArea.java index e2af2fd2b8..03c73e9e9d 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/richtextarea/IRichTextArea.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/richtextarea/IRichTextArea.java @@ -29,18 +29,18 @@ public class IRichTextArea extends Composite implements Paintable, protected ApplicationConnection client; private boolean immediate = false; - + RichTextArea rta = new RichTextArea(); - + RichTextToolbar formatter = new RichTextToolbar(rta); public IRichTextArea() { FlowPanel fp = new FlowPanel(); fp.add(formatter); - + rta.setWidth("100%"); rta.addFocusListener(this); - + fp.add(rta); initWidget(fp); @@ -51,28 +51,30 @@ public class IRichTextArea extends Composite implements Paintable, this.client = client; id = uidl.getId(); - if (client.updateComponent(this, uidl, true)) + if (client.updateComponent(this, uidl, true)) { return; + } immediate = uidl.getBooleanAttribute("immediate"); - - rta.setText(uidl.getStringAttribute("text")); + + rta.setHTML(uidl.getStringVariable("text")); } public void onChange(Widget sender) { - if (client != null && id != null) + if (client != null && id != null) { client.updateVariable(id, "text", rta.getText(), immediate); + } } public void onFocus(Widget sender) { - + } public void onLostFocus(Widget sender) { String html = rta.getHTML(); client.updateVariable(id, "text", html, immediate); - + } } diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/styles.css b/src/com/itmill/toolkit/terminal/gwt/public/default/styles.css index e5e037f988..3935cf07aa 100644 --- a/src/com/itmill/toolkit/terminal/gwt/public/default/styles.css +++ b/src/com/itmill/toolkit/terminal/gwt/public/default/styles.css @@ -8,6 +8,7 @@ @import "table/table.css";
@import "slider/slider.css";
@import "window/window.css";
+@import "window/notification.css";
@import "caption/caption.css";
@import "tree/tree.css";
@import "splitpanel/splitpanel.css";
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/default/window/notification.css b/src/com/itmill/toolkit/terminal/gwt/public/default/window/notification.css new file mode 100644 index 0000000000..3156f387b0 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/public/default/window/notification.css @@ -0,0 +1,38 @@ +
+.i-Notification {
+ font-family: "Trebuchet MS", geneva, helvetica, arial, tahoma, verdana, sans-serif;
+ background-color: #ffffff;
+ color: #cccccc;
+ border: 10px solid #cccccc;
+ padding: 0.2em;
+ cursor: pointer;
+}
+.i-Notification H1,
+.i-Notification p,
+.i-Notification.error H1,
+.i-Notification.error p,
+.i-Notification.warning H1,
+.i-Notification.warning p {
+ display: inline;
+ padding: 0.1em;
+}
+.i-Notification.tray H1,
+.i-Notification.tray p {
+ display: block;
+ font-size: 1em;
+ line-height: 0.5em;
+}
+
+.i-Notification.warning {
+ border-color: #f14c1a;
+ color: #f14c1a;
+}
+
+.i-Notification.error {
+ color: #ff0a0a;
+ border-color: #ff0a0a;
+}
+.i-Notification.tray {
+ color: #000000;
+ border-bottom: none;
+}
diff --git a/src/com/itmill/toolkit/ui/Window.java b/src/com/itmill/toolkit/ui/Window.java index 411f977f81..376e056756 100644 --- a/src/com/itmill/toolkit/ui/Window.java +++ b/src/com/itmill/toolkit/ui/Window.java @@ -28,18 +28,6 @@ package com.itmill.toolkit.ui; -import com.itmill.toolkit.Application; -import com.itmill.toolkit.Application.WindowAttachEvent; -import com.itmill.toolkit.Application.WindowAttachListener; -import com.itmill.toolkit.terminal.DownloadStream; -import com.itmill.toolkit.terminal.PaintException; -import com.itmill.toolkit.terminal.PaintTarget; -import com.itmill.toolkit.terminal.ParameterHandler; -import com.itmill.toolkit.terminal.Resource; -import com.itmill.toolkit.terminal.Sizeable; -import com.itmill.toolkit.terminal.Terminal; -import com.itmill.toolkit.terminal.URIHandler; - import java.lang.ref.WeakReference; import java.lang.reflect.Method; import java.net.MalformedURLException; @@ -47,11 +35,21 @@ import java.net.URL; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.Map; -import java.util.Iterator; import java.util.Set; +import com.itmill.toolkit.Application; +import com.itmill.toolkit.terminal.DownloadStream; +import com.itmill.toolkit.terminal.PaintException; +import com.itmill.toolkit.terminal.PaintTarget; +import com.itmill.toolkit.terminal.ParameterHandler; +import com.itmill.toolkit.terminal.Resource; +import com.itmill.toolkit.terminal.Sizeable; +import com.itmill.toolkit.terminal.Terminal; +import com.itmill.toolkit.terminal.URIHandler; + /** * Application window component. * @@ -98,7 +96,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler { private LinkedList parameterHandlerList = null; /** Set of subwindows */ - private HashSet subwindows = new HashSet(); + private final HashSet subwindows = new HashSet(); /** * Explicitly specified theme of this window. If null, application theme is @@ -109,7 +107,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler { /** * Resources to be opened automatically on next repaint. */ - private LinkedList openList = new LinkedList(); + private final LinkedList openList = new LinkedList(); /** * The name of the window. @@ -148,6 +146,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler { */ private int scrollLeft = 0; + private LinkedList notifications; + /* ********************************************************************* */ /** @@ -240,8 +240,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * @return the parent application of the component. */ public final Application getApplication() { - if (getParent() == null) + if (getParent() == null) { return this.application; + } return ((Window) getParent()).getApplication(); } @@ -300,11 +301,13 @@ public class Window extends Panel implements URIHandler, ParameterHandler { public void addURIHandler(URIHandler handler) { // TODO Subwindow support - if (uriHandlerList == null) + if (uriHandlerList == null) { uriHandlerList = new LinkedList(); + } synchronized (uriHandlerList) { - if (!uriHandlerList.contains(handler)) + if (!uriHandlerList.contains(handler)) { uriHandlerList.addLast(handler); + } } } @@ -317,12 +320,14 @@ public class Window extends Panel implements URIHandler, ParameterHandler { public void removeURIHandler(URIHandler handler) { // TODO Subwindow support - if (handler == null || uriHandlerList == null) + if (handler == null || uriHandlerList == null) { return; + } synchronized (uriHandlerList) { uriHandlerList.remove(handler); - if (uriHandlerList.isEmpty()) + if (uriHandlerList.isEmpty()) { uriHandlerList = null; + } } } @@ -345,10 +350,11 @@ public class Window extends Panel implements URIHandler, ParameterHandler { DownloadStream ds = ((URIHandler) handlers[i]).handleURI( context, relativeUri); if (ds != null) { - if (result != null) + if (result != null) { throw new RuntimeException("handleURI for " + context + " uri: '" + relativeUri + "' returns ambigious result."); + } result = ds; } } @@ -366,11 +372,13 @@ public class Window extends Panel implements URIHandler, ParameterHandler { */ public void addParameterHandler(ParameterHandler handler) { // TODO Subwindow support - if (parameterHandlerList == null) + if (parameterHandlerList == null) { parameterHandlerList = new LinkedList(); + } synchronized (parameterHandlerList) { - if (!parameterHandlerList.contains(handler)) + if (!parameterHandlerList.contains(handler)) { parameterHandlerList.addLast(handler); + } } } @@ -382,12 +390,14 @@ public class Window extends Panel implements URIHandler, ParameterHandler { */ public void removeParameterHandler(ParameterHandler handler) { // TODO Subwindow support - if (handler == null || parameterHandlerList == null) + if (handler == null || parameterHandlerList == null) { return; + } synchronized (parameterHandlerList) { parameterHandlerList.remove(handler); - if (parameterHandlerList.isEmpty()) + if (parameterHandlerList.isEmpty()) { parameterHandlerList = null; + } } } @@ -398,8 +408,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { synchronized (parameterHandlerList) { handlers = parameterHandlerList.toArray(); } - for (int i = 0; i < handlers.length; i++) + for (int i = 0; i < handlers.length; i++) { ((ParameterHandler) handlers[i]).handleParameters(parameters); + } } } @@ -419,14 +430,18 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * returned */ public String getTheme() { - if (getParent() != null) + if (getParent() != null) { return ((Window) getParent()).getTheme(); - if (theme != null) + } + if (theme != null) { return theme; - if ((application != null) && (application.getTheme() != null)) + } + if ((application != null) && (application.getTheme() != null)) { return application.getTheme(); - if (terminal != null) + } + if (terminal != null) { return terminal.getDefaultTheme(); + } return null; } @@ -439,9 +454,10 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * the New theme for this window. Null implies the default theme. */ public void setTheme(String theme) { - if (getParent() != null) + if (getParent() != null) { throw new UnsupportedOperationException( "Setting theme for sub-windws is not supported."); + } this.theme = theme; requestRepaint(); } @@ -467,14 +483,16 @@ public class Window extends Panel implements URIHandler, ParameterHandler { // Marks the main window if (getApplication() != null - && this == getApplication().getMainWindow()) + && this == getApplication().getMainWindow()) { target.addAttribute("main", true); + } // Open requested resource synchronized (openList) { if (!openList.isEmpty()) { - for (Iterator i = openList.iterator(); i.hasNext();) + for (Iterator i = openList.iterator(); i.hasNext();) { ((OpenResource) i.next()).paintContent(target); + } openList.clear(); } } @@ -494,11 +512,12 @@ public class Window extends Panel implements URIHandler, ParameterHandler { target.addVariable(this, "close", false); // Sets the focused component - if (this.focusedComponent != null) + if (this.focusedComponent != null) { target.addVariable(this, "focused", "" + this.focusedComponent.getFocusableId()); - else + } else { target.addVariable(this, "focused", ""); + } // Paint subwindows for (Iterator i = subwindows.iterator(); i.hasNext();) { @@ -506,6 +525,29 @@ public class Window extends Panel implements URIHandler, ParameterHandler { w.paint(target); } + // Paint notifications + if (this.notifications != null) { + target.startTag("notifications"); + for (Iterator it = this.notifications.iterator(); it.hasNext();) { + Notification n = (Notification) it.next(); + target.startTag("notification"); + if (n.getCaption() != null) { + target.addAttribute("caption", n.getCaption()); + } + if (n.getMessage() != null) { + target.addAttribute("message", n.getMessage()); + } + target.addAttribute("position", n.getPosition()); + target.addAttribute("delay", n.getDelayMsec()); + if (n.getStyleName() != null) { + target.addAttribute("style", n.getStyleName()); + } + target.endTag("notification"); + } + target.endTag("notifications"); + this.notifications = null; + } + } /* ********************************************************************* */ @@ -517,9 +559,10 @@ public class Window extends Panel implements URIHandler, ParameterHandler { */ public void open(Resource resource) { synchronized (openList) { - if (!openList.contains(resource)) + if (!openList.contains(resource)) { openList.add(new OpenResource(resource, null, -1, -1, BORDER_DEFAULT)); + } } requestRepaint(); } @@ -538,9 +581,10 @@ public class Window extends Panel implements URIHandler, ParameterHandler { */ public void open(Resource resource, String windowName) { synchronized (openList) { - if (!openList.contains(resource)) + if (!openList.contains(resource)) { openList.add(new OpenResource(resource, windowName, -1, -1, BORDER_DEFAULT)); + } } requestRepaint(); } @@ -561,9 +605,10 @@ public class Window extends Panel implements URIHandler, ParameterHandler { public void open(Resource resource, String windowName, int width, int height, int border) { synchronized (openList) { - if (!openList.contains(resource)) + if (!openList.contains(resource)) { openList.add(new OpenResource(resource, windowName, width, height, border)); + } } requestRepaint(); } @@ -578,8 +623,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { */ public URL getURL() { - if (application == null) + if (application == null) { return null; + } try { return new URL(application.getURL(), getName() + "/"); @@ -651,8 +697,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { public void setApplication(Application application) { // If the application is not changed, dont do nothing - if (application == this.application) + if (application == this.application) { return; + } // Sends detach event if the window is connected to application if (this.application != null) { @@ -663,8 +710,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { this.application = application; // Sends the attach event if connected to a window - if (application != null) + if (application != null) { attach(); + } } /** @@ -684,10 +732,11 @@ public class Window extends Panel implements URIHandler, ParameterHandler { public void setName(String name) { // The name can not be changed in application - if (getApplication() != null) + if (getApplication() != null) { throw new IllegalStateException( "Window name can not be changed while " + "the window is in application"); + } this.name = name; } @@ -709,8 +758,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * @see com.itmill.toolkit.terminal.Sizeable#getHeightUnits() */ public void setHeightUnits(int units) { - if (units != Sizeable.UNITS_PIXELS) + if (units != Sizeable.UNITS_PIXELS) { throw new IllegalArgumentException("Only pixels are supported"); + } } /** @@ -719,8 +769,9 @@ public class Window extends Panel implements URIHandler, ParameterHandler { * @see com.itmill.toolkit.terminal.Sizeable#getWidthUnits() */ public void setWidthUnits(int units) { - if (units != Sizeable.UNITS_PIXELS) + if (units != Sizeable.UNITS_PIXELS) { throw new IllegalArgumentException("Only pixels are supported"); + } } /** @@ -728,15 +779,15 @@ public class Window extends Panel implements URIHandler, ParameterHandler { */ private class OpenResource { - private Resource resource; + private final Resource resource; - private String name; + private final String name; - private int width; + private final int width; - private int height; + private final int height; - private int border; + private final int border; /** * Creates a new open resource. @@ -767,12 +818,15 @@ public class Window extends Panel implements URIHandler, ParameterHandler { private void paintContent(PaintTarget target) throws PaintException { target.startTag("open"); target.addAttribute("src", resource); - if (name != null && name.length() > 0) + if (name != null && name.length() > 0) { target.addAttribute("name", name); - if (width >= 0) + } + if (width >= 0) { target.addAttribute("width", width); - if (height >= 0) + } + if (height >= 0) { target.addAttribute("height", height); + } switch (border) { case Window.BORDER_MINIMAL: target.addAttribute("border", "minimal"); @@ -1052,12 +1106,14 @@ public class Window extends Panel implements URIHandler, ParameterHandler { public void addWindow(Window window) throws IllegalArgumentException, NullPointerException { - if (getParent() != null) + if (getParent() != null) { throw new IllegalArgumentException( "You can only add windows inside application-level windows"); + } - if (window == null) + if (window == null) { throw new NullPointerException("Argument must not be null"); + } subwindows.add(window); window.setParent(this); @@ -1124,4 +1180,136 @@ public class Window extends Panel implements URIHandler, ParameterHandler { this.scrollLeft = scrollLeft; } + public void showNotification(String message) { + addNotification(new Notification(message)); + } + + public void showNotification(String message, int type) { + addNotification(new Notification(message, type)); + } + + public void showNotification(String caption, String message, int type) { + addNotification(new Notification(caption, message, type)); + } + + public void showNotification(Notification notification) { + addNotification(notification); + } + + private void addNotification(Notification notification) { + if (this.notifications == null) { + this.notifications = new LinkedList(); + } + this.notifications.add(notification); + requestRepaint(); + } + + public class Notification { + public static final int TYPE_HUMANIZED_MESSAGE = 1; + public static final int TYPE_WARNING_MESSAGE = 2; + public static final int TYPE_ERROR_MESSAGE = 3; + public static final int TYPE_TRAY_NOTIFICATION = 4; + + public static final int POSITION_CENTERED = 1; + public static final int POSITION_CENTERED_TOP = 2; + public static final int POSITION_CENTERED_BOTTOM = 3; + public static final int POSITION_TOP_LEFT = 4; + public static final int POSITION_TOP_RIGHT = 5; + public static final int POSITION_BOTTOM_LEFT = 6; + public static final int POSITION_BOTTOM_RIGHT = 7; + + public static final int DELAY_FOREVER = -1; + public static final int DELAY_NONE = 0; + + private String caption; + private String message; + private Resource icon; + private int position = POSITION_CENTERED; + private int delayMsec = 0; + private String styleName; + + public Notification(String message) { + this(null, message, TYPE_HUMANIZED_MESSAGE); + } + + public Notification(String message, int type) { + this(null, message, type); + } + + public Notification(String caption, String message, int type) { + this.caption = caption; + this.message = message; + setType(type); + } + + private void setType(int type) { + switch (type) { + case TYPE_WARNING_MESSAGE: + delayMsec = 1500; + styleName = "warning"; + break; + case TYPE_ERROR_MESSAGE: + delayMsec = -1; + styleName = "error"; + break; + case TYPE_TRAY_NOTIFICATION: + delayMsec = 3000; + position = POSITION_BOTTOM_RIGHT; + styleName = "tray"; + + case TYPE_HUMANIZED_MESSAGE: + default: + break; + } + + } + + public String getCaption() { + return caption; + } + + public void setCaption(String caption) { + this.caption = caption; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } + + public Resource getIcon() { + return icon; + } + + public void setIcon(Resource icon) { + this.icon = icon; + } + + public int getDelayMsec() { + return delayMsec; + } + + public void setDelayMsec(int delayMsec) { + this.delayMsec = delayMsec; + } + + public void setStyleName(String styleName) { + this.styleName = styleName; + } + + public String getStyleName() { + return this.styleName; + } + } } |