001: /*
002: * Copyright 2007 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.user.client.ui;
017:
018: import com.google.gwt.user.client.DOM;
019: import com.google.gwt.user.client.Element;
020:
021: /**
022: * A standard check box widget (also serves as a base class for
023: * {@link com.google.gwt.user.client.ui.RadioButton}.
024: * <p>
025: * <img class='gallery' src='CheckBox.png'/>
026: * </p>
027: * <h3>CSS Style Rules</h3>
028: * <ul class='css'>
029: * <li>.gwt-CheckBox { }</li>
030: * <li>.gwt-CheckBox-disabled { Applied when Checkbox is disabled }</li>
031: * </ul>
032: * <p>
033: * <h3>Example</h3>
034: * {@example com.google.gwt.examples.CheckBoxExample}
035: * </p>
036: */
037: public class CheckBox extends ButtonBase implements HasName {
038: private static int uniqueId;
039: private Element inputElem, labelElem;
040:
041: /**
042: * Creates a check box with no label.
043: */
044: public CheckBox() {
045: this (DOM.createInputCheck());
046: setStyleName("gwt-CheckBox");
047: }
048:
049: /**
050: * Creates a check box with the specified text label.
051: *
052: * @param label the check box's label
053: */
054: public CheckBox(String label) {
055: this ();
056: setText(label);
057: }
058:
059: /**
060: * Creates a check box with the specified text label.
061: *
062: * @param label the check box's label
063: * @param asHTML <code>true</code> to treat the specified label as html
064: */
065: public CheckBox(String label, boolean asHTML) {
066: this ();
067: if (asHTML) {
068: setHTML(label);
069: } else {
070: setText(label);
071: }
072: }
073:
074: protected CheckBox(Element elem) {
075: super (DOM.createSpan());
076: inputElem = elem;
077: labelElem = DOM.createLabel();
078:
079: // Hook events to input widget rather than the check box element.
080: DOM.sinkEvents(inputElem, DOM.getEventsSunk(this .getElement()));
081: DOM.sinkEvents(this .getElement(), 0);
082: DOM.appendChild(getElement(), inputElem);
083: DOM.appendChild(getElement(), labelElem);
084:
085: String uid = "check" + (++uniqueId);
086: DOM.setElementProperty(inputElem, "id", uid);
087: DOM.setElementProperty(labelElem, "htmlFor", uid);
088: }
089:
090: @Override
091: public String getHTML() {
092: return DOM.getInnerHTML(labelElem);
093: }
094:
095: public String getName() {
096: return DOM.getElementProperty(inputElem, "name");
097: }
098:
099: @Override
100: public int getTabIndex() {
101: return getFocusImpl().getTabIndex(inputElem);
102: }
103:
104: @Override
105: public String getText() {
106: return DOM.getInnerText(labelElem);
107: }
108:
109: /**
110: * Determines whether this check box is currently checked.
111: *
112: * @return <code>true</code> if the check box is checked
113: */
114: public boolean isChecked() {
115: String propName = isAttached() ? "checked" : "defaultChecked";
116: return DOM.getElementPropertyBoolean(inputElem, propName);
117: }
118:
119: @Override
120: public boolean isEnabled() {
121: return !DOM.getElementPropertyBoolean(inputElem, "disabled");
122: }
123:
124: @Override
125: public void setAccessKey(char key) {
126: DOM.setElementProperty(inputElem, "accessKey", "" + key);
127: }
128:
129: /**
130: * Checks or unchecks this check box.
131: *
132: * @param checked <code>true</code> to check the check box
133: */
134: public void setChecked(boolean checked) {
135: DOM.setElementPropertyBoolean(inputElem, "checked", checked);
136: DOM.setElementPropertyBoolean(inputElem, "defaultChecked",
137: checked);
138: }
139:
140: @Override
141: public void setEnabled(boolean enabled) {
142: DOM.setElementPropertyBoolean(inputElem, "disabled", !enabled);
143: if (enabled) {
144: removeStyleDependentName("disabled");
145: } else {
146: addStyleDependentName("disabled");
147: }
148: }
149:
150: @Override
151: public void setFocus(boolean focused) {
152: if (focused) {
153: getFocusImpl().focus(inputElem);
154: } else {
155: getFocusImpl().blur(inputElem);
156: }
157: }
158:
159: @Override
160: public void setHTML(String html) {
161: DOM.setInnerHTML(labelElem, html);
162: }
163:
164: public void setName(String name) {
165: DOM.setElementProperty(inputElem, "name", name);
166: }
167:
168: @Override
169: public void setTabIndex(int index) {
170: getFocusImpl().setTabIndex(inputElem, index);
171: }
172:
173: @Override
174: public void setText(String text) {
175: DOM.setInnerText(labelElem, text);
176: }
177:
178: /**
179: * This method is called when a widget is attached to the browser's document.
180: * onAttach needs special handling for the CheckBox case. Must still call
181: * {@link Widget#onAttach()} to preserve the <code>onAttach</code> contract.
182: */
183: @Override
184: protected void onLoad() {
185: // Sets the event listener on the inputElem, as in this case that's the
186: // element we want so input on.
187: DOM.setEventListener(inputElem, this );
188: }
189:
190: /**
191: * This method is called when a widget is detached from the browser's
192: * document. Overridden because of IE bug that throws away checked state and
193: * in order to clear the event listener off of the <code>inputElem</code>.
194: */
195: @Override
196: protected void onUnload() {
197: // Clear out the inputElem's event listener (breaking the circular
198: // reference between it and the widget).
199: DOM.setEventListener(inputElem, null);
200: setChecked(isChecked());
201: }
202:
203: /**
204: * Replace the current input element with a new one.
205: *
206: * @param elem the new input element
207: */
208: protected void replaceInputElement(Element elem) {
209: // Collect information we need to set
210: int tabIndex = getTabIndex();
211: boolean checked = isChecked();
212: boolean enabled = isEnabled();
213: String uid = DOM.getElementProperty(inputElem, "id");
214: String accessKey = DOM.getElementProperty(inputElem,
215: "accessKey");
216:
217: // Clear out the old input element
218: setChecked(false);
219: DOM.setElementProperty(inputElem, "id", "");
220: DOM.setElementProperty(inputElem, "accessKey", "");
221: DOM.setEventListener(inputElem, null);
222:
223: // Quickly do the physical replace
224: DOM.removeChild(getElement(), inputElem);
225: DOM.insertChild(getElement(), elem, 0);
226:
227: // Sink events on the new element
228: DOM.sinkEvents(elem, DOM.getEventsSunk(inputElem));
229: DOM.sinkEvents(inputElem, 0);
230: inputElem = elem;
231:
232: // Setup the new element
233: DOM.setElementProperty(inputElem, "id", uid);
234: if (accessKey != "") {
235: DOM.setElementProperty(inputElem, "accessKey", accessKey);
236: }
237: setTabIndex(tabIndex);
238: setChecked(checked);
239: setEnabled(enabled);
240:
241: // Set the event listener
242: if (isAttached()) {
243: DOM.setEventListener(inputElem, this);
244: }
245: }
246: }
|