aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRisto Yrjänä <risto.yrjana@itmill.com>2008-08-21 13:36:43 +0000
committerRisto Yrjänä <risto.yrjana@itmill.com>2008-08-21 13:36:43 +0000
commit7e80369a74187c96ace452a1deaeceffd0251eae (patch)
tree45ccdff0a47121f186b54521579bf97a59bfd83c
parent06d71187d4e281b7cb2b9beb55def6b22493dc54 (diff)
downloadvaadin-framework-7e80369a74187c96ace452a1deaeceffd0251eae.tar.gz
vaadin-framework-7e80369a74187c96ace452a1deaeceffd0251eae.zip
Copied PopupView from incubator to trunk
svn changeset:5240/svn branch:trunk
-rw-r--r--WebContent/ITMILL/themes/default/popupview/popupview.css11
-rw-r--r--WebContent/ITMILL/themes/default/styles.css14
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java6
-rw-r--r--src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupView.java337
-rw-r--r--src/com/itmill/toolkit/tests/tickets/Ticket1397.java147
-rw-r--r--src/com/itmill/toolkit/ui/PopupView.java235
6 files changed, 749 insertions, 1 deletions
diff --git a/WebContent/ITMILL/themes/default/popupview/popupview.css b/WebContent/ITMILL/themes/default/popupview/popupview.css
new file mode 100644
index 0000000000..d1024c4f38
--- /dev/null
+++ b/WebContent/ITMILL/themes/default/popupview/popupview.css
@@ -0,0 +1,11 @@
+/*
+ * PopupView styles
+ */
+.i-popupview-popup{
+ border: 1px solid #babfc0;
+ border-bottom: 1px solid #dee2e3;
+ background-color: white;
+ overflow: auto;
+ padding: 3px;
+ margin: 3px;
+} \ No newline at end of file
diff --git a/WebContent/ITMILL/themes/default/styles.css b/WebContent/ITMILL/themes/default/styles.css
index fa5c072c9a..ba97b407d1 100644
--- a/WebContent/ITMILL/themes/default/styles.css
+++ b/WebContent/ITMILL/themes/default/styles.css
@@ -210,7 +210,6 @@ input.i-modified,
line-height: 13px;
font-family: arial, helvetica, tahoma, verdana, sans-serif;
color: #5d5444;
- overflow: auto;
}
.i-tooltip-text {
@@ -218,6 +217,7 @@ input.i-modified,
border: none;
border-top: 1px solid #fffef5;
border-bottom: 1px solid #fbf8d9;
+ overflow: auto;
}
.i-tooltip .i-errormessage {
@@ -227,6 +227,7 @@ input.i-modified,
border: none;
border-top: 1px solid #fff3dc;
border-bottom: 1px solid #ead7b1;
+ overflow: auto;
}
.i-tooltip .i-errormessage h2 {
@@ -1035,6 +1036,17 @@ i-orderedlayout-margin-top {
background: #c1c6cc;
border: none;
}
+/*
+ * PopupView styles
+ */
+.i-popupview-popup{
+ border: 1px solid #babfc0;
+ border-bottom: 1px solid #dee2e3;
+ background-color: white;
+ overflow: auto;
+ padding: 3px;
+ margin: 3px;
+}
.i-progressindicator {
background: #dfe2e4 url(progressindicator/img/base.gif);
height: 9px;
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
index 0cd7348c5e..3f672a3ce0 100644
--- a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
+++ b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetSet.java
@@ -32,6 +32,7 @@ import com.itmill.toolkit.terminal.gwt.client.ui.IOrderedLayout;
import com.itmill.toolkit.terminal.gwt.client.ui.IPanel;
import com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField;
import com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar;
+import com.itmill.toolkit.terminal.gwt.client.ui.IPopupView;
import com.itmill.toolkit.terminal.gwt.client.ui.IProgressIndicator;
import com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable;
import com.itmill.toolkit.terminal.gwt.client.ui.ISlider;
@@ -186,6 +187,9 @@ public class DefaultWidgetSet implements WidgetSet {
} else if ("com.itmill.toolkit.terminal.gwt.client.ui.IMenuBar"
.equals(className)) {
return new IMenuBar();
+ } else if ("com.itmill.toolkit.terminal.gwt.client.ui.IPopupView"
+ .equals(className)) {
+ return new IPopupView();
}
return new IUnknownComponent();
@@ -306,6 +310,8 @@ public class DefaultWidgetSet implements WidgetSet {
}
} else if ("menubar".equals(tag)) {
return "com.itmill.toolkit.terminal.gwt.client.ui.IMenuBar";
+ } else if ("popupview".equals(tag)) {
+ return "com.itmill.toolkit.terminal.gwt.client.ui.IPopupView";
}
return "com.itmill.toolkit.terminal.gwt.client.ui.IUnknownComponent";
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupView.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupView.java
new file mode 100644
index 0000000000..303767faa1
--- /dev/null
+++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IPopupView.java
@@ -0,0 +1,337 @@
+package com.itmill.toolkit.terminal.gwt.client.ui;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+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.ui.ClickListener;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.HasFocus;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.PopupListener;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;
+import com.itmill.toolkit.terminal.gwt.client.Caption;
+import com.itmill.toolkit.terminal.gwt.client.CaptionWrapper;
+import com.itmill.toolkit.terminal.gwt.client.Container;
+import com.itmill.toolkit.terminal.gwt.client.Paintable;
+import com.itmill.toolkit.terminal.gwt.client.UIDL;
+
+public class IPopupView extends HTML implements Paintable, Container {
+
+ public static final String CLASSNAME = "i-popupview";
+
+ /** For server-client communication */
+ private String uidlId;
+ private ApplicationConnection client;
+
+ /** For inner classes */
+ private final IPopupView hostReference = this;
+
+ /** This variable helps to communicate popup visibility to the server */
+ private boolean hostPopupVisible;
+
+ private CustomPopup popup;
+ private final Label loading = new Label("Loading...");
+
+ // Browser window sizes
+ int windowTop;
+ int windowLeft;
+ int windowRight;
+ int windowBottom;
+
+ /**
+ * loading constructor
+ */
+ public IPopupView() {
+ super();
+ popup = new CustomPopup();
+
+ setStyleName(CLASSNAME);
+ popup.setStylePrimaryName(CLASSNAME + "-popup");
+
+ this.setHTML("PopupPanel");
+ popup.setWidget(loading);
+
+ // When we click to open the popup...
+ this.addClickListener(new ClickListener() {
+ public void onClick(Widget sender) {
+ updateState(true);
+ }
+ });
+
+ // ..and when we close it
+ popup.addPopupListener(new PopupListener() {
+ public void onPopupClosed(PopupPanel sender, boolean autoClosed) {
+ updateState(false);
+ }
+ });
+
+ }
+
+ /**
+ *
+ *
+ * @see com.itmill.toolkit.terminal.gwt.client.Paintable#updateFromUIDL(com.itmill.toolkit.terminal.gwt.client.UIDL,
+ * com.itmill.toolkit.terminal.gwt.client.ApplicationConnection)
+ */
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ // This call should be made first. Ensure correct implementation,
+ // and don't let the containing layout manage caption.
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+
+ // These are for future server connections
+ this.client = client;
+ uidlId = uidl.getId();
+
+ updateWindowSize();
+
+ hostPopupVisible = uidl.getBooleanAttribute("popupVisible");
+ this.setHTML(uidl.getStringAttribute("html"));
+
+ if (uidl.hasAttribute("description")) {
+ this.setTitle(uidl.getStringAttribute("description"));
+ }
+
+ // Render the popup if visible and show it. The component inside can
+ // change dynamically.
+ if (hostPopupVisible) {
+ UIDL popupUIDL = uidl.getChildUIDL(0);
+
+ popup.updateFromUIDL(popupUIDL, client);
+ showPopupOnTop(popup, hostReference);
+
+ } else { // The popup isn't visible so we should remove its child
+ popup.setWidget(null);
+ }
+ }// updateFromUIDL
+
+ /**
+ *
+ * @param visibility
+ */
+ private void updateState(boolean visibility) {
+ // If we know the server connection
+ // then update the current situation
+ if (uidlId != null && client != null) {
+ client.updateVariable(uidlId, "popupVisibility", visibility, true);
+ }
+ }
+
+ /**
+ * This shows the popup on top of the widget below. This function allows us
+ * to position the popup before making it visible.
+ *
+ * @param popup
+ * the popup to show
+ * @param host
+ * the widget to draw the popup on
+ */
+ private void showPopupOnTop(final CustomPopup popup, final Widget host) {
+ popup.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
+ public void setPosition(int offsetWidth, int offsetHeight) {
+ int hostHorizontalCenter = host.getAbsoluteLeft()
+ + host.getOffsetWidth() / 2;
+ int hostVerticalCenter = host.getAbsoluteTop()
+ + host.getOffsetHeight() / 2;
+
+ int left = hostHorizontalCenter - offsetWidth / 2;
+ int top = hostVerticalCenter - offsetHeight / 2;
+
+ // Superclass takes care of top and left
+ if ((left + offsetWidth) > windowRight) {
+ left -= (left + offsetWidth) - windowRight;
+ }
+
+ if ((top + offsetHeight) > windowBottom) {
+ top -= (top + offsetHeight) - windowBottom;
+ }
+
+ popup.setPopupPosition(left, top);
+ }
+ });
+ }
+
+ public void updateWindowSize() {
+ windowTop = RootPanel.get().getAbsoluteTop();
+ windowLeft = RootPanel.get().getAbsoluteLeft();
+ windowRight = windowLeft + RootPanel.get().getOffsetWidth();
+ windowBottom = windowTop + RootPanel.get().getOffsetHeight();
+ }
+
+ public boolean hasChildComponent(Widget component) {
+ return popup.equals(component);
+ }
+
+ public void replaceChildComponent(Widget oldComponent, Widget newComponent) {
+ if (newComponent == null || newComponent instanceof CustomPopup) {
+ popup.hide();
+
+ if (popup != null) {
+ client.unregisterPaintable((Paintable) popup);
+ }
+ popup = (CustomPopup) newComponent;
+
+ } else {
+ throw new IllegalArgumentException(
+ "PopupPanel only supports components of type CustomPopup");
+ }
+
+ }
+
+ public void updateCaption(Paintable component, UIDL uidl) {
+
+ }
+
+ public static native void nativeBlur(Element e) /*-{
+ if(e.focus) {
+ e.blur();
+ }
+ }-*/;
+
+ private class CustomPopup extends ToolkitOverlay implements Container {
+
+ private Paintable popupComponentPaintable = null;
+ private Widget popupComponentWidget = null;
+ private CaptionWrapper captionWrapper = null;
+
+ private boolean hasHadMouseOver = false;
+ private Set activeChildren;
+
+ public CustomPopup() {
+ super(true, false, true); // autoHide, not modal, dropshadow
+ activeChildren = new HashSet();
+ }
+
+ // For some reason ONMOUSEOUT events are not always recieved, so we have
+ // to use ONMOUSEMOVE that doesn't target the popup
+ public boolean onEventPreview(Event event) {
+
+ Element target = DOM.eventGetTarget(event);
+ boolean eventTargetsPopup = DOM.isOrHasChild(getElement(), target);
+ int type = DOM.eventGetType(event);
+
+ // Catch children that use keyboard, so we can unfocus them when
+ // hiding
+ if (type == Event.ONKEYPRESS) {
+ activeChildren.add(target);
+ }
+
+ if (eventTargetsPopup & type == Event.ONMOUSEMOVE) {
+ hasHadMouseOver = true;
+ }
+
+ if (!eventTargetsPopup & type == Event.ONMOUSEMOVE) {
+ if (hasHadMouseOver) {
+ hide();
+ hasHadMouseOver = false;
+ return true;
+ }
+ }
+
+ return super.onEventPreview(event);
+ }
+
+ public void hide() {
+ // Notify children with focus
+ if ((popupComponentWidget instanceof HasFocus)) {
+ ((HasFocus) popupComponentWidget).setFocus(false);
+ }
+
+ for (Iterator iterator = activeChildren.iterator(); iterator
+ .hasNext();) {
+ nativeBlur((Element) iterator.next());
+ }
+ activeChildren.clear();
+
+ super.hide();
+ }
+
+ public void setWidget(Widget w) {
+ super.setWidget(w);
+
+ if (w == null) {
+
+ unregisterPaintables();
+
+ popupComponentPaintable = null;
+ popupComponentWidget = null;
+ captionWrapper = null;
+ }
+ }
+
+ public boolean hasChildComponent(Widget component) {
+ if (popupComponentWidget != null) {
+ return popupComponentWidget.equals(component);
+ } else {
+ return false;
+ }
+ }
+
+ public void replaceChildComponent(Widget oldComponent,
+ Widget newComponent) {
+ System.out.println("CustomPopup replacechildcomponent");
+ if (oldComponent != null) {
+ client.unregisterPaintable((Paintable) oldComponent);
+ }
+
+ popupComponentWidget = (Widget) newComponent;
+
+ setWidget(popupComponentWidget);
+ }
+
+ public void updateCaption(Paintable component, UIDL uidl) {
+ if (Caption.isNeeded(uidl)) {
+ if (captionWrapper != null) {
+ captionWrapper.updateCaption(uidl);
+ } else {
+ captionWrapper = new CaptionWrapper(component, client);
+ setWidget(captionWrapper);
+ captionWrapper.updateCaption(uidl);
+ }
+ } else {
+ if (captionWrapper != null) {
+ setWidget(popupComponentWidget);
+ }
+ }
+
+ }
+
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
+ if (client.updateComponent(this, uidl, false)) {
+ return;
+ }
+
+ Paintable newPopupComponent = client.getPaintable(uidl
+ .getChildUIDL(0));
+
+ if (newPopupComponent != popupComponentPaintable) {
+
+ unregisterPaintables();
+
+ popupComponentWidget = (Widget) newPopupComponent;
+
+ popup.setWidget(popupComponentWidget);
+ popupComponentPaintable = newPopupComponent;
+ popupComponentPaintable.updateFromUIDL(uidl.getChildUIDL(0),
+ client);
+ }
+
+ }
+
+ private void unregisterPaintables() {
+ if (popupComponentPaintable != null) {
+ client.unregisterPaintable(popupComponentPaintable);
+ }
+ }
+
+ }// class CustomPopup
+
+}// class IPopupView
diff --git a/src/com/itmill/toolkit/tests/tickets/Ticket1397.java b/src/com/itmill/toolkit/tests/tickets/Ticket1397.java
new file mode 100644
index 0000000000..3fb7f8633a
--- /dev/null
+++ b/src/com/itmill/toolkit/tests/tickets/Ticket1397.java
@@ -0,0 +1,147 @@
+package com.itmill.toolkit.tests.tickets;
+
+import java.util.Date;
+
+import com.itmill.toolkit.Application;
+import com.itmill.toolkit.data.util.ObjectProperty;
+import com.itmill.toolkit.ui.Button;
+import com.itmill.toolkit.ui.Component;
+import com.itmill.toolkit.ui.InlineDateField;
+import com.itmill.toolkit.ui.Label;
+import com.itmill.toolkit.ui.Panel;
+import com.itmill.toolkit.ui.PopupView;
+import com.itmill.toolkit.ui.Table;
+import com.itmill.toolkit.ui.TextField;
+import com.itmill.toolkit.ui.Window;
+
+public class Ticket1397 extends Application {
+
+ Window main;
+
+ public void init() {
+ setTheme("default");
+ main = new Window("PopupView test");
+ setMainWindow(main);
+ Panel panel = new Panel("PopupTest");
+
+ // First test component
+ final ObjectProperty prop = new ObjectProperty("fooTextField");
+
+ PopupView.Content content = new PopupView.Content() {
+ public String getMinimizedValueAsHTML() {
+ return prop.toString();
+ }
+
+ public Component getPopupComponent() {
+ return new TextField("Edit foo", prop);
+ }
+ };
+
+ PopupView pe = new PopupView(content);
+ pe.setDescription("Click to edit");
+ panel.addComponent(pe);
+
+ // Second test component
+ PopupView pe2 = new PopupView("fooLabel", new Label(
+ "Foooooooooo..."));
+ pe2.setDescription("Click to view");
+ panel.addComponent(pe2);
+
+ // Third test component
+ final ObjectProperty prop2 = new ObjectProperty(new StringBuffer(
+ "Text for button"));
+
+ class myButton extends Button {
+ public myButton() {
+ super("Reverse the property");
+ this.addListener(new Button.ClickListener() {
+ public void buttonClick(Button.ClickEvent event) {
+ StringBuffer getContents = (StringBuffer) prop2
+ .getValue();
+ getContents.reverse();
+
+ }
+ });
+ }
+ }
+
+ final Panel panel2 = new Panel("Editor with a button");
+ panel2.addComponent(new myButton());
+ PopupView.Content content2 = new PopupView.Content() {
+ public String getMinimizedValueAsHTML() {
+ return prop2.toString();
+ }
+
+ public Component getPopupComponent() {
+ return panel2;
+ }
+ };
+
+ PopupView p3 = new PopupView(content2);
+ panel.addComponent(p3);
+
+ // Fourth test component
+ final Panel panel3 = new Panel("Editor popup for a property");
+ TextField tf2 = new TextField("TextField for editing a property");
+ final ObjectProperty op = new ObjectProperty("This is property text.");
+ tf2.setPropertyDataSource(op);
+ panel3.addComponent(tf2);
+ PopupView.Content content3 = new PopupView.Content() {
+
+ public String getMinimizedValueAsHTML() {
+ return op.toString();
+ }
+
+ public Component getPopupComponent() {
+ return panel3;
+ }
+
+ };
+ PopupView p4 = new PopupView(content3);
+ panel.addComponent(p4);
+
+ // Fifth test component
+ Table table = new Table("Table for testing purposes");
+ for (int i = 0; i < 5; i++)
+ table.addContainerProperty("" + (i + 1), String.class, "");
+ table.addContainerProperty("" + 6, PopupView.class, null);
+ table.addContainerProperty("" + 7, PopupView.class, null);
+ table.setPageLength(20);
+ for (int i = 0; i < 1000; i++) {
+
+ final InlineDateField df = new InlineDateField("", new Date());
+ PopupView pp = new PopupView(new PopupView.Content() {
+ public String getMinimizedValueAsHTML() {
+ return df.toString();
+ }
+
+ public Component getPopupComponent() {
+ return df;
+ }
+ });
+ final int lineNum = i;
+ PopupView pp2 = new PopupView(new PopupView.Content() {
+
+ TextField tf = new TextField("Editor for line " + lineNum,
+
+ "Try to edit the contents for this textfield on line "
+ + lineNum
+ + " and see how the overview-version changes.");
+
+ public String getMinimizedValueAsHTML() {
+ return "" + tf.toString().length() + " characters of info";
+ }
+
+ public Component getPopupComponent() {
+ return tf;
+ }
+
+ });
+ table.addItem(new Object[] { "1 " + i, "2 " + i, "3 " + i,
+ "4 " + i, "5 " + i, pp, pp2 }, new Integer(i));
+ }
+
+ main.addComponent(table);
+ main.addComponent(panel);
+ }
+}
diff --git a/src/com/itmill/toolkit/ui/PopupView.java b/src/com/itmill/toolkit/ui/PopupView.java
new file mode 100644
index 0000000000..c3ccb8f088
--- /dev/null
+++ b/src/com/itmill/toolkit/ui/PopupView.java
@@ -0,0 +1,235 @@
+package com.itmill.toolkit.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+import com.itmill.toolkit.terminal.PaintException;
+import com.itmill.toolkit.terminal.PaintTarget;
+
+public class PopupView extends AbstractComponentContainer {
+
+ Content itsContent;
+ boolean popupVisible;
+ ArrayList componentList;
+
+ /* Constructors */
+
+ /**
+ * A simple way to create a PopupPanel. Note that the minimal representation
+ * may not be dynamically updated, to achieve this create your own Content
+ * object.
+ *
+ * @param small
+ * the minimal textual representation as HTML
+ * @param large
+ * the full, Component-type representation
+ */
+ public PopupView(final java.lang.String small, final Component large) {
+ this(new PopupView.Content() {
+ public java.lang.String getMinimizedValueAsHTML() {
+ return small;
+ }
+
+ public Component getPopupComponent() {
+ return large;
+ }
+ });
+
+ }
+
+ /**
+ * Creates a PopupView through the PopupView.Content interface. This allows
+ * the creator to dynamically change the contents of the PopupView.
+ *
+ * @param content
+ * the PopupView.Content that contains the information for this
+ */
+ public PopupView(final PopupView.Content content) {
+ super();
+ itsContent = content;
+ popupVisible = false;
+ componentList = new ArrayList(1);
+ }
+
+ /**
+ * This method will replace the current content of the panel with a new one.
+ * Give null to remove current content.
+ *
+ * @param newContent
+ * PopupView.Content object containing new information for the
+ * PopupView
+ *
+ */
+ public void setContent(PopupView.Content newContent) {
+ itsContent = newContent;
+ requestRepaint();
+ }
+
+ /**
+ * Returns the content-package for this PopupView. Returns null if the
+ * PopupView has no content.
+ *
+ * @return the PopupView.Content for this object or null
+ */
+ public PopupView.Content getContent() {
+ return itsContent;
+ }
+
+ /**
+ * Return whether the popup is visible.
+ *
+ * @return true if the popup is showing
+ */
+ public boolean getPopupVisibility() {
+ return popupVisible;
+ }
+
+ /*
+ * Methods inherited from AbstractComponentContainer. These are unnecessary
+ * (but mandatory). They are not supported in this implementation.
+ */
+
+ /**
+ * Not supported in this implementation. Will return an empty iterator.
+ *
+ * @see com.itmill.toolkit.ui.ComponentContainer#getComponentIterator()
+ */
+ public Iterator getComponentIterator() {
+ return componentList.iterator();
+
+ }
+
+ /**
+ * Not supported in this implementation.
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponentContainer#removeAllComponents()
+ * @throws UnsupportedOperationException
+ */
+ public void removeAllComponents() {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * In this implementation, moveComponents is not supported. It always throws
+ * UnsupportedOperationException.
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponentContainer#moveComponentsFrom(com.itmill.toolkit.ui.ComponentContainer)
+ * @throws UnsupportedOperationException
+ */
+ public void moveComponentsFrom(ComponentContainer source)
+ throws UnsupportedOperationException {
+
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Not supported in this implementation.
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponentContainer#addComponent(com.itmill.toolkit.ui.Component)
+ * @throws UnsupportedOperationException
+ */
+ public void addComponent(Component c) throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ /**
+ * Not supported in this implementation. Always throws
+ * UnsupportedOperationException.
+ *
+ * @see com.itmill.toolkit.ui.ComponentContainer#replaceComponent(com.itmill.toolkit.ui.Component,
+ * com.itmill.toolkit.ui.Component)
+ * @throws UnsupportedOperationException
+ */
+ public void replaceComponent(Component oldComponent, Component newComponent)
+ throws UnsupportedOperationException {
+
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Not supported in this implementation
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponentContainer#removeComponent(com.itmill.toolkit.ui.Component)
+ */
+ public void removeComponent(Component c)
+ throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+
+ }
+
+ /*
+ * Methods for server-client communications.
+ */
+
+ /**
+ * @see com.itmill.toolkit.ui.AbstractComponent#getTag()
+ */
+ public java.lang.String getTag() {
+ return "popupview";
+ }
+
+ /**
+ * Paint (serialize) the component for the client.
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponent#paintContent(com.itmill.toolkit.terminal.PaintTarget)
+ */
+ public void paintContent(PaintTarget target) throws PaintException {
+ // Superclass writes any common attributes in the paint target.
+ super.paintContent(target);
+
+ target.addAttribute("html", itsContent.getMinimizedValueAsHTML());
+ target.addAttribute("popupVisible", popupVisible);
+
+ if (popupVisible) {
+ Component c = itsContent.getPopupComponent();
+
+ target.startTag("popupComponent");
+ c.paint(target);
+ target.endTag("popupComponent");
+ }
+
+ }
+
+ /**
+ * Deserialize changes received from client.
+ *
+ * @see com.itmill.toolkit.ui.AbstractComponent#changeVariables(java.lang.Object,
+ * java.util.Map)
+ */
+ public void changeVariables(Object source, Map variables) {
+ if (variables.containsKey("popupVisibility")) {
+ popupVisible = ((Boolean) variables.get("popupVisibility"))
+ .booleanValue();
+
+ if (popupVisible) {
+ componentList.add(itsContent.getPopupComponent());
+ } else {
+ componentList.clear();
+ }
+ requestRepaint();
+ }
+ }
+
+ /**
+ * Used to deliver customized content-packages to the PopupView. These are
+ * dynamically loaded when they are redrawn.
+ */
+ public interface Content {
+
+ /**
+ * This should return a small view of the full data.
+ *
+ * @return value in HTML format
+ */
+ public String getMinimizedValueAsHTML();
+
+ /**
+ * This should return the full Component representing the data
+ *
+ * @return a Component for the value
+ */
+ public Component getPopupComponent();
+ }
+}