0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package com.sun.rave.web.ui.component;
0042:
0043: import com.sun.rave.web.ui.event.TablePaginationActionListener;
0044: import com.sun.rave.web.ui.event.TableSortActionListener;
0045: import com.sun.rave.web.ui.theme.Theme;
0046: import com.sun.rave.web.ui.theme.ThemeImages;
0047: import com.sun.rave.web.ui.theme.ThemeStyles;
0048: import com.sun.rave.web.ui.util.ClientSniffer;
0049: import com.sun.rave.web.ui.util.LogUtil;
0050: import com.sun.rave.web.ui.util.RenderingUtilities;
0051: import com.sun.rave.web.ui.util.ThemeUtilities;
0052:
0053: import java.io.IOException;
0054:
0055: import javax.faces.context.FacesContext;
0056: import javax.faces.component.NamingContainer;
0057: import javax.faces.component.UIComponent;
0058:
0059: /**
0060: * Component that represents a table action bar.
0061: * <p>
0062: * Note: Column headers and footers are rendered by TableRowGroupRenderer. Table
0063: * column footers are rendered by TableRenderer.
0064: * </p><p>
0065: * Note: To see the messages logged by this class, set the following global
0066: * defaults in your JDK's "jre/lib/logging.properties" file.
0067: * </p><p><pre>
0068: * java.util.logging.ConsoleHandler.level = FINE
0069: * com.sun.rave.web.ui.component.TableActions.level = FINE
0070: * </pre></p>
0071: */
0072: public class TableActions extends TableActionsBase implements
0073: NamingContainer {
0074: /** The component id for the actions separator icon. */
0075: public static final String ACTIONS_SEPARATOR_ICON_ID = "_actionsSeparatorIcon"; //NOI18N
0076:
0077: /** The facet name for the actions separator icon. */
0078: public static final String ACTIONS_SEPARATOR_ICON_FACET = "actionsSeparatorIcon"; //NOI18N
0079:
0080: /** The component id for the clear sort button. */
0081: public static final String CLEAR_SORT_BUTTON_ID = "_clearSortButton"; //NOI18N
0082:
0083: /** The facet name for the clear sort button. */
0084: public static final String CLEAR_SORT_BUTTON_FACET = "clearSortButton"; //NOI18N
0085:
0086: /** The component id for the deselect multiple button. */
0087: public static final String DESELECT_MULTIPLE_BUTTON_ID = "_deselectMultipleButton"; //NOI18N
0088:
0089: /** The facet name for the deselect multiple button. */
0090: public static final String DESELECT_MULTIPLE_BUTTON_FACET = "deselectMultipleButton"; //NOI18N
0091:
0092: /** The component id for the deselect single button. */
0093: public static final String DESELECT_SINGLE_BUTTON_ID = "_deselectSingleButton"; //NOI18N
0094:
0095: /** The facet name for the deselect single button. */
0096: public static final String DESELECT_SINGLE_BUTTON_FACET = "deselectSingleButton"; //NOI18N
0097:
0098: /** The component id for the filter label. */
0099: public static final String FILTER_LABEL_ID = "_filterLabel"; //NOI18N
0100:
0101: /** The facet name for the filter label. */
0102: public static final String FILTER_LABEL_FACET = "filterLabel"; //NOI18N
0103:
0104: /** The component id for the filter separator icon. */
0105: public static final String FILTER_SEPARATOR_ICON_ID = "_filterSeparatorIcon"; //NOI18N
0106:
0107: /** The facet name for the filter separator icon. */
0108: public static final String FILTER_SEPARATOR_ICON_FACET = "filterSeparatorIcon"; //NOI18N
0109:
0110: /** The component id for the paginate button. */
0111: public static final String PAGINATE_BUTTON_ID = "_paginateButton"; //NOI18N
0112:
0113: /** The facet name for the paginate button. */
0114: public static final String PAGINATE_BUTTON_FACET = "paginateButton"; //NOI18N
0115:
0116: /** The component id for the paginate separator icon. */
0117: public static final String PAGINATE_SEPARATOR_ICON_ID = "_paginateSeparatorIcon"; //NOI18N
0118:
0119: /** The facet name for the paginate separator icon. */
0120: public static final String PAGINATE_SEPARATOR_ICON_FACET = "paginateSeparatorIcon"; //NOI18N
0121:
0122: /** The component id for the pagination first button. */
0123: public static final String PAGINATION_FIRST_BUTTON_ID = "_paginationFirstButton"; //NOI18N
0124:
0125: /** The facet name for the pagination first button. */
0126: public static final String PAGINATION_FIRST_BUTTON_FACET = "paginationFirstButton"; //NOI18N
0127:
0128: /** The component id for the pagination last button. */
0129: public static final String PAGINATION_LAST_BUTTON_ID = "_paginationLastButton"; //NOI18N
0130:
0131: /** The facet name for the pagination last button. */
0132: public static final String PAGINATION_LAST_BUTTON_FACET = "paginationLastButton"; //NOI18N
0133:
0134: /** The component id for the pagination next button. */
0135: public static final String PAGINATION_NEXT_BUTTON_ID = "_paginationNextButton"; //NOI18N
0136:
0137: /** The facet name for the pagination next button. */
0138: public static final String PAGINATION_NEXT_BUTTON_FACET = "paginationNextButton"; //NOI18N
0139:
0140: /** The component id for the pagination page field. */
0141: public static final String PAGINATION_PAGE_FIELD_ID = "_paginationPageField"; //NOI18N
0142:
0143: /** The facet name for the pagination page field. */
0144: public static final String PAGINATION_PAGE_FIELD_FACET = "paginationPageField"; //NOI18N
0145:
0146: /** The component id for the pagination pages text. */
0147: public static final String PAGINATION_PAGES_TEXT_ID = "_paginationPagesText"; //NOI18N
0148:
0149: /** The facet name for the pagination pages text. */
0150: public static final String PAGINATION_PAGES_TEXT_FACET = "paginationPagesText"; //NOI18N
0151:
0152: /** The component id for the pagination previous button. */
0153: public static final String PAGINATION_PREV_BUTTON_ID = "_paginationPrevButton"; //NOI18N
0154:
0155: /** The facet name for the pagination previous button. */
0156: public static final String PAGINATION_PREV_BUTTON_FACET = "paginationPrevButton"; //NOI18N
0157:
0158: /** The component id for the pagination submit button. */
0159: public static final String PAGINATION_SUBMIT_BUTTON_ID = "_paginationSubmitButton"; //NOI18N
0160:
0161: /** The facet name for the pagination submit button. */
0162: public static final String PAGINATION_SUBMIT_BUTTON_FACET = "paginationSubmitButton"; //NOI18N
0163:
0164: /** The component id for the preferences panel button. */
0165: public static final String PREFERENCES_PANEL_TOGGLE_BUTTON_ID = "_preferencesPanelToggleButton"; //NOI18N
0166:
0167: /** The facet name for the preferences panel button. */
0168: public static final String PREFERENCES_PANEL_TOGGLE_BUTTON_FACET = "preferencesPanelToggleButton"; //NOI18N
0169:
0170: /** The component id for the select multiple button. */
0171: public static final String SELECT_MULTIPLE_BUTTON_ID = "_selectMultipleButton"; //NOI18N
0172:
0173: /** The facet name for the select multiple button. */
0174: public static final String SELECT_MULTIPLE_BUTTON_FACET = "selectMultipleButton"; //NOI18N
0175:
0176: /** The component id for the sort panel toggle button. */
0177: public static final String SORT_PANEL_TOGGLE_BUTTON_ID = "_sortPanelToggleButton"; //NOI18N
0178:
0179: /** The facet name for the sort panel toggle button. */
0180: public static final String SORT_PANEL_TOGGLE_BUTTON_FACET = "sortPanelToggleButton"; //NOI18N
0181:
0182: /** The component id for the view actions separator icon. */
0183: public static final String VIEW_ACTIONS_SEPARATOR_ICON_ID = "_viewActionsSeparatorIcon"; //NOI18N
0184:
0185: /** The facet name for the view actions separator icon. */
0186: public static final String VIEW_ACTIONS_SEPARATOR_ICON_FACET = "viewActionsSeparatorIcon"; //NOI18N
0187:
0188: // The Table ancestor enclosing this component.
0189: private Table table = null;
0190:
0191: /** Default constructor */
0192: public TableActions() {
0193: super ();
0194: }
0195:
0196: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0197: // Child methods
0198: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0199:
0200: /**
0201: * Get the closest Table ancestor that encloses this component.
0202: *
0203: * @return The Table ancestor.
0204: */
0205: public Table getTableAncestor() {
0206: if (table == null) {
0207: UIComponent component = this ;
0208: while (component != null) {
0209: component = component.getParent();
0210: if (component instanceof Table) {
0211: table = (Table) component;
0212: break;
0213: }
0214: }
0215: }
0216: return table;
0217: }
0218:
0219: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0220: // Pagination methods
0221: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0222:
0223: /**
0224: * Get first page button for pagination controls.
0225: *
0226: * @return The first page button.
0227: */
0228: public UIComponent getPaginationFirstButton() {
0229: UIComponent facet = getFacet(PAGINATION_FIRST_BUTTON_FACET);
0230: if (facet != null) {
0231: return facet;
0232: }
0233:
0234: // Get disabled state.
0235: Table table = getTableAncestor();
0236: TableRowGroup group = (table != null) ? table
0237: .getTableRowGroupChild() : null;
0238: boolean disabled = (group != null) ? group.getFirst() <= 0
0239: : false;
0240:
0241: // Get child.
0242: IconHyperlink child = new IconHyperlink();
0243: child.setId(PAGINATION_FIRST_BUTTON_ID);
0244: child
0245: .setIcon(disabled ? ThemeImages.TABLE_PAGINATION_FIRST_DISABLED
0246: : ThemeImages.TABLE_PAGINATION_FIRST);
0247: child.setBorder(0);
0248: child.setAlign("top"); //NOI18N
0249: child.setDisabled(disabled);
0250: child.addActionListener(new TablePaginationActionListener());
0251:
0252: // Set tool tip.
0253: String toolTip = getTheme()
0254: .getMessage("table.pagination.first"); //NOI18N
0255: child.setAlt(toolTip);
0256: child.setToolTip(toolTip);
0257:
0258: // Set tab index.
0259: if (table != null) {
0260: child.setTabIndex(table.getTabIndex());
0261: } else {
0262: log("getPaginationFirstButton",
0263: "Tab index not set, Table is null"); //NOI18N
0264: }
0265:
0266: // Set focus when paginaton buttons are disabled -- bugtraq #6316565.
0267: setPaginationFocus(child);
0268:
0269: // Save facet and return child.
0270: getFacets().put(child.getId(), child);
0271: return child;
0272: }
0273:
0274: /**
0275: * Get pagination submit button for pagination controls.
0276: *
0277: * @return The pagination submit button.
0278: */
0279: public UIComponent getPaginationSubmitButton() {
0280: UIComponent facet = getFacet(PAGINATION_SUBMIT_BUTTON_FACET);
0281: if (facet != null) {
0282: return facet;
0283: }
0284:
0285: // Get child.
0286: Button child = new Button();
0287: child.setId(PAGINATION_SUBMIT_BUTTON_ID);
0288: child.setText(getTheme().getMessage("table.pagination.submit")); //NOI18N
0289: child.setToolTip(getTheme().getMessage(
0290: "table.pagination.submitPage")); //NOI18N
0291: child.addActionListener(new TablePaginationActionListener());
0292:
0293: // Set tab index.
0294: Table table = getTableAncestor();
0295: if (table != null) {
0296: child.setTabIndex(table.getTabIndex());
0297: } else {
0298: log("getPaginationSubmitButton",
0299: "Tab index not set, Table is null"); //NOI18N
0300: }
0301:
0302: // Save facet and return child.
0303: getFacets().put(child.getId(), child);
0304: return child;
0305: }
0306:
0307: /**
0308: * Get last page button for pagination controls.
0309: *
0310: * @return The last page button.
0311: */
0312: public UIComponent getPaginationLastButton() {
0313: UIComponent facet = getFacet(PAGINATION_LAST_BUTTON_FACET);
0314: if (facet != null) {
0315: return facet;
0316: }
0317:
0318: // Get disabled state.
0319: Table table = getTableAncestor();
0320: TableRowGroup group = (table != null) ? table
0321: .getTableRowGroupChild() : null;
0322: boolean disabled = (group != null) ? group.getFirst() >= group
0323: .getLast() : false;
0324:
0325: // Get child.
0326: IconHyperlink child = new IconHyperlink();
0327: child.setId(PAGINATION_LAST_BUTTON_ID);
0328: child
0329: .setIcon(disabled ? ThemeImages.TABLE_PAGINATION_LAST_DISABLED
0330: : ThemeImages.TABLE_PAGINATION_LAST);
0331: child.setBorder(0);
0332: child.setAlign("top"); //NOI18N
0333: child.setDisabled(disabled);
0334: child.addActionListener(new TablePaginationActionListener());
0335:
0336: // Set tool tip.
0337: String toolTip = getTheme().getMessage("table.pagination.last"); //NOI18N
0338: child.setAlt(toolTip);
0339: child.setToolTip(toolTip);
0340:
0341: // Set tab index.
0342: if (table != null) {
0343: child.setTabIndex(table.getTabIndex());
0344: } else {
0345: log("getPaginationLastButton",
0346: "Tab index not set, Table is null"); //NOI18N
0347: }
0348:
0349: // Set focus when paginaton buttons are disabled -- bugtraq #6316565.
0350: setPaginationFocus(child);
0351:
0352: // Save facet and return child.
0353: getFacets().put(child.getId(), child);
0354: return child;
0355: }
0356:
0357: /**
0358: * Get next page button for pagination controls.
0359: *
0360: * @return The next page button.
0361: */
0362: public UIComponent getPaginationNextButton() {
0363: UIComponent facet = getFacet(PAGINATION_NEXT_BUTTON_FACET);
0364: if (facet != null) {
0365: return facet;
0366: }
0367:
0368: // Get disabled state.
0369: Table table = getTableAncestor();
0370: TableRowGroup group = (table != null) ? table
0371: .getTableRowGroupChild() : null;
0372: boolean disabled = (group != null) ? group.getFirst() >= group
0373: .getLast() : false;
0374:
0375: // Get child.
0376: IconHyperlink child = new IconHyperlink();
0377: child.setId(PAGINATION_NEXT_BUTTON_ID);
0378: child
0379: .setIcon(disabled ? ThemeImages.TABLE_PAGINATION_NEXT_DISABLED
0380: : ThemeImages.TABLE_PAGINATION_NEXT);
0381: child.setBorder(0);
0382: child.setAlign("top"); //NOI18N
0383: child.setDisabled(disabled);
0384: child.addActionListener(new TablePaginationActionListener());
0385:
0386: // Set tool tip.
0387: String toolTip = getTheme().getMessage("table.pagination.next"); //NOI18N
0388: child.setAlt(toolTip);
0389: child.setToolTip(toolTip);
0390:
0391: // Set tab index.
0392: if (table != null) {
0393: child.setTabIndex(table.getTabIndex());
0394: } else {
0395: log("getPaginationNextButton",
0396: "Tab index not set, Table is null"); //NOI18N
0397: }
0398:
0399: // Set focus when paginaton buttons are disabled -- bugtraq #6316565.
0400: setPaginationFocus(child);
0401:
0402: // Save facet and return child.
0403: getFacets().put(child.getId(), child);
0404: return child;
0405: }
0406:
0407: /**
0408: * Get page field for pagination controls.
0409: *
0410: * @return The page field.
0411: */
0412: public UIComponent getPaginationPageField() {
0413: UIComponent facet = getFacet(PAGINATION_PAGE_FIELD_FACET);
0414: if (facet != null) {
0415: return facet;
0416: }
0417:
0418: // Get current page.
0419: Table table = getTableAncestor();
0420: TableRowGroup group = (table != null) ? table
0421: .getTableRowGroupChild() : null;
0422: int page = (group != null) ? group.getPage() : 1;
0423:
0424: // Get child.
0425: TextField child = new TextField();
0426: child.setId(PAGINATION_PAGE_FIELD_ID);
0427: child.setText(Integer.toString(page));
0428: child.setOnKeyPress(getPaginationJavascript());
0429: child.setColumns(3); //NOI18N
0430: child.setLabelLevel(2);
0431: child.setLabel(getTheme().getMessage("table.pagination.page")); //NOI18N
0432:
0433: // Set tab index.
0434: if (table != null) {
0435: child.setTabIndex(table.getTabIndex());
0436: } else {
0437: log("getPaginationPageField",
0438: "Tab index not set, Table is null"); //NOI18N
0439: }
0440:
0441: // Save facet and return child.
0442: getFacets().put(child.getId(), child);
0443: return child;
0444: }
0445:
0446: /**
0447: * Get pages text for pagination controls.
0448: *
0449: * @return The pages text.
0450: */
0451: public UIComponent getPaginationPagesText() {
0452: UIComponent facet = getFacet(PAGINATION_PAGES_TEXT_FACET);
0453: if (facet != null) {
0454: return facet;
0455: }
0456:
0457: Theme theme = getTheme();
0458:
0459: // Get child.
0460: StaticText child = new StaticText();
0461: child.setId(PAGINATION_PAGES_TEXT_ID);
0462: child.setStyleClass(theme
0463: .getStyleClass(ThemeStyles.TABLE_PAGINATION_TEXT));
0464:
0465: // Set page text.
0466: Table table = getTableAncestor();
0467: if (table != null) {
0468: child.setText(theme.getMessage("table.pagination.pages", //NOI18N
0469: new String[] { Integer.toString(table
0470: .getPageCount()) }));
0471: } else {
0472: log("getPaginationPagesText",
0473: "Pages text not set, Table is null"); //NOI18N
0474: }
0475:
0476: // Save facet and return child.
0477: getFacets().put(child.getId(), child);
0478: return child;
0479: }
0480:
0481: /**
0482: * Get paginate button of pagination controls.
0483: *
0484: * @return The paginate button.
0485: */
0486: public UIComponent getPaginateButton() {
0487: UIComponent facet = getFacet(PAGINATE_BUTTON_FACET);
0488: if (facet != null) {
0489: return facet;
0490: }
0491:
0492: // Get paginated state.
0493: Table table = getTableAncestor();
0494: TableRowGroup group = (table != null) ? table
0495: .getTableRowGroupChild() : null;
0496: boolean paginated = (group != null) ? group.isPaginated()
0497: : false;
0498:
0499: // Get child.
0500: IconHyperlink child = new IconHyperlink();
0501: child.setId(PAGINATE_BUTTON_ID);
0502: child.setIcon(paginated ? ThemeImages.TABLE_SCROLL_PAGE
0503: : ThemeImages.TABLE_PAGINATE);
0504: child.setBorder(0);
0505: child.setAlign("top"); //NOI18N
0506: child.addActionListener(new TablePaginationActionListener());
0507:
0508: // Set i18n tool tip.
0509: String toolTip = paginated ? getTheme().getMessage(
0510: "table.pagination.scroll") //NOI18N
0511: : getTheme().getMessage("table.pagination.paginated"); //NOI18N
0512: child.setAlt(toolTip);
0513: child.setToolTip(toolTip);
0514:
0515: // Set tab index.
0516: if (table != null) {
0517: child.setTabIndex(table.getTabIndex());
0518: } else {
0519: log("getPaginateButton", "Tab index not set, Table is null"); //NOI18N
0520: }
0521:
0522: // Save facet and return child.
0523: getFacets().put(child.getId(), child);
0524: return child;
0525: }
0526:
0527: /**
0528: * Get previous page button for pagination controls.
0529: *
0530: * @return The previous page button.
0531: */
0532: public UIComponent getPaginationPrevButton() {
0533: UIComponent facet = getFacet(PAGINATION_PREV_BUTTON_FACET);
0534: if (facet != null) {
0535: return facet;
0536: }
0537:
0538: // Get disabled state.
0539: Table table = getTableAncestor();
0540: TableRowGroup group = (table != null) ? table
0541: .getTableRowGroupChild() : null;
0542: boolean disabled = (group != null) ? group.getFirst() <= 0
0543: : false;
0544:
0545: // Get child.
0546: IconHyperlink child = new IconHyperlink();
0547: child.setId(PAGINATION_PREV_BUTTON_ID);
0548: child
0549: .setIcon(disabled ? ThemeImages.TABLE_PAGINATION_PREV_DISABLED
0550: : ThemeImages.TABLE_PAGINATION_PREV);
0551: child.setBorder(0);
0552: child.setAlign("top"); //NOI18N
0553: child.setDisabled(disabled);
0554: child.addActionListener(new TablePaginationActionListener());
0555:
0556: // Set tool tip.
0557: String toolTip = getTheme().getMessage(
0558: "table.pagination.previous"); //NOI18N
0559: child.setAlt(toolTip);
0560: child.setToolTip(toolTip);
0561:
0562: // Set tab index.
0563: if (table != null) {
0564: child.setTabIndex(table.getTabIndex());
0565: } else {
0566: log("getPaginationPrevButton",
0567: "Tab index not set, Table is null"); //NOI18N
0568: }
0569:
0570: // Set focus when paginaton buttons are disabled -- bugtraq #6316565.
0571: setPaginationFocus(child);
0572:
0573: // Save facet and return child.
0574: getFacets().put(child.getId(), child);
0575: return child;
0576: }
0577:
0578: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0579: // Select methods
0580: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0581:
0582: /**
0583: * Get deselect multiple button.
0584: *
0585: * @return The deselect multiple button.
0586: */
0587: public UIComponent getDeselectMultipleButton() {
0588: UIComponent facet = getFacet(DESELECT_MULTIPLE_BUTTON_FACET);
0589: if (facet != null) {
0590: return facet;
0591: }
0592:
0593: // Get paginated state.
0594: Table table = getTableAncestor();
0595: TableRowGroup group = (table != null) ? table
0596: .getTableRowGroupChild() : null;
0597: boolean paginated = (group != null) ? group.isPaginated()
0598: : false;
0599:
0600: // Get child.
0601: IconHyperlink child = new IconHyperlink();
0602: child.setId(DESELECT_MULTIPLE_BUTTON_ID);
0603: child.setIcon(ThemeImages.TABLE_DESELECT_MULTIPLE);
0604: child.setBorder(0);
0605: child.setAlign("top"); //NOI18N
0606:
0607: // Set onClick and tab index.
0608: if (table != null) {
0609: child.setOnClick(getSelectJavascript(table
0610: .getDeselectMultipleButtonOnClick(), false));
0611: child.setTabIndex(table.getTabIndex());
0612: } else {
0613: log("getDeselectMultipleButton", //NOI18N
0614: "Tab index & onClick not set, Table is null"); //NOI18N
0615: }
0616:
0617: // Get tool tip.
0618: String toolTip = getTheme().getMessage(
0619: paginated ? "table.select.deselectMultiplePaginated" //NOI18N
0620: : "table.select.deselectMultiple"); //NOI18N
0621: child.setAlt(toolTip);
0622: child.setToolTip(toolTip);
0623:
0624: // Save facet and return child.
0625: getFacets().put(child.getId(), child);
0626: return child;
0627: }
0628:
0629: /**
0630: * Get deselect single button.
0631: *
0632: * @return The deselect single button.
0633: */
0634: public UIComponent getDeselectSingleButton() {
0635: UIComponent facet = getFacet(DESELECT_SINGLE_BUTTON_FACET);
0636: if (facet != null) {
0637: return facet;
0638: }
0639:
0640: // Get paginated state.
0641: Table table = getTableAncestor();
0642: TableRowGroup group = (table != null) ? table
0643: .getTableRowGroupChild() : null;
0644: boolean paginated = (group != null) ? group.isPaginated()
0645: : false;
0646:
0647: // Get child.
0648: IconHyperlink child = new IconHyperlink();
0649: child.setId(DESELECT_SINGLE_BUTTON_ID);
0650: child.setIcon(ThemeImages.TABLE_DESELECT_SINGLE);
0651: child.setBorder(0);
0652: child.setAlign("top"); //NOI18N
0653:
0654: // Set onClick and tab index.
0655: if (table != null) {
0656: child.setOnClick(getSelectJavascript(table
0657: .getDeselectSingleButtonOnClick(), false));
0658: child.setTabIndex(table.getTabIndex());
0659: } else {
0660: log("getDeselectSingleButton", //NOI18N
0661: "Tab index & onClick not set, Table is null"); //NOI18N
0662: }
0663:
0664: // Set tool tip.
0665: String toolTip = getTheme().getMessage(
0666: paginated ? "table.select.deselectSinglePaginated" //NOI18N
0667: : "table.select.deselectSingle"); //NOI18N
0668: child.setAlt(toolTip);
0669: child.setToolTip(toolTip);
0670:
0671: // Save facet and return child.
0672: getFacets().put(child.getId(), child);
0673: return child;
0674: }
0675:
0676: /**
0677: * Get select multiple button.
0678: *
0679: * @return The select multiple button.
0680: */
0681: public UIComponent getSelectMultipleButton() {
0682: UIComponent facet = getFacet(SELECT_MULTIPLE_BUTTON_FACET);
0683: if (facet != null) {
0684: return facet;
0685: }
0686:
0687: // Get paginated state.
0688: Table table = getTableAncestor();
0689: TableRowGroup group = (table != null) ? table
0690: .getTableRowGroupChild() : null;
0691: boolean paginated = (group != null) ? group.isPaginated()
0692: : false;
0693:
0694: // Get child.
0695: IconHyperlink child = new IconHyperlink();
0696: child.setId(SELECT_MULTIPLE_BUTTON_ID);
0697: child.setIcon(ThemeImages.TABLE_SELECT_MULTIPLE);
0698: child.setBorder(0);
0699: child.setAlign("top"); //NOI18N
0700:
0701: // Set onClick and tab index.
0702: if (table != null) {
0703: child.setOnClick(getSelectJavascript(table
0704: .getDeselectMultipleButtonOnClick(), true));
0705: child.setTabIndex(table.getTabIndex());
0706: } else {
0707: log("getSelectMultipleButton", //NOI18N
0708: "Tab index & onClick not set, Table is null"); //NOI18N
0709: }
0710:
0711: // Set tool tip.
0712: String toolTip = getTheme().getMessage(
0713: paginated ? "table.select.selectMultiplePaginated" //NOI18N
0714: : "table.select.selectMultiple"); //NOI18N
0715: child.setAlt(toolTip);
0716: child.setToolTip(toolTip);
0717:
0718: // Save facet and return child.
0719: getFacets().put(child.getId(), child);
0720: return child;
0721: }
0722:
0723: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0724: // Separator methods
0725: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0726:
0727: /**
0728: * Get the actions separator icon.
0729: *
0730: * @return The top actions separator icon.
0731: */
0732: public UIComponent getActionsSeparatorIcon() {
0733: return getSeparatorIcon(ACTIONS_SEPARATOR_ICON_ID,
0734: ACTIONS_SEPARATOR_ICON_FACET);
0735: }
0736:
0737: /**
0738: * Get the filter separator icon.
0739: *
0740: * @return The filter separator icon.
0741: */
0742: public UIComponent getFilterSeparatorIcon() {
0743: return getSeparatorIcon(FILTER_SEPARATOR_ICON_ID,
0744: FILTER_SEPARATOR_ICON_FACET);
0745: }
0746:
0747: /**
0748: * Get the paginate separator icon.
0749: *
0750: * @return The paginate separator icon.
0751: */
0752: public UIComponent getPaginateSeparatorIcon() {
0753: return getSeparatorIcon(PAGINATE_SEPARATOR_ICON_ID,
0754: PAGINATE_SEPARATOR_ICON_FACET);
0755: }
0756:
0757: /**
0758: * Get the view actions separator icon.
0759: *
0760: * @return The view actions separator icon.
0761: */
0762: public UIComponent getViewActionsSeparatorIcon() {
0763: return getSeparatorIcon(VIEW_ACTIONS_SEPARATOR_ICON_ID,
0764: VIEW_ACTIONS_SEPARATOR_ICON_FACET);
0765: }
0766:
0767: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0768: // View-changing action methods
0769: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0770:
0771: /**
0772: * Get clear sort button.
0773: *
0774: * @return The clear sort button.
0775: */
0776: public UIComponent getClearSortButton() {
0777: UIComponent facet = getFacet(CLEAR_SORT_BUTTON_FACET);
0778: if (facet != null) {
0779: return facet;
0780: }
0781:
0782: // Get child.
0783: IconHyperlink child = new IconHyperlink();
0784: child.setId(CLEAR_SORT_BUTTON_ID);
0785: child.setIcon(ThemeImages.TABLE_SORT_CLEAR);
0786: child.setBorder(0);
0787: child.setAlign("top"); //NOI18N
0788: child.addActionListener(new TableSortActionListener());
0789:
0790: // Set tool tip.
0791: String toolTip = getTheme().getMessage(
0792: "table.viewActions.clearSort"); //NOI18N
0793: child.setAlt(toolTip);
0794: child.setToolTip(toolTip);
0795:
0796: // Set tab index.
0797: if (table != null) {
0798: child.setTabIndex(table.getTabIndex());
0799: } else {
0800: log("getClearSortButton",
0801: "Tab index not set, Table is null"); //NOI18N
0802: }
0803:
0804: // Save facet and return child.
0805: getFacets().put(child.getId(), child);
0806: return child;
0807: }
0808:
0809: /**
0810: * Get filter label.
0811: *
0812: * @return The filter label.
0813: */
0814: public UIComponent getFilterLabel() {
0815: UIComponent facet = getFacet(FILTER_LABEL_FACET);
0816: if (facet != null) {
0817: return facet;
0818: }
0819:
0820: // Get child.
0821: Label child = new Label();
0822: child.setId(FILTER_LABEL_ID);
0823: child
0824: .setText(getTheme().getMessage(
0825: "table.viewActions.filter")); //NOI18N
0826: child.setLabelLevel(2);
0827:
0828: Table table = getTableAncestor();
0829: if (table != null) {
0830: child.setLabeledComponent(table
0831: .getFacet(Table.FILTER_FACET));
0832: } else {
0833: log("getFilterLabel",
0834: "Labeled component not set, Table is null"); //NOI18N
0835: }
0836:
0837: // Save facet and return child.
0838: getFacets().put(child.getId(), child);
0839: return child;
0840: }
0841:
0842: /**
0843: * Get preferences panel toggle button.
0844: *
0845: * @return The preferences panel toggle button.
0846: */
0847: public UIComponent getPreferencesPanelToggleButton() {
0848: UIComponent facet = getFacet(PREFERENCES_PANEL_TOGGLE_BUTTON_FACET);
0849: if (facet != null) {
0850: return facet;
0851: }
0852:
0853: // Get child.
0854: IconHyperlink child = new IconHyperlink();
0855: child.setId(PREFERENCES_PANEL_TOGGLE_BUTTON_ID);
0856: child.setIcon(ThemeImages.TABLE_PREFERENCES_PANEL);
0857: child.setBorder(0);
0858: child.setAlign("top"); //NOI18N
0859:
0860: // Set JS to display table preferences panel.
0861: Table table = getTableAncestor();
0862: if (table != null) {
0863: StringBuffer buff = new StringBuffer(128).append(
0864: "document.getElementById('")
0865: //NOI18N
0866: .append(table.getClientId(getFacesContext()))
0867: .append("').togglePreferencesPanel(); return false"); //NOI18N
0868: child.setOnClick(buff.toString());
0869: child.setTabIndex(table.getTabIndex());
0870: } else {
0871: log("getPreferencesPanelToggleButton", //NOI18N
0872: "Tab index & onClick not set, Table is null"); //NOI18N
0873: }
0874:
0875: // Get tool tip.
0876: String toolTip = getTheme().getMessage(
0877: "table.viewActions.preferences"); //NOI18N
0878: child.setAlt(toolTip);
0879: child.setToolTip(toolTip);
0880:
0881: // Save facet and return child.
0882: getFacets().put(child.getId(), child);
0883: return child;
0884: }
0885:
0886: /**
0887: * Get sort panel toggle button.
0888: *
0889: * @return The sort panel toggle button.
0890: */
0891: public UIComponent getSortPanelToggleButton() {
0892: UIComponent facet = getFacet(SORT_PANEL_TOGGLE_BUTTON_FACET);
0893: if (facet != null) {
0894: return facet;
0895: }
0896:
0897: // Get child.
0898: IconHyperlink child = new IconHyperlink();
0899: child.setId(SORT_PANEL_TOGGLE_BUTTON_ID);
0900: child.setIcon(ThemeImages.TABLE_SORT_PANEL);
0901: child.setBorder(0);
0902: child.setAlign("top"); //NOI18N
0903:
0904: // Set JS to display table preferences panel.
0905: Table table = getTableAncestor();
0906: if (table != null) {
0907: StringBuffer buff = new StringBuffer(128).append(
0908: "document.getElementById('")
0909: //NOI18N
0910: .append(table.getClientId(getFacesContext()))
0911: .append("').toggleSortPanel(); return false"); //NOI18N
0912: child.setOnClick(buff.toString());
0913: child.setTabIndex(table.getTabIndex());
0914: } else {
0915: log("getSortPanelToggleButton", //NOI18N
0916: "Tab index & onClick not set, Table is null"); //NOI18N
0917: }
0918:
0919: // Set tool tip.
0920: Theme theme = getTheme();
0921: String toolTip = theme.getMessage("table.viewActions.sort"); //NOI18N
0922: child.setAlt(toolTip);
0923: child.setToolTip(toolTip);
0924:
0925: // Save facet and return child.
0926: getFacets().put(child.getId(), child);
0927: return child;
0928: }
0929:
0930: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0931: // UIComponent methods
0932: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0933:
0934: /**
0935: * If the rendered property is true, render the begining of the current
0936: * state of this UIComponent to the response contained in the specified
0937: * FacesContext.
0938: *
0939: * If a Renderer is associated with this UIComponent, the actual encoding
0940: * will be delegated to Renderer.encodeBegin(FacesContext, UIComponent).
0941: *
0942: * @param context FacesContext for the current request.
0943: *
0944: * @exception IOException if an input/output error occurs while rendering.
0945: * @exception NullPointerException if FacesContext is null.
0946: */
0947: public void encodeBegin(FacesContext context) throws IOException {
0948: // Clear cached variables -- bugtraq #6300020.
0949: table = null;
0950: super .encodeBegin(context);
0951: }
0952:
0953: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0954: // Private methods
0955: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
0956:
0957: /**
0958: * Helper method to get Javascript for the de/select all buttons.
0959: *
0960: * @param script The Javascript to be prepended, if any.
0961: * @param checked true if components used for row selection should be
0962: * checked; otherwise, false.
0963: *
0964: * @return The Javascript for the de/select buttons.
0965: */
0966: private String getSelectJavascript(String script, boolean checked) {
0967: // Get JS to de/select all components in table.
0968: StringBuffer buff = new StringBuffer(1024);
0969:
0970: // Developer may have added onClick Javascript for de/select all button.
0971: if (script != null) {
0972: buff.append(script).append(";"); //NOI18N
0973: }
0974:
0975: // Append Javascript to de/select all select components.
0976: Table table = getTableAncestor();
0977: if (table != null) {
0978: buff.append("document.getElementById('")
0979: //NOI18N
0980: .append(table.getClientId(getFacesContext()))
0981: .append("').selectAllRows(") //NOI18N
0982: .append(checked).append("); return false"); //NOI18N
0983: } else {
0984: log("getSelectJavascript", //NOI18N
0985: "Cannot obtain select Javascript, Table is null"); //NOI18N
0986: }
0987: return buff.toString();
0988: }
0989:
0990: /**
0991: * Helper method to get separator icons used for top and bottom actions,
0992: * filter, view actions, and paginate button.
0993: *
0994: * @param id The identifier for the component.
0995: * @param name The facet name used to override the component.
0996: *
0997: * @return The separator icon.
0998: */
0999: private UIComponent getSeparatorIcon(String id, String name) {
1000: UIComponent facet = getFacet(name);
1001: if (facet != null) {
1002: return facet;
1003: }
1004:
1005: // Get child.
1006: Icon child = getTheme().getIcon(
1007: ThemeImages.TABLE_ACTIONS_SEPARATOR);
1008: child.setId(id);
1009: child.setBorder(0);
1010: child.setAlign("top"); //NOI18N
1011:
1012: // Save facet and return child.
1013: getFacets().put(child.getId(), child);
1014: return child;
1015: }
1016:
1017: /**
1018: * Helper method to get Javascript to submit the "go" button when the user
1019: * clicks enter in the page field.
1020: *
1021: * @return The Javascript used to submit the "go" button.
1022: */
1023: private String getPaginationJavascript() {
1024: ClientSniffer cs = ClientSniffer.getInstance(getFacesContext());
1025:
1026: // Get key code.
1027: String keyCode = cs.isNav() ? "event.which" : "event.keyCode"; //NOI18N
1028:
1029: // Append JS to capture the event.
1030: StringBuffer buff = new StringBuffer(128).append("if (") //NOI18N
1031: .append(keyCode).append("==13) {"); //NOI18N
1032:
1033: // To prevent an auto-submit, Netscape 6.x and netscape 7.0 require
1034: // setting the cancelBubble property. However, Netscape 7.1,
1035: // Mozilla 1.x, IE 5.x for SunOS/Windows do not use this property.
1036: if (cs.isNav6() || cs.isNav70()) {
1037: buff.append("event.cancelBubble = true;"); //NOI18N
1038: }
1039:
1040: // Append JS to submit the button.
1041: buff
1042: .append("var e=document.getElementById('")
1043: //NOI18N
1044: .append(
1045: getClientId(getFacesContext())
1046: + NamingContainer.SEPARATOR_CHAR
1047: + TableActions.PAGINATION_SUBMIT_BUTTON_ID)
1048: .append("'); if (e != null) e.click(); return false}"); //NOI18N
1049: return buff.toString();
1050: }
1051:
1052: /**
1053: * Helper method to get Theme objects.
1054: *
1055: * @return The current theme.
1056: */
1057: private Theme getTheme() {
1058: return ThemeUtilities.getTheme(getFacesContext());
1059: }
1060:
1061: /**
1062: * Helper method to determine if table is empty.
1063: *
1064: * @return true if table contains no rows.
1065: */
1066: private boolean isEmptyTable() {
1067: int totalRows = table.getRowCount();
1068: return (totalRows == 0);
1069: }
1070:
1071: /**
1072: * Helper method to determine if all rows fit on a single page.
1073: * <p>
1074: * Note: Pagination controls are only hidden when all groups fit on a single
1075: * page.
1076: * </p>
1077: * @return true if all rows fit on a single page.
1078: */
1079: private boolean isSinglePage() {
1080: int totalRows = table.getRowCount();
1081: return (totalRows < table.getRows());
1082: }
1083:
1084: /**
1085: * Helper method to determine if table contains a single row.
1086: *
1087: * @return true if all rows fit on a single page.
1088: */
1089: private boolean isSingleRow() {
1090: int totalRows = table.getRowCount();
1091: return (totalRows == 1);
1092: }
1093:
1094: /**
1095: * Log fine messages.
1096: */
1097: private void log(String method, String message) {
1098: // Get class.
1099: Class clazz = this .getClass();
1100: if (LogUtil.fineEnabled(clazz)) {
1101: // Log method name and message.
1102: LogUtil.fine(clazz, clazz.getName() + "." + method + ": "
1103: + message); //NOI18N
1104: }
1105: }
1106:
1107: /**
1108: * Set focus when paginaton buttons are disabled.
1109: */
1110: private void setPaginationFocus(IconHyperlink component) {
1111: if (component == null || !component.isDisabled()) {
1112: return;
1113: }
1114:
1115: // Get prefix for all IDs.
1116: FacesContext context = getFacesContext();
1117: String prefix = getClientId(context)
1118: + NamingContainer.SEPARATOR_CHAR;
1119:
1120: // Get the client ID of the last component to have focus.
1121: String id = RenderingUtilities.getLastClientID(context);
1122: if (id == null) {
1123: return;
1124: }
1125:
1126: // Set focus on the page field component.
1127: if (id.equals(prefix + PAGINATION_FIRST_BUTTON_ID)
1128: || id.equals(prefix + PAGINATION_LAST_BUTTON_ID)
1129: || id.equals(prefix + PAGINATION_NEXT_BUTTON_ID)
1130: || id.equals(prefix + PAGINATION_PREV_BUTTON_ID)) {
1131: RenderingUtilities.setLastClientID(context, prefix
1132: + PAGINATION_PAGE_FIELD_ID + Field.INPUT_ID);
1133: }
1134: }
1135: }
|