/* Groupbox.java
Purpose:
Description:
History:
Fri Jul 29 16:55:24 2005, Created by tomyeh
Copyright (C) 2005 Potix Corporation. All Rights Reserved.
{{IS_RIGHT
This program is distributed under LGPL Version 2.1 in the hope that
it will be useful, but WITHOUT ANY WARRANTY.
}}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.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.impl.XulElement;
/**
* Groups a set of child elements to have a visual effect.
* <p>Default {@link #getZclass}: "z-groupbox". If {@link #getMold()} is 3d,
* "z-groupbox-3d" is assumed.(since 3.5.0)
*
* <p>Events: onOpen.
*
* @author tomyeh
*/
public class Groupbox extends XulElement {
private transient Caption _caption;
/** The style used for the content block. */
private String _cntStyle;
/** The style class used for the content block. */
private String _cntSclass;
private String _title = "";
private boolean _open = true, _closable = true;
static {
addClientEvent(Groupbox.class, Events.ON_OPEN, CE_IMPORTANT);
}
/** Returns the caption of this groupbox.
*/
public Caption getCaption() {
return _caption;
}
/** Returns whether this groupbox is open.
*
* <p>Default: true.
*/
public boolean isOpen() {
return _open;
}
/** Opens or closes this groupbox.
*/
public void setOpen(boolean open) {
if (_open != open) {
_open = open;
smartUpdate("open", _open);
}
}
/** Returns whether user can open or close the group box.
* In other words, if false, users are no longer allowed to
* change the open status (by clicking on the title).
*
* <p>Default: true.
*/
public boolean isClosable() {
return _closable;
}
/** Sets whether user can open or close the group box.
*/
public void setClosable(boolean closable) {
if (_closable != closable) {
_closable = closable;
smartUpdate("closable", closable);
}
}
// super
protected void renderProperties(org.zkoss.zk.ui.sys.ContentRenderer renderer) throws java.io.IOException {
super.renderProperties(renderer);
render(renderer, "contentStyle", _cntStyle);
render(renderer, "contentSclass", _cntSclass);
render(renderer, "title", _title);
if (!_open)
renderer.render("open", false);
if (!_closable)
renderer.render("closable", false);
}
public String getZclass() {
return _zclass == null ? "default".equals(getMold()) ? "z-groupbox" : "z-groupbox-3d" : _zclass;
}
/** Returns the CSS style for the content block of the groupbox.
* Used only if {@link #getMold} is not default.
*/
public String getContentStyle() {
return _cntStyle;
}
/** Sets the CSS style for the content block of the groupbox.
* Used only if {@link #getMold} is not default.
*
* <p>Default: null.
*/
public void setContentStyle(String style) {
if (!Objects.equals(_cntStyle, style)) {
_cntStyle = style;
smartUpdate("contentStyle", _cntStyle);
}
}
/** Returns the style class used for the content block of the groupbox.
* Used only if {@link #getMold} is not default.
*/
public String getContentSclass() {
return _cntSclass;
}
/** Sets the style class used for the content block.
*
* @see #getContentSclass
* @since 3.0.0
*/
public void setContentSclass(String scls) {
if (!Objects.equals(_cntSclass, scls)) {
_cntSclass = scls;
smartUpdate("contentSclass", _cntSclass);
}
}
/** Returns the title.
* Besides this attribute, you could use {@link Caption} to define
* a more sophisticated caption (a.k.a., title).
* <p> It will be displayed before caption.
* <p>Default: empty.
* @since 6.0.0
*/
public String getTitle() {
return _title;
}
/** Sets the title.
* @since 6.0.0
*/
public void setTitle(String title) {
if (title == null)
title = "";
if (!Objects.equals(_title, title)) {
_title = title;
smartUpdate("title", title);
}
}
/** @deprecated As of release 6.0, legend no longer used in groupbox.
*/
public boolean isLegend() {
return "default".equals(getMold());
}
/** @deprecated As of release 6.0, legend no longer used in groupbox.
*/
public void setLegend(boolean legend) {
if (legend && "3d".equals(getMold()))
setMold("default");
else if (!legend && "default".equals(getMold()))
setMold("3d");
}
//-- Component --//
public void beforeChildAdded(Component child, Component refChild) {
if (child instanceof Caption) {
if (_caption != null && _caption != child)
throw new UiException("Only one caption is allowed: " + this);
} else if (refChild instanceof Caption) {
throw new UiException("caption must be the first child");
}
super.beforeChildAdded(child, refChild);
}
public boolean insertBefore(Component child, Component refChild) {
if (child instanceof Caption) {
refChild = getFirstChild();
//always makes caption as the first child
if (super.insertBefore(child, refChild)) {
_caption = (Caption) child;
return true;
}
} else {
return super.insertBefore(child, refChild);
}
return false;
}
public void onChildRemoved(Component child) {
if (child instanceof Caption)
_caption = null;
super.onChildRemoved(child);
}
//-- 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);
}
//Cloneable//
public Object clone() {
final Groupbox clone = (Groupbox) super.clone();
if (_caption != null)
clone.afterUnmarshal();
return clone;
}
/** @param cnt # of children that need special handling (used for optimization).
* -1 means process all of them
*/
private void afterUnmarshal() {
for (Component child : getChildren())
if (child instanceof Caption) {
_caption = (Caption) child;
break; //done
}
}
//Serializable//
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
afterUnmarshal();
}
}