123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- /*
- * Copyright 2000-2016 Vaadin Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
- package com.vaadin.ui;
-
- import java.io.Serializable;
- import java.lang.reflect.Method;
- import java.util.Collections;
- import java.util.Iterator;
-
- import org.jsoup.nodes.Element;
- import org.jsoup.nodes.Node;
- import org.jsoup.parser.Tag;
-
- import com.vaadin.shared.Registration;
- import com.vaadin.shared.ui.popupview.PopupViewServerRpc;
- import com.vaadin.shared.ui.popupview.PopupViewState;
- import com.vaadin.ui.declarative.DesignContext;
-
- /**
- *
- * A component for displaying a two different views to data. The minimized view
- * is normally used to render the component, and when it is clicked the full
- * view is displayed on a popup. The inner class {@link PopupView.Content} is
- * used to deliver contents to this component.
- *
- * @author Vaadin Ltd.
- */
- @SuppressWarnings("serial")
- public class PopupView extends AbstractComponent implements HasComponents {
-
- private Content content;
- private Component visibleComponent;
-
- private static final Method POPUP_VISIBILITY_METHOD;
- static {
- try {
- POPUP_VISIBILITY_METHOD = PopupVisibilityListener.class
- .getDeclaredMethod("popupVisibilityChange",
- PopupVisibilityEvent.class);
- } catch (final java.lang.NoSuchMethodException e) {
- // This should never happen
- throw new java.lang.RuntimeException(
- "Internal error finding methods in PopupView");
- }
- }
-
- private final PopupViewServerRpc rpc = this::setPopupVisible;
-
- /* Constructors */
-
- /**
- * This is an internal constructor. Use
- * {@link PopupView#PopupView(String, Component)} instead.
- *
- * @since 7.5.0
- */
- @Deprecated
- public PopupView() {
- registerRpc(rpc);
- setHideOnMouseOut(true);
- setContent(createContent("", new Label("")));
- }
-
- /**
- * A simple way to create a PopupPanel. Note that the minimal representation
- * may not be dynamically updated, in order to achieve this create your own
- * Content object and use {@link PopupView#PopupView(Content)}.
- *
- * @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(createContent(small, 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(PopupView.Content content) {
- this();
- setContent(content);
- }
-
- /**
- * Creates a Content from given text representation and popup content.
- *
- * @since 7.5.0
- *
- * @param minimizedValue
- * text representation when popup is hidden
- * @param popupContent
- * popup content
- * @return content with given data
- */
- protected static Content createContent(final String minimizedValue,
- final Component popupContent) {
- return new Content() {
- @Override
- public String getMinimizedValueAsHTML() {
- return minimizedValue;
- }
-
- @Override
- public Component getPopupComponent() {
- return popupContent;
- }
- };
- }
-
- /**
- * This method will replace the current content of the panel with a new one.
- *
- * @param newContent
- * PopupView.Content object containing new information for the
- * PopupView
- * @throws IllegalArgumentException
- * if the method is passed a null value, or if one of the
- * content methods returns null
- */
- public void setContent(PopupView.Content newContent)
- throws IllegalArgumentException {
- if (newContent == null) {
- throw new IllegalArgumentException("Content must not be null");
- }
- content = newContent;
- markAsDirty();
- }
-
- /**
- * Returns the content-package for this PopupView.
- *
- * @return the PopupView.Content for this object or null
- */
- public PopupView.Content getContent() {
- return content;
- }
-
- /**
- * Set the visibility of the popup. Does not hide the minimal
- * representation.
- *
- * @param visible
- */
- public void setPopupVisible(boolean visible) {
- if (isPopupVisible() != visible) {
- if (visible) {
- visibleComponent = content.getPopupComponent();
- if (visibleComponent == null) {
- throw new java.lang.IllegalStateException(
- "PopupView.Content did not return Component to set visible");
- }
- if (visibleComponent.getParent() != null) {
- // If the component already has a parent, try to remove it
- AbstractSingleComponentContainer
- .removeFromParent(visibleComponent);
- }
- visibleComponent.setParent(this);
- } else {
- if (equals(visibleComponent.getParent())) {
- visibleComponent.setParent(null);
- }
- visibleComponent = null;
- }
- fireEvent(new PopupVisibilityEvent(this));
- markAsDirty();
- }
- }
-
- @Override
- public void beforeClientResponse(boolean initial) {
- super.beforeClientResponse(initial);
- String html = content.getMinimizedValueAsHTML();
- if (html == null) {
- html = "";
- }
- getState().html = html;
- }
-
- /**
- * Return whether the popup is visible.
- *
- * @return true if the popup is showing
- */
- public boolean isPopupVisible() {
- return visibleComponent != null;
- }
-
- /**
- * Check if this popup will be hidden when the user takes the mouse cursor
- * out of the popup area.
- *
- * @return true if the popup is hidden on mouse out, false otherwise
- */
- public boolean isHideOnMouseOut() {
- return getState(false).hideOnMouseOut;
- }
-
- /**
- * Should the popup automatically hide when the user takes the mouse cursor
- * out of the popup area? If this is false, the user must click outside the
- * popup to close it. The default is true.
- *
- * @param hideOnMouseOut
- *
- */
- public void setHideOnMouseOut(boolean hideOnMouseOut) {
- getState().hideOnMouseOut = hideOnMouseOut;
- }
-
- /*
- * Methods inherited from AbstractComponentContainer. These are unnecessary
- * (but mandatory). Most of them are not supported in this implementation.
- */
-
- /**
- * This class only contains other components when the popup is showing.
- *
- * @see com.vaadin.ui.ComponentContainer#getComponentIterator()
- */
- @Override
- public Iterator<Component> iterator() {
- if (visibleComponent != null) {
- return Collections.singletonList(visibleComponent).iterator();
- } else {
- return Collections.<Component> emptyList().iterator();
- }
- }
-
- /**
- * Gets the number of contained components. Consistent with the iterator
- * returned by {@link #getComponentIterator()}.
- *
- * @return the number of contained components (zero or one)
- */
- public int getComponentCount() {
- return (visibleComponent != null ? 1 : 0);
- }
-
- @Override
- public void readDesign(Element design, DesignContext designContext) {
-
- // Read content first to avoid NPE when setting popup visible
- Component popupContent = null;
- String minimizedValue = "";
- for (Node childNode : design.childNodes()) {
- if (childNode instanceof Element) {
- Element child = (Element) childNode;
- if (child.tagName().equals("popup-content")) {
- popupContent = designContext.readDesign(child.child(0));
- } else {
- minimizedValue += child.toString();
- }
- } else {
- minimizedValue += childNode.toString();
- }
- }
- setContent(createContent(minimizedValue.trim(), popupContent));
-
- super.readDesign(design, designContext);
- }
-
- @Override
- public void writeDesign(Element design, DesignContext designContext) {
- super.writeDesign(design, designContext);
-
- Element popupContent = new Element(Tag.valueOf("popup-content"), "");
- popupContent.appendChild(
- designContext.createElement(content.getPopupComponent()));
-
- String minimizedHTML = content.getMinimizedValueAsHTML();
- if (minimizedHTML != null && !minimizedHTML.isEmpty()) {
- design.append(minimizedHTML);
- }
- design.appendChild(popupContent);
- }
-
- @Override
- protected PopupViewState getState() {
- return (PopupViewState) super.getState();
- }
-
- @Override
- protected PopupViewState getState(boolean markAsDirty) {
- return (PopupViewState) super.getState(markAsDirty);
- }
-
- /**
- * Used to deliver customized content-packages to the PopupView. These are
- * dynamically loaded when they are redrawn. The user must take care that
- * neither of these methods ever return null.
- */
- public interface Content extends Serializable {
-
- /**
- * 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();
- }
-
- /**
- * Add a listener that is called whenever the visibility of the popup is
- * changed.
- *
- * @see PopupVisibilityListener
- * @see PopupVisibilityEvent
- *
- * @param listener
- * the listener to add, not null
- * @return a registration object for removing the listener
- */
- public Registration addPopupVisibilityListener(
- PopupVisibilityListener listener) {
- return addListener(PopupVisibilityEvent.class, listener,
- POPUP_VISIBILITY_METHOD);
- }
-
- /**
- * Removes a previously added listener, so that it no longer receives events
- * when the visibility of the popup changes.
- *
- * @param listener
- * the listener to remove
- * @see PopupVisibilityListener
- * @see #addListener(PopupVisibilityListener)
- *
- * @deprecated As of 8.0, replaced by {@link Registration#remove()} in the
- * registration object returned from
- * {@link #addPopupVisibilityListener(PopupVisibilityListener)}.
- */
- @Deprecated
- public void removePopupVisibilityListener(
- PopupVisibilityListener listener) {
- removeListener(PopupVisibilityEvent.class, listener,
- POPUP_VISIBILITY_METHOD);
- }
-
- /**
- * This event is received by the PopupVisibilityListeners when the
- * visibility of the popup changes. You can get the new visibility directly
- * with {@link #isPopupVisible()}, or get the PopupView that produced the
- * event with {@link #getPopupView()}.
- *
- */
- public static class PopupVisibilityEvent extends Event {
-
- public PopupVisibilityEvent(PopupView source) {
- super(source);
- }
-
- /**
- * Get the PopupView instance that is the source of this event.
- *
- * @return the source PopupView
- */
- public PopupView getPopupView() {
- return (PopupView) getSource();
- }
-
- /**
- * Returns the current visibility of the popup.
- *
- * @return true if the popup is visible
- */
- public boolean isPopupVisible() {
- return getPopupView().isPopupVisible();
- }
- }
-
- /**
- * Defines a listener that can receive a PopupVisibilityEvent when the
- * visibility of the popup changes.
- *
- */
- public interface PopupVisibilityListener extends Serializable {
- /**
- * Pass to {@link PopupView#PopupVisibilityEvent} to start listening for
- * popup visibility changes.
- *
- * @param event
- * the event
- *
- * @see PopupVisibilityEvent
- * @see PopupView#addListener(PopupVisibilityListener)
- */
- public void popupVisibilityChange(PopupVisibilityEvent event);
- }
- }
|