001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package com.sun.rave.web.ui.component;
042:
043: import java.io.IOException;
044: import javax.faces.component.UIComponent;
045: import javax.faces.context.FacesContext;
046: import javax.faces.el.MethodBinding;
047: import javax.faces.el.ValueBinding;
048:
049: /**
050: * <p>
051: * Use the <code>ui:radioButton</code> tag to display a radio button
052: * in the rendered HTML page. The tag can be used as a single
053: * radio button or as one radio button among a group of radio buttons.
054: * A group of radio buttons represents a single selection list.
055: * A radio button can represent a value of a class type such as
056: * <code>Boolean, Byte, Character, Double,
057: * Float, Integer, Long, Short, String</code> or the primitive form of one of
058: * these class types. A radio button may also represent an application defined
059: * object value.
060: * </p>
061: * A <code>Boolean</code> value is useful for indicating whether
062: * an item, such as a table row, is selected. A <code>String</code>
063: * value is useful for passing a value for the radio button selection made in the
064: * interface. An application defined <code>Object</code> value or class
065: * instance can be used to hold more information related to the radio button
066: * selection.
067: * </p>
068: * <p>
069: * A group of radio buttons is the common way to use the the
070: * <code>radioButton</code> tag. It can be used to represent different
071: * types of data:
072: * </p>
073: * <ul>
074: * <li>a group of boolean controls where only one control is selected at a
075: * time.</li>
076: * <li>string values that are related to the radio button selection</li>
077: * <li>object values defined by the application</li>
078: * </ul>
079: * <p><em>
080: * Note: It is not common to use a <code>radioButton</code> tag that is not
081: * in a group. If a single radio button is not in a group, once it
082: * is selected by the user in the interface, the user cannot deselect it.
083: * This is because a radio button is defined to be a single selection
084: * among several where one radio button is always selected. Since there
085: * are no other radio buttons grouped with the single radio button, the user
086: * cannot select an alternative, to cause the selected
087: * radio button to be deselected.
088: * </em></p>
089: * <p>
090: * Note: Another tag for rendering radio buttons is
091: * <code>ui:radioButtonGroup</code>, which imposes a grid layout on a group
092: * of radio buttons. The <code>radioButton</code> tag is useful in
093: * situations where the <code>radioButtonGroup</code> tag layout is not
094: * desirable, such as in a table row where only one row among several may be
095: * selected.
096: * </p>
097: * <h3>Detecting a selected radio button</h3>
098: * <p>
099: * The <code>radioButton</code> tag uses both the <code>selected</code>
100: * and <code>selectedValue</code> attributes to pass information about
101: * the radio button's selection status. The <code>selected</code>
102: * attribute is used to indicate that the radio button is selected, and should
103: * have a check mark displayed in the page. The <code>selectedValue</code>
104: * attribute is used to pass a data value for the
105: * radio button. A radio button is considered to be selected when the value of the
106: * <code>selected</code> attribute is equal to the value of
107: * the <code>selectedValue</code> attribute. You can display a radio button as
108: * selected on the initial viewing of the page by assigning the same value
109: * to the <code>selectedValue</code> and the <code> selected</code> attributes.
110: * </p>
111: * <p>
112: * If the <code>selectedValue</code> attribute is not specified or its
113: * value is <code>null</code> then the radio button behaves like a
114: * boolean control. If the radio button is selected, the value of the
115: * <code>selected</code> attribute is a true <code>Boolean</code>
116: * instance. If the radio button is not selected, the value of the
117: * <code>selected</code> attribute will be a false <code>Boolean</code>
118: * instance.
119: * </p>
120: * <p><em>
121: * Note that a value binding expression that evaluates to a
122: * primitive boolean value can be assigned to the <code>selected</code>
123: * and <code>selectedValue</code> attributes.
124: * </em>
125: * </p>
126: * <p>
127: * When a radio button is part of a group, the value of the selected
128: * radio button is maintained as a request attribute value in the
129: * <code>RequestMap</code>. The attribute name is the value of the
130: * <code>name</code> attribute. The value of the request attribute
131: * is the value of the <code>selectedValue</code> attribute of the
132: * selected radio button. The value of the <code>selected</code> attribute
133: * will also be equal to the <code>selectedValue</code> attribute of the
134: * selected radio button. If no radio button is selected, no request
135: * attribute will be created.<br>
136: * The <code>RadioButton</code> class provides a convenience method for
137: * obtaining the selected radio button in a group:
138: * </p>
139: * <p>
140: * public static Object getSelected(String groupName);
141: * </p>
142: * <p> where <code>groupName</code> is the value of the <code>name</code>
143: * attribtue. Note that unlike the <code>selected</code> and
144: * <code>selectedValue</code> attributes, the return value of this method
145: * is always a class instance and not a primitive value.
146: * </p>
147: * <p><em>
148: * Note that the <code>radioButton</code> does not enforce that
149: * at least one radio button is always be selected.
150: * The application must ensure this behavior if necessary.
151: * </em></p>
152: * <h3>Using a <code>radioButton</code> tag as a boolean control</h3>
153: * <p>
154: * If the <code>selectedValue</code> attribute is not specified or its
155: * value is <code>null</code> then the radio button behaves like a
156: * boolean control.
157: * </p>
158: * <p>
159: * To use the <code>radioButton</code> tag as a boolean control, do not
160: * specify a value for the <code>selectedValue</code> attribute. The
161: * radio button is selected if the <code>selected</code> attribute is not
162: * null and has the value of a true <code>Boolean</code> instance or
163: * <code>boolean</code> primitive. If the radio button is not selected,
164: * then the value of the <code>selected</code> attribute is a false
165: * <code>Boolean</code> instance or <code>boolean</code> primitive.
166: * </p>
167: * <p>
168: * Normally the value of the <code>selectedValue</code> attribute is
169: * specified as the value of the <input> HTML element. When a
170: * radio button is behaving as a boolean control the value of the <input>
171: * element is the <code>clientId</code> of the radio button.
172: * </p>
173: * <p><em>
174: * Note that using a boolean radio button in a group and
175: * referencing the request attribute for the selected radio button is not
176: * useful, since the value of the request attribute will be an
177: * indistinguishable <code>Boolean</code> <code>true</code> value.</em>
178: * </p>
179: * <h3>Using a <code>radioButton</code> tag to represent an application defined
180: * value</h3>
181: * <p>
182: * The <code>selectedValue</code> attribute can be assigned an
183: * application defined object value to represent the value of a selected
184: * radio button. If the radio button is selected, the value of the
185: * <code>selected</code> attribute is assigned the value of the
186: * <code>selectedValue</code> attribute.
187: * </p>
188: * <p>
189: * If the value of the <code>selectedValue</code> attribute is an
190: * application defined object, a converter must be registered
191: * to convert to and from a <code>String</code> value. The
192: * converter is used to encode the radio button value
193: * as the value of the HTML <input> element and to decode the
194: * submitted value in a request. In addition the object must support an
195: * <code>equals</code> method that returns <code>true</code> when the
196: * value of the <code>selectedValue</code> attribute is compared to
197: * the <code>selected</code> attribute value in order to detect a
198: * selected radio button.
199: * </p>
200: * <h3>Using a <code>radioButton</code> tag as one control in a group</h3>
201: * <p>
202: * The <code>name</code> attribute determines whether a
203: * radio button is part of a group. A radio button is treated as part of a group
204: * of radio buttons if the <code>name</code> attribute of the radio button is
205: * assigned a value equal to the <code>name</code> attribute of the other
206: * radio buttons in the group. In other words, all radio buttons of a group
207: * have the same <code>name</code> attribute value. The group behaves
208: * like a single selection list, where only one radio button
209: * can be selected. The value of the name attribute must
210: * be unique within the scope of the <form> element containing the
211: * radio buttons.
212: * </p>
213: *
214: * <h3>Facets</h3>
215: * <p>
216: * The following facets are supported:
217: * <ul>
218: * <li><em>image</em> If the image facet exists, it is rendered to the
219: * immediate right hand side of the radio button.
220: * <li><em>label</em> If the label facet exists, it is rendered to the
221: * immediate right of the image, or to the immediate right of the
222: * radio button if no image is rendered.
223: * </ul>
224: * </p>
225: * <h3>Examples</h3>
226: * <h4>Example 1: Two grouped boolean radio buttons with value bindings.</h4>
227: * <code>
228: * <ui:radioButton id="rb0" name="rb1grp"
229: * selected="#{tldRbCbExample.selectedRb0}"/><br/>
230: * <br/><br/>
231: * <ui:radioButton id="rb1" name="rb1grp"
232: * selected="#{tldRbCbExample.selectedRb1}"/>
233: * </code>
234: * <p>
235: * The value bindings imply that
236: * there are two methods implemented in the <code>tldRbCbExample</code>
237: * managed bean for each value binding.
238: * </p>
239: * <ul>
240: * <li>public void setSelectedRb0(boolean selected)</li>
241: * <li>public boolean getSelectedRb0()</li>
242: * <li>public void setSelectedRb1(boolean selected)</li>
243: * <li>public boolean getSelectedRb1()</li>
244: * </ul>
245: * <p>
246: * The "getSelected" methods will be called to determine the checked
247: * state of the radio buttons during rendering.<br/>
248: * When the tags are first rendered, the initial checked state is
249: * determined by the return value of the "getSelected" methods, only one of
250: * which should return true.
251: * The radio button whose "getSelected" method returns
252: * <code>true</code> will be checked in the HTML page and not checked if it
253: * returns <code>false</code>.
254: * When one of the radio buttons is checked by the user its "setSelected" method
255: * will be called with a <code>boolean</code> argument equal to <code>true</code>.
256: * The other radio button's "setSelected" method will be called
257: * with a <code>boolean</code> argument equal to <code>false</code>.<br/>
258: * </p>
259: * <p>
260: * No image or label will be displayed by this example.
261: * </p>
262: * <h4>Example 2: Two grouped boolean radio buttons with value bindings,
263: * that display an image and a label.</h4>
264: * <code>
265: * <ui:radioButton id="rb2" name="rb2grp"
266: * imageURL="tree_server.gif" label="Server"
267: * selected="#{tldRbCbExample.selectedRb2}"/><br/>
268: * <br/><br/>
269: * <ui:radioButton id="rb3" name="rb2grp"
270: * imageURL="pool_tree.gif" label="Pool"
271: * selected="#{tldRbCbExample.selectedRb3}"/>
272: * </code>
273: * <p>
274: * The behavior of these radio buttons is the same as example one.<br/>
275: * In this example an image and a label are displayed next to both
276: * radio buttons. Both
277: * the <code>imageURL</code> and <code>label</code> attributes may be assigned
278: * value binding expressions instead of literal values.
279: * </p>
280: * <h4>Example 3: Two grouped String valued radio buttons with value bindings
281: * and labels.</h4>
282: * <code>
283: * <ui:radioButton id="rb4" name="rb3grp"
284: * label="Print" selectedValue="Print"
285: * selected="#{tldRbCbExample.selectedRb4}"/><br/>
286: * <br/><br/>
287: * <ui:radioButton id="rb5" name="rb3grp"
288: * label="Fax" selectedValue="Fax"
289: * selected="#{tldRbCbExample.selectedRb5}"/>
290: * </code>
291: * <p>
292: * The value bindings imply that
293: * there are two methods implemented in the <code>tldRbCbExample</code>
294: * managed bean for each value binding.
295: * Because the <code>selectedValue</code> attribute is a
296: * <code>String</code> the expected method signatures will be:
297: * </p>
298: * <ul>
299: * <li>public void setSelectedRb4(String selected)</li>
300: * <li>public String getSelectedRb4()</li>
301: * <li>public void setSelectedRb5(String selected)</li>
302: * <li>public String getSelectedRb5()</li>
303: * </ul>
304: * <p>
305: * The "getSelected" methods will be called to determine the checked
306: * state of the radio buttons during rendering.<br/>
307: * When the tags are first rendered, the initial checked state is
308: * determined by the return value of the "getSelected" methods.<br/>
309: * With a <code>String</code> valued radio button, a radio button will
310: * be checked only if the "getSelected" method returns the value of its
311: * <code>selectedValue</code> attribute.<br/>
312: * For example if <code>getSelectedRb4</code> returns "Print", the
313: * radio button "rb4" will be checked. <code>getSelectedRb5</code> must
314: * not return "Fax" and should return <code>null</code> in order for "rb4" to
315: * remain checked.<br/>
316: * Alternatively if <code>getSelectedRb4</code> returns <code>null</code>
317: * <code>getSelectedRb5</code> should return "Fax", and radio button "rb5"
318: * will be checked.
319: * </p>
320: * <p>
321: * When the radio button is checked by the user the "setSelected"
322: * methods will be called with a <code>String</code> argument equal to the
323: * value of the <code>selectedValue</code> attribute of the radio button.<br/>
324: * When it is unchecked the method will be called with a <code>null</code>
325: * <code>String</code>
326: * argument.<br/>
327: * For example if radio button "rb4" is checked by the user
328: * <code>setSelectedRb4</code> will be called with "Print" as the argument and
329: * <code>setSelectedRb5</code> will be called with a <code>null</code> argument.
330: * </p>
331: * <h4>Example 4: Two grouped object valued radio buttons with value bindings
332: * and labels.</h4>
333: * <code>
334: * <ui:radioButton id="rb6" name="rb4grp" label="Print"
335: * selectedValue="#{tldRbCbExample.selectedValueRb6}"
336: * selected="#{tldRbCbExample.selectedRb6}"
337: * converter="#{tldRbCbExample.rbConverter}"/><br/>
338: * <br/><br/>
339: * <ui:radioButton id="rb7" name="rb4grp" label="Fax"
340: * selectedValue="#{tldRbCbExample.selectedValueRb7}"
341: * selected="#{tldRbCbExample.selectedRb7}"
342: * converter="#{tldRbCbExample.rbConverter}"/>
343: * </code>
344: * <p>
345: * The value bindings imply that
346: * there are two methods implemented in the <code>tldRbCbExample</code>
347: * managed bean for each value binding.
348: * Let's say the object value for "rb6" is an instance of the "Printer" class,
349: * and "rb7" an instance of the "Fax" class, then the expected
350: * method signatures will be:
351: * </p>
352: * <p>
353: * <ul>
354: * <li>public void setSelectedRb6(Printer selected)</li>
355: * <li>public Printer getSelectedRb6()</li>
356: * <li>public void setSelectedValueRb7(Fax selected)</li>
357: * <li>public Printer getSelectedValueRb7()</li>
358: * </ul>
359: * </p>
360: * A Printer class might look like:
361: * <p>
362: * <code><pre>
363: * public class Printer implements Device {
364: * private String name;
365: * private String location;
366: * public Printer(String name, String location) {
367: * this.name = name;
368: * this.location = location;
369: * }
370: * public String getName() {
371: * return name;
372: * }
373: * public String getLocation() {
374: * return location;
375: * }
376: * public int getType() {
377: * return Device.PRINTER;
378: * }
379: * public boolean equals(Printer p) {
380: * return this.name.equals(p.getName()) &&
381: * this.location.equals(p.getLocation()) &&
382: * p.getType() == Device.PRINTER;
383: * }
384: * };
385: * </pre>
386: * </code>
387: * </p>
388: * A Fax class might look like:
389: * <p>
390: * <code><pre>
391: * public class Fax implements Device {
392: * private String name;
393: * private String phoneNumber;
394: * public Printer(String name, String phoneNumber) {
395: * this.name = name;
396: * this.phoneNumber = phoneNumber;
397: * }
398: * public String getName() {
399: * return name;
400: * }
401: * public String getPhoneNumber() {
402: * return phoneNumber;
403: * }
404: * public int getType() {
405: * return Device.FAX;
406: * }
407: * public boolean equals(Fax f) {
408: * return this.name.equals(f.getName()) &&
409: * this.phoneNumber.equals(f.getPhoneNumber()) &&
410: * f.getType() == Device.FAX;
411: * }
412: * };
413: * </pre>
414: * </code>
415: * </p>
416: * <p>
417: * Since this radio button represents an application defined object value,
418: * the application must provide a converter instance. The converter attribute's
419: * value binding expression implies a method in the <code>tldRbCbExample</code>
420: * managed bean called
421: * </p>
422: * <p>
423: * <code>public Converter getRbConverter();</code>
424: * </p>
425: * The converter class might look like:
426: * <code><pre>
427: * public class RbConverter implements javax.faces.convert.Converter {
428: * public RbConverter() {
429: * }
430: * public String getAsString(FacesContext context,
431: * UIComponent component, Object value) {
432: * if (!value instanceof Device) {
433: * throw new ConverterException("Not a Device value");
434: * }
435: * return String.valueOf(((Device)value).getType());
436: * }
437: * public Object getAsObject(FacesContext context,
438: * UIComponent component, String value) {
439: * if (value == null) {
440: * return null;
441: * }
442: * // value is the String representation of "getType"
443: * //
444: * int type = Integer.parseInt(value);
445: * switch (type) {
446: * case Device.PRINTER:
447: * return deviceDb.getClosestPrinter();
448: * break;
449: * case Device.FAX:
450: * return deviceDb.getFax();
451: * break;
452: * default:
453: * throw new ConverterException("No such device : " + value);
454: * break;
455: * }
456: * }
457: * };
458: * </pre>
459: * </code>
460: * <p>
461: * The "getSelected" methods will be called to determine the checked
462: * state of the radio buttons during rendering.<br/>
463: * When the tags are first rendered, the initial checked state is
464: * determined by the return value of the "getSelected" methods.<br/>
465: * With <code>Object</code> valued radio buttons,
466: * a radio button will be checked only if the "getSelected" method
467: * returns an object instance that equals the object instance returned
468: * by the "getSelectedValue" method.<br/>
469: * For example if <code>getSelectedRb6</code> returns the <code>Printer</code>
470: * instance value of "rb6"'s <code>selectedValue</code> attribute, then
471: * "rb6" will be checked. <code>getSelectedRb7</code> should return
472: * <code>null</code>. If the <code>getSelectedRb6</code> method returns a
473: * <code>Printer</code> instance that is not equal as determined by
474: * <code>getSelectedValueRb6().equals(getSelectedRb6())</code> the radio button
475: * will not be checked.<br/>
476: * When the radio button is checked by the user the "setSelectedValue"
477: * methods will be called with the object instance returned by the converter.<br/>
478: * For example if "rb6" is checked by the user, <code>setSelectedRb6</code> will
479: * be called with a <code>Printer</code> instance returned by the converter.
480: * <code>setSelectedRb7</code> will be called with a <code>null</code>
481: * argument.
482: * </p>
483: * <p>
484: * Note that when radio buttons are part of a group the value of the
485: * selected radio button can be obtained directly from the request map.
486: * For example, processing the selection could take place in the action
487: * method of a submit button tag:
488: * </p>
489: * <p>
490: * <code><pre>
491: * public void submit() {
492: *
493: * // RadioButton.getSelected(String groupName) is
494: * // a static convenience method that obtains the
495: * // selected radio button value from the request map
496: * // <em>ONLY when the radio button is part of a group</em>.
497: * //
498: * Object selection = RadioButton.getSelected("rb4grp");
499: *
500: * // Assume at least one radio button will be selected.
501: * //
502: * processSelection((Device)selection);
503: * }
504: * </pre></code>
505: * </p>
506: * <h4>Example 5: Grouped Integer valued radio buttons in a table.</h4>
507: * <p>
508: * The following example shows a common use case for radio buttons in
509: * a table. The radio buttons are used to select at most one row
510: * for processing. The radio button state does not need to be
511: * stored. The selected row index can be obtained directly in the
512: * <code>#{tldRbCbExample.table5process}</code> method, using the
513: * <code>RadioButton.getSelected(String groupName)</code> convenience
514: * method. The markup in bold is how you would specify a radio button tag
515: * for this purpose. The <code>selectedValue</code> value binding,
516: * <code>#{tldRbCbExample.currentRow1}</code>
517: * is implemented to return the current row in the <code>table5row1</code>
518: * tableRow tag.
519: * </p>
520: * <p>
521: * Note that this example will not initially select a radio button
522: * which is normally not the way radio buttons are used; one is usually
523: * always checked.
524: * </p>
525: * <p>
526: * <code><pre>
527: * <ui:table id="table5">
528: * <ui:tableRow id="table5row1"
529: * sourceData="#{tldRbCbExample.table5row1data}"
530: * sourceVar="table5data"
531: * binding="#{tldRbCbExample.table5row1}">
532: * <ui:tableColumn id="col1">
533: *
534: * <f:facet name="header">
535: * <ui:tableHeader id="header1"
536: * deselectAllButton="true"
537: * selectAllButton="true"
538: * selectId="rb5"/>
539: * </f:facet>
540: *
541: * <b>
542: * <ui:radioButton id="rb8" name="rb5grp"
543: * selectedValue="#{tldRbCbExample.currentRow1}">
544: * </ui:radioButton>
545: * </b>
546: *
547: * </ui:tableColumn>
548: * <ui:tableColumn id="col2">
549: * <f:facet name="header">
550: * <ui:staticText text="Application Data"/>
551: * </f:facet>
552: *
553: * <ui:staticText text="#{table5data.text}"/>
554: *
555: * </ui:tableColumn>
556: * </ui:tableRow>
557: * <f:facet name="tableActionsBottom">
558: * <ui:button id="table5process"
559: * action="#{tldRbCbExample.table5process}"
560: * text="Process Checked"/>
561: * </f:facet>
562: * </ui:table>
563: * </pre>
564: * </code>
565: * </p>
566: * <p>
567: * See <a href="table.html" target="tagFrame">ui:table</a> for details
568: * on using the <code><ui:table></code> tag and other table child tags
569: * and facets.
570: * </p>
571: * <p>
572: * </p>
573: * <p>
574: * Normally when radio buttons are contained within a <code>ui:tableRow</code>
575: * the application MUST provide a value binding for the <code>selected</code>
576: * attribute and any attribute that is expected to maintain its state. This
577: * is because the table only creates a single instance of the radio button for
578: * all rows. It depends on a model to provide the storage for the attribute
579: * values, as it iterates over the rows in the dataset.<br/>
580: * In this example, we don't need to maintain the state across requests because
581: * a row is only selected for processing. Once the processing
582: * is complete, the radio button no longer needs to be checked.
583: * <p>
584: * The following code shows how the <code>table5process</code> action
585: * method obtains the selected radio button value from the request map.
586: * It calls a static member on <code>RadioButton</code> to return the
587: * <code>Integer</code> row index.
588: * </p>
589: * <code><pre>
590: * public void table5process() {
591: *
592: * // RadioButton.getSelected(String groupName) is
593: * // a static convenience method that obtains the
594: * // selected radio button value from the request map
595: * // <em>ONLY when the radio button is part of a group</em>.
596: * //
597: * Integer row = (Integer)RadioButton.getSelected("rb5grp");
598: * if (row != null) {
599: * processRow(row.intValue());
600: * }
601: * }
602: * </pre></code>
603: * <p>
604: * <h4>Example 6: Grouped boolean radio buttons in a table, using value bindings to
605: * maintain the state.</h4>
606: * <p>
607: * This example is similar to Example 5, but it maintains the state of the radio
608: * buttons across requests, by specifying a value binding for the selected
609: * attribute. A simple way to store the radio button state, is to store the
610: * state with the row data. The following code replaces the "ui:radioButton"
611: * code in the previous example.
612: * </p>
613: * <code>
614: * <ui:radioButton id="rb6" name="rb6grp"
615: * selected="#{table6data.selected}">
616: * </ui:radioButton>
617: * </code>
618: * <p>
619: * The value binding <code>#{table6data.selected}</code> references a boolean
620: * member in the row data for storing and retrieving the radio button state.
621: * </p>
622: *
623: * <h3>HTML Elements and Layout</h3>
624: * <p>
625: * A <code>radioButton</code> is rendered as at least one HTML <span>
626: * element and one <input> element of type <em>radio</em>.
627: * Each radio button may consist of the following elements:
628: * </p>
629: * <ul>
630: * <li>a <span> element</li>
631: * <li>an <input> element of type <em>radio</em></li>
632: * <li>an optional image if the <code>imageURL</code>
633: * attribute or an <code>image</code> facet is specified. If the
634: * <code>imageURL</code> attribute is specified a
635: * <code>com.sun.rave.web.ui.component.ImageComponent</code> component is created
636: * and rendered. If an <code>image</code> facet is specified then the
637: * component specified by the facet is rendered.</li>
638: * <li>an optional label if a <code>label</code>
639: * attribute or a <code>label</code> facet is specified.
640: * If the <code>label</code> attribute is
641: * specified a <code>com.sun.rave.web.ui.component.Label</code> component is
642: * created and rendered. If a <code>label</code> facet is specified then
643: * the component specified by the facet is rendered.</li>
644: * </ul>
645: * <p>
646: * The id attributes for HTML elements are constructed as follows,
647: * where <em>rid</em> is the <code>clientId</code> of the
648: * component being rendered.
649: * <p>
650: * <ul>
651: * <li> <em>rid_span</em> for the <span> element
652: * </li>
653: * <li> <em>rid</em> for the <input element
654: * </li>
655: * <li> <em>rid</em><b>_image</b> for the image component if created.</li>
656: * <li> <em>rid</em><b>_label</b> for the label component if created.</li>
657: * </li>
658: * </ul>
659: * </p>
660: * <p>
661: * Note that the value of the <code>style</code> and <code>styleClass</code>
662: * attributes of a radio button will be assigned to the containing
663: * <span> HTML element's <code>style</code> and <code>class</code> attributes
664: * respectively.
665: * </p>
666: * <h3>Client Side Javascript Functions </h3>
667: * <p>
668: * <ul>
669: * <li><em>radioButton_setChecked(elementId, checked)</em>: Set the checked
670: * property for a radio button with the given element id, <em>elementId</em>.
671: * If <em>checked</em> is true the radio button is checked.
672: * If <em>checked</em> is false the radio button is unchecked.</li>
673: * </ul>
674: * </p>
675: *
676: * <!--
677: * <h3>Theme Identifiers</h3>
678: * <p>
679: * <lo>
680: * <li>Rb for the INPUT element</li>
681: * <li>RbDis for the INPUT element for disabled radio button</li>
682: * <li>RbLbl for a LABEL element of a radio button</li>
683: * <li>RbLblDis for a LABEL element of a disabled radio button</li>
684: * <li>RbImg for an IMG element of a radio button</li>
685: * <li>RbImgDis for an IMG element of a disabled radio button</li>
686: * </lo>
687: * </p>
688: * -->
689: * <p>Auto-generated component class.
690: * Do <strong>NOT</strong> modify; all changes
691: * <strong>will</strong> be lost!</p>
692: */
693:
694: public abstract class RadioButtonBase extends
695: com.sun.rave.web.ui.component.RbCbSelector {
696:
697: /**
698: * <p>Construct a new <code>RadioButtonBase</code>.</p>
699: */
700: public RadioButtonBase() {
701: super ();
702: setRendererType("com.sun.rave.web.ui.RadioButton");
703: }
704:
705: /**
706: * <p>Return the identifier of the component family to which this
707: * component belongs. This identifier, in conjunction with the value
708: * of the <code>rendererType</code> property, may be used to select
709: * the appropriate {@link Renderer} for this component instance.</p>
710: */
711: public String getFamily() {
712: return "com.sun.rave.web.ui.RadioButton";
713: }
714:
715: // labelLevel
716: private int labelLevel = Integer.MIN_VALUE;
717: private boolean labelLevel_set = false;
718:
719: /**
720: * <p>Sets the style level for the generated label, provided the
721: * label attribute has been set. Valid values are 1 (largest), 2 and
722: * 3 (smallest). The default value is 3.</p>
723: */
724: public int getLabelLevel() {
725: if (this .labelLevel_set) {
726: return this .labelLevel;
727: }
728: ValueBinding _vb = getValueBinding("labelLevel");
729: if (_vb != null) {
730: Object _result = _vb.getValue(getFacesContext());
731: if (_result == null) {
732: return Integer.MIN_VALUE;
733: } else {
734: return ((Integer) _result).intValue();
735: }
736: }
737: return 3;
738: }
739:
740: /**
741: * <p>Sets the style level for the generated label, provided the
742: * label attribute has been set. Valid values are 1 (largest), 2 and
743: * 3 (smallest). The default value is 3.</p>
744: * @see #getLabelLevel()
745: */
746: public void setLabelLevel(int labelLevel) {
747: this .labelLevel = labelLevel;
748: this .labelLevel_set = true;
749: }
750:
751: /**
752: * <p>Restore the state of this component.</p>
753: */
754: public void restoreState(FacesContext _context, Object _state) {
755: Object _values[] = (Object[]) _state;
756: super .restoreState(_context, _values[0]);
757: this .labelLevel = ((Integer) _values[1]).intValue();
758: this .labelLevel_set = ((Boolean) _values[2]).booleanValue();
759: }
760:
761: /**
762: * <p>Save the state of this component.</p>
763: */
764: public Object saveState(FacesContext _context) {
765: Object _values[] = new Object[3];
766: _values[0] = super .saveState(_context);
767: _values[1] = new Integer(this .labelLevel);
768: _values[2] = this.labelLevel_set ? Boolean.TRUE : Boolean.FALSE;
769: return _values;
770: }
771:
772: }
|