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.event;
042:
043: import java.util.Iterator;
044:
045: import javax.faces.event.ActionEvent;
046: import javax.faces.event.ActionListener;
047: import javax.faces.component.UIComponent;
048:
049: import com.sun.rave.web.ui.util.LogUtil;
050: import com.sun.rave.web.ui.component.Tab;
051: import com.sun.rave.web.ui.component.TabSet;
052:
053: /**
054: * <p>Defines an ActionListener for Tab click events.</p>
055: *
056: * <p>This listener updates the selected value of the enclsing TabSet with the
057: * id of the Tab that generated the event. It also ensures that the
058: * selectedChildId of the clicked Tab's parent Tab is updated.</p>
059: *
060: * @author Sean Comerford
061: */
062: public class TabActionListener implements ActionListener {
063:
064: /**
065: * <p> Creates a new instance of <code>TabActionListener</code>.</p>
066: */
067: public TabActionListener() {
068: }
069:
070: /**
071: * <p>Perform the processing necessary to handle a Tab click event.</p>
072: *
073: * <p>The clicked Tab will be the source component that generated the given
074: * ActionEvent. This method should ensure that id of the source component
075: * (or one of its children) is set as the selected tab id for the
076: * enclosing TabSet. This method should also ensure that the selectedChildId
077: * of the source tab's parent Tab (if one exists) is also updated.
078: *
079: * @param event The ActionEvent generated
080: */
081: public void processAction(ActionEvent event) {
082: UIComponent eventComponent = event.getComponent();
083: if (!(eventComponent instanceof Tab)) {
084: // we don't care about non Tab child actions
085: return;
086: }
087:
088: // get the tab that was clicked
089: Tab tabToSelect = (Tab) eventComponent;
090:
091: while (tabToSelect.getChildCount() > 0) {
092: // the clicked tab has children - one of them may need to be set as
093: // the selected tab
094: String selectedChildId = tabToSelect.getSelectedChildId();
095:
096: Iterator i = tabToSelect.getChildren().iterator();
097:
098: // test if a previous child tab was set as the selected child
099: if (selectedChildId != null) {
100: // set the last selected child tab as selected
101: while (i.hasNext()) {
102: Tab child = null;
103:
104: try {
105: child = (Tab) i.next();
106: } catch (ClassCastException cce) {
107: // this child not a Tab
108: continue;
109: }
110:
111: if (selectedChildId.equals(child.getId())) {
112: // set this child as the tab to select
113: tabToSelect = child;
114: break;
115: }
116: }
117: } else {
118: // no prior child selection - select the 1st child tab but be
119: // aware there may not actually be any Tab children
120: while (i.hasNext()) {
121: Object kid = i.next();
122:
123: if (kid instanceof Tab) {
124: tabToSelect = (Tab) kid;
125: break;
126: }
127: }
128: // there must not be any Tab children - break outer while
129: break;
130: }
131: }
132:
133: String newSelection = tabToSelect.getId();
134: UIComponent parent = eventComponent.getParent();
135:
136: if (parent instanceof Tab) {
137: // updated the parent's selectedChildId
138: ((Tab) parent).setSelectedChildId(newSelection);
139: }
140:
141: // back up the component tree until we find the TabSet ancestor
142: while (parent != null) {
143: if (parent instanceof TabSet) {
144: break;
145: } else {
146: parent = parent.getParent();
147: }
148: }
149:
150: try {
151: ((TabSet) parent).setSelected(newSelection);
152: } catch (NullPointerException npe) {
153: if (LogUtil.infoEnabled()) {
154: LogUtil.info(TabActionListener.class, "WEBUI0006",
155: new String[] { eventComponent.getId() });
156: }
157: }
158: }
159: }
|