001: /* Radio.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Fri Jun 17 09:20:52 2005, Created by tomyeh
010: }}IS_NOTE
011:
012: Copyright (C) 2005 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zul;
020:
021: import org.zkoss.lang.Objects;
022: import org.zkoss.xml.HTMLs;
023:
024: import org.zkoss.zk.ui.Component;
025: import org.zkoss.zk.ui.UiException;
026:
027: /**
028: * A radio button.
029: *
030: * <p>Radio buttons without a ancestor {@link Radiogroup} is considered
031: * as the same group.
032: * The nearest ancestor {@link Radiogroup} is the group that the radio
033: * belongs to. See also {@link #getRadiogroup}.
034: *
035: * <p>Event:
036: * <ol>
037: * <li>{@link org.zkoss.zk.ui.event.CheckEvent} is sent when a checkbox
038: * is checked or unchecked by user.</li>
039: * </ol>
040: *
041: * @author tomyeh
042: */
043: public class Radio extends Checkbox {
044: private String _value = "";
045:
046: public Radio() {
047: }
048:
049: public Radio(String label) {
050: super (label);
051: }
052:
053: public Radio(String label, String image) {
054: super (label, image);
055: }
056:
057: /** Returns {@link Radiogroup} that this radio button belongs to.
058: * It is the nearest ancestor {@link Radiogroup}.
059: * In other words, it searches up the parent, parent's parent
060: * and so on for any {@link Radiogroup} instance.
061: * If found this radio belongs the found radiogroup.
062: * If not, this radio itself is a group.
063: */
064: public Radiogroup getRadiogroup() {
065: for (Component p = this ;;) {
066: Component q = p.getParent();
067: if ((q instanceof Radiogroup) || q == null)
068: return (Radiogroup) q;
069: p = q;
070: }
071: }
072:
073: /** Returns whether it is selected.
074: * <p>Default: false.
075: * <p>Don't override this. Override {@link #isChecked} instead.
076: */
077: public final boolean isSelected() {
078: return isChecked();
079: }
080:
081: /** Sets whether it is selected.
082: * <p>Don't override this. Override {@link #setChecked} instead.
083: * <p>The same as {@link #setChecked}.
084: */
085: public final void setSelected(boolean selected) {
086: setChecked(selected);
087: }
088:
089: /** Sets the radio is checked and unchecked the others in the same radio
090: * group ({@link Radiogroup}.
091: */
092: public void setChecked(boolean checked) {
093: if (checked != isChecked()) {
094: super .setChecked(checked);
095: fixSiblings(checked, false);
096: }
097: }
098:
099: /** Make sure only one of them is checked. */
100: private void fixSiblings(boolean checked, boolean byclient) {
101: final Radiogroup group = getRadiogroup();
102: if (group != null) {
103: if (checked) {
104: final Radio sib = group.getSelectedItem();
105: if (sib != null && sib != this ) {
106: if (byclient)
107: ((ExtraCtrl) sib.getExtraCtrl())
108: .setCheckedByClient(false);
109: else
110: sib.setChecked(false); //and fixSelectedIndex
111: return;
112: }
113: }
114: group.fixSelectedIndex();
115: }
116: }
117:
118: /** Returns the value.
119: * <p>Default: "".
120: */
121: public String getValue() {
122: return _value;
123: }
124:
125: /** Sets the value.
126: * @param value the value; If null, it is considered as empty.
127: */
128: public void setValue(String value) {
129: if (value == null)
130: value = "";
131: if (!Objects.equals(_value, value)) {
132: _value = value;
133: smartUpdate("value", _value);
134: }
135: }
136:
137: /** Returns the name of this radio button.
138: * <p>Don't use this method if your application is purely based
139: * on ZK's event-driven model.
140: * <p>It is readonly, and it is generated automatically
141: * to be the same as its parent's name ({@link Radiogroup#getName}).
142: */
143: public final String getName() {
144: final Radiogroup group = getRadiogroup();
145: return group != null ? group.getName() : getUuid();
146: }
147:
148: /** Returns the inner attributes for generating the HTML radio tag
149: * (the name and value attribute).
150: * <p>Used only by component developers.
151: */
152: public String getInnerAttrs() {
153: final StringBuffer sb = new StringBuffer(64).append(super
154: .getInnerAttrs());
155: HTMLs.appendAttribute(sb, "value", getValue());
156: return sb.toString();
157: }
158:
159: //-- Component --//
160: public void setParent(Component parent) {
161: final Radiogroup oldgp = getRadiogroup();
162: super .setParent(parent);
163:
164: final Radiogroup newgp = getRadiogroup();
165: if (oldgp != newgp) {
166: if (oldgp != null)
167: oldgp.fixOnRemove(this );
168: if (newgp != null)
169: newgp.fixOnAdd(this );
170: }
171: }
172:
173: //-- ComponentCtrl --//
174: protected Object newExtraCtrl() {
175: return new ExtraCtrl();
176: }
177:
178: /** A utility class to implement {@link #getExtraCtrl}.
179: * It is used only by component developers.
180: */
181: protected class ExtraCtrl extends Checkbox.ExtraCtrl {
182: //-- Checkable --//
183: public void setCheckedByClient(boolean checked) {
184: super .setCheckedByClient(checked);
185: fixSiblings(checked, true);
186: }
187: }
188: }
|