diff options
Diffstat (limited to 'server/src/com/vaadin/ui/Panel.java')
-rw-r--r-- | server/src/com/vaadin/ui/Panel.java | 486 |
1 files changed, 486 insertions, 0 deletions
diff --git a/server/src/com/vaadin/ui/Panel.java b/server/src/com/vaadin/ui/Panel.java new file mode 100644 index 0000000000..3c26b73f09 --- /dev/null +++ b/server/src/com/vaadin/ui/Panel.java @@ -0,0 +1,486 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Map; + +import com.vaadin.event.Action; +import com.vaadin.event.Action.Handler; +import com.vaadin.event.ActionManager; +import com.vaadin.event.MouseEvents.ClickEvent; +import com.vaadin.event.MouseEvents.ClickListener; +import com.vaadin.shared.MouseEventDetails; +import com.vaadin.shared.ui.panel.PanelServerRpc; +import com.vaadin.shared.ui.panel.PanelState; +import com.vaadin.terminal.PaintException; +import com.vaadin.terminal.PaintTarget; +import com.vaadin.terminal.Scrollable; +import com.vaadin.terminal.Vaadin6Component; +import com.vaadin.terminal.gwt.client.ui.ClickEventHandler; +import com.vaadin.ui.Component.Focusable; + +/** + * Panel - a simple single component container. + * + * @author Vaadin Ltd. + * @version + * @VERSION@ + * @since 3.0 + */ +@SuppressWarnings("serial") +public class Panel extends AbstractComponentContainer implements Scrollable, + ComponentContainer.ComponentAttachListener, + ComponentContainer.ComponentDetachListener, Action.Notifier, Focusable, + Vaadin6Component { + + /** + * Content of the panel. + */ + private ComponentContainer content; + + /** + * Keeps track of the Actions added to this component, and manages the + * painting and handling as well. + */ + protected ActionManager actionManager; + + private PanelServerRpc rpc = new PanelServerRpc() { + @Override + public void click(MouseEventDetails mouseDetails) { + fireEvent(new ClickEvent(Panel.this, mouseDetails)); + } + }; + + /** + * Creates a new empty panel. A VerticalLayout is used as content. + */ + public Panel() { + this((ComponentContainer) null); + } + + /** + * Creates a new empty panel which contains the given content. The content + * cannot be null. + * + * @param content + * the content for the panel. + */ + public Panel(ComponentContainer content) { + registerRpc(rpc); + setContent(content); + setWidth(100, Unit.PERCENTAGE); + getState().setTabIndex(-1); + } + + /** + * Creates a new empty panel with caption. Default layout is used. + * + * @param caption + * the caption used in the panel (HTML/XHTML). + */ + public Panel(String caption) { + this(caption, null); + } + + /** + * Creates a new empty panel with the given caption and content. + * + * @param caption + * the caption of the panel (HTML/XHTML). + * @param content + * the content used in the panel. + */ + public Panel(String caption, ComponentContainer content) { + this(content); + setCaption(caption); + } + + /** + * Sets the caption of the panel. + * + * Note that the caption is interpreted as HTML/XHTML and therefore care + * should be taken not to enable HTML injection and XSS attacks using panel + * captions. This behavior may change in future versions. + * + * @see AbstractComponent#setCaption(String) + */ + @Override + public void setCaption(String caption) { + super.setCaption(caption); + } + + /** + * Returns the content of the Panel. + * + * @return + */ + public ComponentContainer getContent() { + return content; + } + + /** + * + * Set the content of the Panel. If null is given as the new content then a + * layout is automatically created and set as the content. + * + * @param content + * The new content + */ + public void setContent(ComponentContainer newContent) { + + // If the content is null we create the default content + if (newContent == null) { + newContent = createDefaultContent(); + } + + // if (newContent == null) { + // throw new IllegalArgumentException("Content cannot be null"); + // } + + if (newContent == content) { + // don't set the same content twice + return; + } + + // detach old content if present + if (content != null) { + content.setParent(null); + content.removeListener((ComponentContainer.ComponentAttachListener) this); + content.removeListener((ComponentContainer.ComponentDetachListener) this); + } + + // Sets the panel to be parent for the content + newContent.setParent(this); + + // Sets the new content + content = newContent; + + // Adds the event listeners for new content + newContent + .addListener((ComponentContainer.ComponentAttachListener) this); + newContent + .addListener((ComponentContainer.ComponentDetachListener) this); + + content = newContent; + requestRepaint(); + } + + /** + * Create a ComponentContainer which is added by default to the Panel if + * user does not specify any content. + * + * @return + */ + private ComponentContainer createDefaultContent() { + VerticalLayout layout = new VerticalLayout(); + // Force margins by default + layout.setMargin(true); + return layout; + } + + /* + * (non-Javadoc) + * + * @see + * com.vaadin.terminal.Vaadin6Component#paintContent(com.vaadin.terminal + * .PaintTarget) + */ + @Override + public void paintContent(PaintTarget target) throws PaintException { + if (actionManager != null) { + actionManager.paintActions(null, target); + } + } + + /** + * Adds the component into this container. + * + * @param c + * the component to be added. + * @see com.vaadin.ui.AbstractComponentContainer#addComponent(com.vaadin.ui.Component) + */ + @Override + public void addComponent(Component c) { + content.addComponent(c); + // No repaint request is made as we except the underlying container to + // request repaints + } + + /** + * Removes the component from this container. + * + * @param c + * The component to be removed. + * @see com.vaadin.ui.AbstractComponentContainer#removeComponent(com.vaadin.ui.Component) + */ + @Override + public void removeComponent(Component c) { + content.removeComponent(c); + // No repaint request is made as we except the underlying container to + // request repaints + } + + /** + * Gets the component container iterator for going through all the + * components in the container. + * + * @return the Iterator of the components inside the container. + * @see com.vaadin.ui.ComponentContainer#getComponentIterator() + */ + @Override + public Iterator<Component> getComponentIterator() { + return Collections.singleton((Component) content).iterator(); + } + + /** + * Called when one or more variables handled by the implementing class are + * changed. + * + * @see com.vaadin.terminal.VariableOwner#changeVariables(Object, Map) + */ + @Override + @SuppressWarnings("unchecked") + public void changeVariables(Object source, Map<String, Object> variables) { + // Get new size + final Integer newWidth = (Integer) variables.get("width"); + final Integer newHeight = (Integer) variables.get("height"); + if (newWidth != null && newWidth.intValue() != getWidth()) { + setWidth(newWidth.intValue(), UNITS_PIXELS); + } + if (newHeight != null && newHeight.intValue() != getHeight()) { + setHeight(newHeight.intValue(), UNITS_PIXELS); + } + + // Scrolling + final Integer newScrollX = (Integer) variables.get("scrollLeft"); + final Integer newScrollY = (Integer) variables.get("scrollTop"); + if (newScrollX != null && newScrollX.intValue() != getScrollLeft()) { + // set internally, not to fire request repaint + getState().setScrollLeft(newScrollX.intValue()); + } + if (newScrollY != null && newScrollY.intValue() != getScrollTop()) { + // set internally, not to fire request repaint + getState().setScrollTop(newScrollY.intValue()); + } + + // Actions + if (actionManager != null) { + actionManager.handleActions(variables, this); + } + + } + + /* Scrolling functionality */ + + /* + * (non-Javadoc) + * + * @see com.vaadin.terminal.Scrollable#setScrollable(boolean) + */ + @Override + public int getScrollLeft() { + return getState().getScrollLeft(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.terminal.Scrollable#setScrollable(boolean) + */ + @Override + public int getScrollTop() { + return getState().getScrollTop(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.terminal.Scrollable#setScrollLeft(int) + */ + @Override + public void setScrollLeft(int scrollLeft) { + if (scrollLeft < 0) { + throw new IllegalArgumentException( + "Scroll offset must be at least 0"); + } + getState().setScrollLeft(scrollLeft); + requestRepaint(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.terminal.Scrollable#setScrollTop(int) + */ + @Override + public void setScrollTop(int scrollTop) { + if (scrollTop < 0) { + throw new IllegalArgumentException( + "Scroll offset must be at least 0"); + } + getState().setScrollTop(scrollTop); + requestRepaint(); + } + + /* Documented in superclass */ + @Override + public void replaceComponent(Component oldComponent, Component newComponent) { + + content.replaceComponent(oldComponent, newComponent); + } + + /** + * A new component is attached to container. + * + * @see com.vaadin.ui.ComponentContainer.ComponentAttachListener#componentAttachedToContainer(com.vaadin.ui.ComponentContainer.ComponentAttachEvent) + */ + @Override + public void componentAttachedToContainer(ComponentAttachEvent event) { + if (event.getContainer() == content) { + fireComponentAttachEvent(event.getAttachedComponent()); + } + } + + /** + * A component has been detached from container. + * + * @see com.vaadin.ui.ComponentContainer.ComponentDetachListener#componentDetachedFromContainer(com.vaadin.ui.ComponentContainer.ComponentDetachEvent) + */ + @Override + public void componentDetachedFromContainer(ComponentDetachEvent event) { + if (event.getContainer() == content) { + fireComponentDetachEvent(event.getDetachedComponent()); + } + } + + /** + * Removes all components from this container. + * + * @see com.vaadin.ui.ComponentContainer#removeAllComponents() + */ + @Override + public void removeAllComponents() { + content.removeAllComponents(); + } + + /* + * ACTIONS + */ + @Override + protected ActionManager getActionManager() { + if (actionManager == null) { + actionManager = new ActionManager(this); + } + return actionManager; + } + + @Override + public <T extends Action & com.vaadin.event.Action.Listener> void addAction( + T action) { + getActionManager().addAction(action); + } + + @Override + public <T extends Action & com.vaadin.event.Action.Listener> void removeAction( + T action) { + if (actionManager != null) { + actionManager.removeAction(action); + } + } + + @Override + public void addActionHandler(Handler actionHandler) { + getActionManager().addActionHandler(actionHandler); + } + + @Override + public void removeActionHandler(Handler actionHandler) { + if (actionManager != null) { + actionManager.removeActionHandler(actionHandler); + } + } + + /** + * Removes all action handlers + */ + public void removeAllActionHandlers() { + if (actionManager != null) { + actionManager.removeAllActionHandlers(); + } + } + + /** + * Add a click listener to the Panel. The listener is called whenever the + * user clicks inside the Panel. Also when the click targets a component + * inside the Panel, provided the targeted component does not prevent the + * click event from propagating. + * + * Use {@link #removeListener(ClickListener)} to remove the listener. + * + * @param listener + * The listener to add + */ + public void addListener(ClickListener listener) { + addListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER, ClickEvent.class, + listener, ClickListener.clickMethod); + } + + /** + * Remove a click listener from the Panel. The listener should earlier have + * been added using {@link #addListener(ClickListener)}. + * + * @param listener + * The listener to remove + */ + public void removeListener(ClickListener listener) { + removeListener(ClickEventHandler.CLICK_EVENT_IDENTIFIER, + ClickEvent.class, listener); + } + + /** + * {@inheritDoc} + */ + @Override + public int getTabIndex() { + return getState().getTabIndex(); + } + + /** + * {@inheritDoc} + */ + @Override + public void setTabIndex(int tabIndex) { + getState().setTabIndex(tabIndex); + requestRepaint(); + } + + /** + * Moves keyboard focus to the component. {@see Focusable#focus()} + * + */ + @Override + public void focus() { + super.focus(); + } + + /* + * (non-Javadoc) + * + * @see com.vaadin.ui.ComponentContainer#getComponentCount() + */ + @Override + public int getComponentCount() { + // This is so wrong... (#2924) + return content.getComponentCount(); + } + + @Override + public PanelState getState() { + return (PanelState) super.getState(); + } + +} |