zul/src/main/java/org/zkoss/zul/Splitter.java

Summary

Maintainability
A
1 hr
Test Coverage
/* Splitter.java

{{IS_NOTE
    Purpose:
        
    Description:
        
    History:
        Thu Jun  8 14:54:05     2006, Created by tomyeh
}}IS_NOTE

Copyright (C) 2006 Potix Corporation. All Rights Reserved.

{{IS_RIGHT
}}IS_RIGHT
*/
package org.zkoss.zul;

import org.zkoss.lang.Objects;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.impl.XulElement;

/**
 * An element which should appear before or after an element inside a box
 * ({@link Box}, {@link Vbox} and {@link Hbox}).
 *
 * <p>When the splitter is dragged, the sibling elements of the splitter are
 * resized. If {@link #getCollapse} is true, a grippy is placed
 * inside the splitter, and one sibling element of the splitter is collapsed
 * when the grippy is clicked.
 *
 * <p>Events: onOpen
 *
 * <p>Default {@link #getZclass}: z-splitter.
 * 
 * @author tomyeh
 */
public class Splitter extends XulElement {
    private String _collapse = "none";
    private boolean _open = true;

    static {
        addClientEvent(Splitter.class, Events.ON_OPEN, CE_IMPORTANT);
    }

    public Splitter() {
    }

    /** Returns if the orientation of this splitter is vertical.
     * @since 5.0.0
     */
    public boolean isVertical() {
        final Box box = (Box) getParent();
        return box == null || box.isVertical();
    }

    /** Returns if the orientation of this splitter is horizontal.
     * @since 5.0.0
     */
    public boolean isHorizontal() {
        final Box box = (Box) getParent();
        return box != null && box.isHorizontal();
    }

    /** Returns the orientation of the splitter.
     * It is the same as the parent's orientation ({@link Box#getOrient}.
     */
    public String getOrient() {
        final Box box = (Box) getParent();
        return box != null ? box.getOrient() : "vertical";
    }

    /** Returns which side of the splitter is collapsed when its grippy
     * is clicked. If this attribute is not specified, the splitter will
     * not cause a collapse.
     * If it is collapsed, {@link #isOpen} returns false.
     *
     * <p>Default: none.
     *
     * <p>The returned value can be one of the following.
     *
     * <dl>
     * <dt>none</dt>
     * <dd>No collapsing occurs.</dd>
     * <dt>before</dt>
     * <dd>When the grippy is clicked, the element immediately
     * before the splitter in the same parent is collapsed so that
     * its width or height is 0.</dd>
     * <dt>after</dt>
     * <dd>When the grippy is clicked, the element immediately
     * after the splitter in the same parent is collapsed so that
     * its width or height is 0.</dd>
     * </dl>
     *
     * <p>Unlike XUL, you don't have to put a so-called grippy component
     * as a child of the splitter.
     */
    public String getCollapse() {
        return _collapse;
    }

    /** Sets which side of the splitter is collapsed when its grippy
     * is clicked. If this attribute is not specified, the splitter will
     * not cause a collapse.
     *
     * @param collapse one of none, before and after.
     * If null or empty is specified, none is assumed.
     * @see #getCollapse
     */
    public void setCollapse(String collapse) throws WrongValueException {
        if (collapse == null || collapse.length() == 0)
            collapse = "none";
        else if (!"none".equals(collapse) && !"before".equals(collapse) && !"after".equals(collapse))
            throw new WrongValueException("Unknown collpase: " + collapse);

        if (!Objects.equals(_collapse, collapse)) {
            _collapse = collapse;
            smartUpdate("collapse", collapse);
        }
    }

    /** Returns whether it is open (i.e., not collapsed.
     * Meaningful only if {@link #getCollapse} is not "none".
     */
    public boolean isOpen() {
        return _open;
    }

    /** Opens or collapses the splitter.
     * Meaningful only if {@link #getCollapse} is not "none".
     */
    public void setOpen(boolean open) {
        if (_open != open) {
            _open = open;
            smartUpdate("open", open);
        }
    }

    //super//
    public void beforeParentChanged(Component parent) {
        if (parent != null && !(parent instanceof Box))
            throw new UiException("Wrong parent: " + parent);
        super.beforeParentChanged(parent);
    }

    /** Not allow any children.
     */
    protected boolean isChildable() {
        return false;
    }

    protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) throws java.io.IOException {
        super.renderProperties(renderer);

        if (!_open)
            renderer.render("open", false);
        if (!"none".equals(_collapse))
            render(renderer, "collapse", _collapse);
    }

    public String getZclass() {
        return _zclass != null ? _zclass : "z-splitter";
    }

    //-- ComponentCtrl --//
    /** Processes an AU request.
     *
     * <p>Default: in addition to what are handled by {@link XulElement#service},
     * it also handles onOpen.
     * @since 5.0.0
     */
    public void service(org.zkoss.zk.au.AuRequest request, boolean everError) {
        final String cmd = request.getCommand();
        if (cmd.equals(Events.ON_OPEN)) {
            OpenEvent evt = OpenEvent.getOpenEvent(request);
            _open = evt.isOpen();
            Events.postEvent(evt);
        } else
            super.service(request, everError);
    }
}