org.vaadin.alump.fancylayouts.FancyPanel.java Source code

Java tutorial

Introduction

Here is the source code for org.vaadin.alump.fancylayouts.FancyPanel.java

Source

/**
 * FancyPanel.java (FancyLayouts)
 * 
 * Copyright 2012 Vaadin Ltd, Sami Viitanen <alump@vaadin.org>
 *
 * 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 org.vaadin.alump.fancylayouts;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.vaadin.alump.fancylayouts.gwt.client.connect.FancyPanelServerRpc;
import org.vaadin.alump.fancylayouts.gwt.client.shared.FancyPanelState;
import org.vaadin.alump.fancylayouts.gwt.client.shared.RotateDirection;

import com.vaadin.event.ActionManager;
import com.vaadin.event.LayoutEvents.LayoutClickEvent;
import com.vaadin.event.LayoutEvents.LayoutClickListener;
import com.vaadin.event.LayoutEvents.LayoutClickNotifier;
import com.vaadin.shared.Connector;
import com.vaadin.shared.EventId;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.CssLayout;

/**
 * FancyPanel works like Vaadin Panel but it adds transition when content inside
 * it is changed.
 */
@SuppressWarnings("serial")
public class FancyPanel extends AbstractLayout implements ComponentContainer.ComponentAttachListener,
        ComponentContainer.ComponentDetachListener, LayoutClickNotifier {

    protected Set<Component> components = new HashSet<Component>();
    protected ActionManager actionManager;
    protected int scrollTop = 0;
    protected int scrollLeft = 0;
    protected ComponentContainer placeHolderComponent = null;

    protected FancyPanelServerRpc serverRpc = new FancyPanelServerRpc() {

        @Override
        public void scrollTop(int top) {
            scrollTop = top;
        }

        @Override
        public void scrollLeft(int left) {
            scrollLeft = left;
        }

        @Override
        public void hidden(Connector child) {
        }

        @Override
        public void layoutClick(MouseEventDetails mouseDetails, Connector clickedConnector) {
            fireEvent(LayoutClickEvent.createEvent(FancyPanel.this, mouseDetails, clickedConnector));
        }

    };

    /**
     * Create empty panel
     */
    public FancyPanel() {
        this(null);
    }

    /**
     * Create new panel with given content
     * 
     * @param content
     *            Content used inside panel
     */
    public FancyPanel(Component content) {
        super();
        showComponent(content);
    }

    /**
     * Create new panel with content and caption
     * 
     * @param content
     *            Content of panel
     * @param caption
     *            Caption of panel
     */
    public FancyPanel(ComponentContainer content, String caption) {
        this(content);
        setCaption(caption);
    }

    @Override
    protected FancyPanelState getState() {
        return (FancyPanelState) super.getState();
    }

    /**
     * Build default content container
     * 
     * @return Default content container
     */
    protected ComponentContainer createDefaultContent() {
        if (placeHolderComponent == null) {
            CssLayout layout = new CssLayout();
            layout.setStyleName("fancypanel-default-layout");
            layout.setSizeFull();
            placeHolderComponent = layout;
        }
        return placeHolderComponent;
    }

    /**
     * Get currently visible component
     * 
     * @return Currently visible component
     */
    public Component getCurrentComponent() {
        return (Component) getState().currentComponent;
    }

    /**
     * Show given component in panel. Will add to panel if not added yet.
     * 
     * @param component
     *            Component shown in panel.
     */
    public void showComponent(Component component) {

        if (component == null) {
            component = createDefaultContent();
        }

        addComponent(component);

        if (getCurrentComponent() != component) {
            getState().currentComponent = component;
        }
    }

    @Override
    public void beforeClientResponse(boolean initial) {
        if (getState().currentComponent == null) {
            if (this.getComponentCount() == 0) {
                showComponent(null);
            } else {
                showComponent(components.iterator().next());
            }
        }

        super.beforeClientResponse(initial);
    }

    @Override
    /**
     * Add child to current content (use setContent to add direct child to this
     * instance)
     */
    public void addComponent(Component c) {
        if (components.contains(c)) {
            return;
        }

        components.add(c);

        try {
            super.addComponent(c);
            markAsDirty();

            if (c != placeHolderComponent && placeHolderComponent != null) {
                removeComponent(placeHolderComponent);
                placeHolderComponent = null;
            }

        } catch (IllegalArgumentException e) {
            components.remove(c);
            throw e;
        }
    }

    @Override
    /**
     * Removes all components
     */
    public void removeAllComponents() {
        super.removeAllComponents();
        components.clear();
        getState().currentComponent = null;
        markAsDirty();
    }

    @Override
    public void removeComponent(Component c) {
        if (!components.remove(c)) {
            System.err.println("Can not remove unknown component");
            return;
        } else {
            super.removeComponent(c);
            if (getState().currentComponent != c) {
                resolveNewCurrent();
            }
        }
    }

    protected void resolveNewCurrent() {
        if (components.isEmpty()) {
            getState().currentComponent = null;
        } else {
            showComponent(components.iterator().next());
        }
    }

    @Override
    protected ActionManager getActionManager() {
        if (actionManager == null) {
            // actionManager = new ActionManager(this);
        }
        return actionManager;
    }

    @Override
    public void replaceComponent(Component oldComponent, Component newComponent) {

        boolean showNew = (getCurrentComponent() == oldComponent);

        if (showNew) {
            showComponent(newComponent);
            removeComponent(oldComponent);
        } else {
            removeComponent(oldComponent);
            addComponent(newComponent);
        }
    }

    /**
     * Set FancyPanel scrollable
     * 
     * @param scrollable
     *            true to make panel scrollable
     */
    public void setScrollable(boolean scrollable) {
        getState().scrollable = scrollable;
    }

    /**
     * Check if FancyPanel is scrollable
     * 
     * @return true if scrollable
     */
    public boolean isScrollable() {
        return getState().scrollable;
    }

    /**
     * Enabled or disable horizontal transition
     * 
     * @param enabled
     *            true to enable, false to disable
     */
    public void setRotateTransition(boolean enabled) {
        setRotateTransition(enabled, true);
    }

    /**
     * Enable disable rotate transition. When this transition is enabled
     * conflicting transition will be automatically disabled.
     * 
     * @param enabled
     *            true to enable, false to disable.
     * @param horizontal
     *            true to rotate horizontal, false to rotate vertical. If not
     *            enabled then this value is ignored.
     */
    public void setRotateTransition(boolean enabled, boolean horizontal) {
        if (enabled) {
            setZoomTransition(false);
            getState().rotateTransition = (horizontal ? RotateDirection.HORIZONTAL : RotateDirection.VERTICAL);
        } else {
            getState().rotateTransition = RotateDirection.NONE;
        }
    }

    /**
     * Check if rotate transition is enabled
     * 
     * @return true if enabled
     */
    public boolean isRotateTransition() {
        return getState().rotateTransition != RotateDirection.NONE;
    }

    /**
     * Enable disable fade transition. When this transition is enabled
     * conflicting transition will be automatically disabled.
     * 
     * @param enabled
     *            true to enable, false to disable.
     */
    public void setFadeTransition(boolean enabled) {
        getState().fadeTransition = enabled;
    }

    /**
     * Check if fade transition is enabled
     * 
     * @return
     */
    public boolean isFadeTransition() {
        return getState().fadeTransition;
    }

    /**
     * Enable disable zoom transition. When this transition is enabled
     * conflicting transition will be automatically disabled.
     * 
     * @param enabled
     *            true to enable, false to disable.
     */
    public void setZoomTransition(boolean enabled) {
        if (enabled) {
            setRotateTransition(false);
        }

        getState().zoomTransition = enabled;
    }

    public boolean isZoomTransition() {
        return getState().zoomTransition;
    }

    @Override
    public int getComponentCount() {
        return components.size();
    }

    @Override
    public Iterator<Component> iterator() {
        return components.iterator();
    }

    @Override
    public void componentDetachedFromContainer(ComponentDetachEvent event) {
        Component component = event.getDetachedComponent();
        if (components.contains(component)) {
            fireComponentDetachEvent(component);
        }
    }

    @Override
    public void componentAttachedToContainer(ComponentAttachEvent event) {
        Component component = event.getAttachedComponent();
        if (components.contains(component)) {
            fireComponentAttachEvent(component);
        }
    }

    /**
     * If components are automatically removed when replaced
     * 
     * @param remove
     *            true to have auto remove enabled
     */
    public void setAutoRemove(boolean remove) {
        getState().autoRemove = remove;
    }

    public boolean isAutoRemove() {
        return getState().autoRemove;
    }

    @Override
    public void addLayoutClickListener(LayoutClickListener listener) {
        addListener(EventId.LAYOUT_CLICK_EVENT_IDENTIFIER, LayoutClickEvent.class, listener,
                LayoutClickListener.clickMethod);
    }

    @Override
    @Deprecated
    public void addListener(LayoutClickListener listener) {
        addLayoutClickListener(listener);
    }

    @Override
    public void removeLayoutClickListener(LayoutClickListener listener) {
        removeListener(EventId.LAYOUT_CLICK_EVENT_IDENTIFIER, LayoutClickEvent.class, listener);
    }

    @Override
    @Deprecated
    public void removeListener(LayoutClickListener listener) {
        removeLayoutClickListener(listener);
    }

}