Source Code Cross Referenced for HTMLTable.java in  » Ajax » GWT » com » google » gwt » user » client » ui » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Ajax » GWT » com.google.gwt.user.client.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2007 Google Inc.
0003:         * 
0004:         * Licensed under the Apache License, Version 2.0 (the "License"); you may not
0005:         * use this file except in compliance with the License. You may obtain a copy of
0006:         * the License at
0007:         * 
0008:         * http://www.apache.org/licenses/LICENSE-2.0
0009:         * 
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
0012:         * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
0013:         * License for the specific language governing permissions and limitations under
0014:         * the License.
0015:         */
0016:        package com.google.gwt.user.client.ui;
0017:
0018:        import com.google.gwt.user.client.DOM;
0019:        import com.google.gwt.user.client.Element;
0020:        import com.google.gwt.user.client.Event;
0021:        import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
0022:        import com.google.gwt.user.client.ui.HasVerticalAlignment.VerticalAlignmentConstant;
0023:
0024:        import java.util.ArrayList;
0025:        import java.util.Iterator;
0026:        import java.util.NoSuchElementException;
0027:
0028:        /**
0029:         * HTMLTable contains the common table algorithms for
0030:         * {@link com.google.gwt.user.client.ui.Grid} and
0031:         * {@link com.google.gwt.user.client.ui.FlexTable}.
0032:         * <p>
0033:         * <img class='gallery' src='Table.png'/>
0034:         * </p>
0035:         */
0036:        public abstract class HTMLTable extends Panel implements 
0037:                SourcesTableEvents {
0038:            /**
0039:             * This class contains methods used to format a table's cells.
0040:             */
0041:            public class CellFormatter {
0042:                /**
0043:                 * Adds a style to the specified cell.
0044:                 * 
0045:                 * @param row the cell's row
0046:                 * @param column the cell's column
0047:                 * @param styleName the style name to be added
0048:                 * @see UIObject#addStyleName(String)
0049:                 */
0050:                public void addStyleName(int row, int column, String styleName) {
0051:                    prepareCell(row, column);
0052:                    Element td = getCellElement(bodyElem, row, column);
0053:                    UIObject.setStyleName(td, styleName, true);
0054:                }
0055:
0056:                /**
0057:                 * Gets the TD element representing the specified cell.
0058:                 * 
0059:                 * @param row the row of the cell to be retrieved
0060:                 * @param column the column of the cell to be retrieved
0061:                 * @return the column's TD element
0062:                 * @throws IndexOutOfBoundsException
0063:                 */
0064:                public Element getElement(int row, int column) {
0065:                    checkCellBounds(row, column);
0066:                    return getCellElement(bodyElem, row, column);
0067:                }
0068:
0069:                /**
0070:                 * Gets the style of a specified cell.
0071:                 * 
0072:                 * @param row the cell's row
0073:                 * @param column the cell's column
0074:                 * @see UIObject#getStyleName()
0075:                 * @return returns the style name
0076:                 * @throws IndexOutOfBoundsException
0077:                 */
0078:                public String getStyleName(int row, int column) {
0079:                    return UIObject.getStyleName(getElement(row, column));
0080:                }
0081:
0082:                /**
0083:                 * Gets the primary style of a specified cell.
0084:                 * 
0085:                 * @param row the cell's row
0086:                 * @param column the cell's column
0087:                 * @see UIObject#getStylePrimaryName()
0088:                 * @return returns the style name
0089:                 * @throws IndexOutOfBoundsException
0090:                 */
0091:                public String getStylePrimaryName(int row, int column) {
0092:                    return UIObject
0093:                            .getStylePrimaryName(getElement(row, column));
0094:                }
0095:
0096:                /**
0097:                 * Determines whether or not this cell is visible.
0098:                 * 
0099:                 * @param row the row of the cell whose visibility is to be set
0100:                 * @param column the column of the cell whose visibility is to be set
0101:                 * @return <code>true</code> if the object is visible
0102:                 */
0103:                public boolean isVisible(int row, int column) {
0104:                    Element e = getElement(row, column);
0105:                    return UIObject.isVisible(e);
0106:                }
0107:
0108:                /**
0109:                 * Removes a style from the specified cell.
0110:                 * 
0111:                 * @param row the cell's row
0112:                 * @param column the cell's column
0113:                 * @param styleName the style name to be removed
0114:                 * @see UIObject#removeStyleName(String)
0115:                 * @throws IndexOutOfBoundsException
0116:                 */
0117:                public void removeStyleName(int row, int column,
0118:                        String styleName) {
0119:                    checkCellBounds(row, column);
0120:                    Element td = getCellElement(bodyElem, row, column);
0121:                    UIObject.setStyleName(td, styleName, false);
0122:                }
0123:
0124:                /**
0125:                 * Sets the horizontal and vertical alignment of the specified cell's
0126:                 * contents.
0127:                 * 
0128:                 * @param row the row of the cell whose alignment is to be set
0129:                 * @param column the cell whose alignment is to be set
0130:                 * @param hAlign the cell's new horizontal alignment as specified in
0131:                 *          {@link HasHorizontalAlignment}
0132:                 * @param vAlign the cell's new vertical alignment as specified in
0133:                 *          {@link HasVerticalAlignment}
0134:                 * @throws IndexOutOfBoundsException
0135:                 */
0136:                public void setAlignment(int row, int column,
0137:                        HorizontalAlignmentConstant hAlign,
0138:                        VerticalAlignmentConstant vAlign) {
0139:                    setHorizontalAlignment(row, column, hAlign);
0140:                    setVerticalAlignment(row, column, vAlign);
0141:                }
0142:
0143:                /**
0144:                 * Sets the height of the specified cell.
0145:                 * 
0146:                 * @param row the row of the cell whose height is to be set
0147:                 * @param column the cell whose height is to be set
0148:                 * @param height the cell's new height, in CSS units
0149:                 * @throws IndexOutOfBoundsException
0150:                 */
0151:                public void setHeight(int row, int column, String height) {
0152:                    prepareCell(row, column);
0153:                    Element elem = getCellElement(bodyElem, row, column);
0154:                    DOM.setElementProperty(elem, "height", height);
0155:                }
0156:
0157:                /**
0158:                 * Sets the horizontal alignment of the specified cell.
0159:                 * 
0160:                 * @param row the row of the cell whose alignment is to be set
0161:                 * @param column the cell whose alignment is to be set
0162:                 * @param align the cell's new horizontal alignment as specified in
0163:                 *          {@link HasHorizontalAlignment}.
0164:                 * @throws IndexOutOfBoundsException
0165:                 */
0166:                public void setHorizontalAlignment(int row, int column,
0167:                        HorizontalAlignmentConstant align) {
0168:                    prepareCell(row, column);
0169:                    Element elem = getCellElement(bodyElem, row, column);
0170:                    DOM.setElementProperty(elem, "align", align
0171:                            .getTextAlignString());
0172:                }
0173:
0174:                /**
0175:                 * Sets the style name associated with the specified cell.
0176:                 * 
0177:                 * @param row the row of the cell whose style name is to be set
0178:                 * @param column the column of the cell whose style name is to be set
0179:                 * @param styleName the new style name
0180:                 * @see UIObject#setStyleName(String)
0181:                 * @throws IndexOutOfBoundsException
0182:                 */
0183:                public void setStyleName(int row, int column, String styleName) {
0184:                    prepareCell(row, column);
0185:                    UIObject.setStyleName(
0186:                            getCellElement(bodyElem, row, column), styleName);
0187:                }
0188:
0189:                /**
0190:                 * Sets the primary style name associated with the specified cell.
0191:                 * 
0192:                 * @param row the row of the cell whose style name is to be set
0193:                 * @param column the column of the cell whose style name is to be set
0194:                 * @param styleName the new style name
0195:                 * @see UIObject#setStylePrimaryName(String)
0196:                 * @throws IndexOutOfBoundsException
0197:                 */
0198:                public void setStylePrimaryName(int row, int column,
0199:                        String styleName) {
0200:                    UIObject.setStylePrimaryName(getCellElement(bodyElem, row,
0201:                            column), styleName);
0202:                }
0203:
0204:                /**
0205:                 * Sets the vertical alignment of the specified cell.
0206:                 * 
0207:                 * @param row the row of the cell whose alignment is to be set
0208:                 * @param column the cell whose alignment is to be set
0209:                 * @param align the cell's new vertical alignment as specified in
0210:                 *          {@link HasVerticalAlignment}.
0211:                 * @throws IndexOutOfBoundsException
0212:                 */
0213:                public void setVerticalAlignment(int row, int column,
0214:                        VerticalAlignmentConstant align) {
0215:                    prepareCell(row, column);
0216:                    DOM.setStyleAttribute(
0217:                            getCellElement(bodyElem, row, column),
0218:                            "verticalAlign", align.getVerticalAlignString());
0219:                }
0220:
0221:                /**
0222:                 * Sets whether this cell is visible via the display style property. The
0223:                 * other cells in the row will all shift left to fill the cell's space. So,
0224:                 * for example a table with (0,1,2) will become (1,2) if cell 1 is hidden.
0225:                 * 
0226:                 * @param row the row of the cell whose visibility is to be set
0227:                 * @param column the column of the cell whose visibility is to be set
0228:                 * @param visible <code>true</code> to show the cell, <code>false</code>
0229:                 *          to hide it
0230:                 */
0231:                public void setVisible(int row, int column, boolean visible) {
0232:                    Element e = ensureElement(row, column);
0233:                    UIObject.setVisible(e, visible);
0234:                }
0235:
0236:                /**
0237:                 * Sets the width of the specified cell.
0238:                 * 
0239:                 * @param row the row of the cell whose width is to be set
0240:                 * @param column the cell whose width is to be set
0241:                 * @param width the cell's new width, in CSS units
0242:                 * @throws IndexOutOfBoundsException
0243:                 */
0244:                public void setWidth(int row, int column, String width) {
0245:                    // Give the subclass a chance to prepare the cell.
0246:                    prepareCell(row, column);
0247:                    DOM.setElementProperty(
0248:                            getCellElement(bodyElem, row, column), "width",
0249:                            width);
0250:                }
0251:
0252:                /**
0253:                 * Sets whether the specified cell will allow word wrapping of its contents.
0254:                 * 
0255:                 * @param row the row of the cell whose word-wrap is to be set
0256:                 * @param column the cell whose word-wrap is to be set
0257:                 * @param wrap <code>false </code> to disable word wrapping in this cell
0258:                 * @throws IndexOutOfBoundsException
0259:                 */
0260:                public void setWordWrap(int row, int column, boolean wrap) {
0261:                    prepareCell(row, column);
0262:                    String wrapValue = wrap ? "" : "nowrap";
0263:                    DOM.setStyleAttribute(getElement(row, column),
0264:                            "whiteSpace", wrapValue);
0265:                }
0266:
0267:                /**
0268:                 * Gets the element associated with a cell. If it does not exist and the
0269:                 * subtype allows creation of elements, creates it.
0270:                 * 
0271:                 * @param row the cell's row
0272:                 * @param column the cell's column
0273:                 * @return the cell's element
0274:                 * @throws IndexOutOfBoundsException
0275:                 */
0276:                protected Element ensureElement(int row, int column) {
0277:                    prepareCell(row, column);
0278:                    return getCellElement(bodyElem, row, column);
0279:                }
0280:
0281:                /**
0282:                 * Convenience methods to get an attribute on a cell.
0283:                 * 
0284:                 * @param row cell's row
0285:                 * @param column cell's column
0286:                 * @param attr attribute to get
0287:                 * @return the attribute's value
0288:                 * @throws IndexOutOfBoundsException
0289:                 */
0290:                protected String getAttr(int row, int column, String attr) {
0291:                    Element elem = getElement(row, column);
0292:                    return DOM.getElementAttribute(elem, attr);
0293:                }
0294:
0295:                /**
0296:                 * Convenience methods to set an attribute on a cell.
0297:                 * 
0298:                 * @param row cell's row
0299:                 * @param column cell's column
0300:                 * @param attrName attribute to set
0301:                 * @param value value to set
0302:                 * @throws IndexOutOfBoundsException
0303:                 */
0304:                protected void setAttr(int row, int column, String attrName,
0305:                        String value) {
0306:                    Element elem = ensureElement(row, column);
0307:                    DOM.setElementAttribute(elem, attrName, value);
0308:                }
0309:
0310:                /**
0311:                 * Native method to get a cell's element.
0312:                 * 
0313:                 * @param table the table element
0314:                 * @param row the row of the cell
0315:                 * @param col the column of the cell
0316:                 * @return the element
0317:                 */
0318:                private native Element getCellElement(Element table, int row,
0319:                        int col) /*-{
0320:                    var out = table.rows[row].cells[col];
0321:                    return (out == null ? null : out);
0322:                    }-*/;
0323:
0324:                /**
0325:                 * Gets the TD element representing the specified cell unsafely (meaning
0326:                 * that it doesn't ensure that the row and column are valid).
0327:                 * 
0328:                 * @param row the row of the cell to be retrieved
0329:                 * @param column the column of the cell to be retrieved
0330:                 * @return the column's TD element
0331:                 */
0332:                private Element getRawElement(int row, int column) {
0333:                    return getCellElement(bodyElem, row, column);
0334:                }
0335:            }
0336:
0337:            /**
0338:             * This class contains methods used to format a table's columns. It is limited
0339:             * by the support cross-browser HTML support for column formatting.
0340:             */
0341:            public class ColumnFormatter {
0342:                protected Element columnGroup;
0343:
0344:                /**
0345:                 * Adds a style to the specified column.
0346:                 * 
0347:                 * @param col the col to which the style will be added
0348:                 * @param styleName the style name to be added
0349:                 * @see UIObject#addStyleName(String)
0350:                 * @throws IndexOutOfBoundsException
0351:                 */
0352:                public void addStyleName(int col, String styleName) {
0353:                    UIObject.setStyleName(ensureColumn(col), styleName, true);
0354:                }
0355:
0356:                /**
0357:                 * Gets the style of the specified column.
0358:                 * 
0359:                 * @param column the column to be queried
0360:                 * @return the style name
0361:                 * @see UIObject#getStyleName()
0362:                 * @throws IndexOutOfBoundsException
0363:                 */
0364:                public String getStyleName(int column) {
0365:                    return UIObject.getStyleName(ensureColumn(column));
0366:                }
0367:
0368:                /**
0369:                 * Gets the primary style of the specified column.
0370:                 * 
0371:                 * @param column the column to be queried
0372:                 * @return the style name
0373:                 * @see UIObject#getStylePrimaryName()
0374:                 * @throws IndexOutOfBoundsException
0375:                 */
0376:                public String getStylePrimaryName(int column) {
0377:                    return UIObject.getStylePrimaryName(ensureColumn(column));
0378:                }
0379:
0380:                /**
0381:                 * Removes a style from the specified column.
0382:                 * 
0383:                 * @param column the column from which the style will be removed
0384:                 * @param styleName the style name to be removed
0385:                 * @see UIObject#removeStyleName(String)
0386:                 * @throws IndexOutOfBoundsException
0387:                 */
0388:                public void removeStyleName(int column, String styleName) {
0389:                    UIObject.setStyleName(ensureColumn(column), styleName,
0390:                            false);
0391:                }
0392:
0393:                /**
0394:                 * Sets the style name associated with the specified column.
0395:                 * 
0396:                 * @param column the column whose style name is to be set
0397:                 * @param styleName the new style name
0398:                 * @see UIObject#setStyleName(String)
0399:                 * @throws IndexOutOfBoundsException
0400:                 */
0401:                public void setStyleName(int column, String styleName) {
0402:                    UIObject.setStyleName(ensureColumn(column), styleName);
0403:                }
0404:
0405:                /**
0406:                 * Sets the primary style name associated with the specified column.
0407:                 * 
0408:                 * @param column the column whose style name is to be set
0409:                 * @param styleName the new style name
0410:                 * @see UIObject#setStylePrimaryName(String)
0411:                 * @throws IndexOutOfBoundsException
0412:                 */
0413:                public void setStylePrimaryName(int column, String styleName) {
0414:                    UIObject.setStylePrimaryName(ensureColumn(column),
0415:                            styleName);
0416:                }
0417:
0418:                /**
0419:                 * Sets the width of the specified column.
0420:                 * 
0421:                 * @param column the column of the cell whose width is to be set
0422:                 * @param width the cell's new width, in percentage or pixel units
0423:                 * @throws IndexOutOfBoundsException
0424:                 */
0425:                public void setWidth(int column, String width) {
0426:                    DOM
0427:                            .setElementProperty(ensureColumn(column), "width",
0428:                                    width);
0429:                }
0430:
0431:                private Element ensureColumn(int col) {
0432:                    prepareColumn(col);
0433:                    prepareColumnGroup();
0434:
0435:                    int num = DOM.getChildCount(columnGroup);
0436:                    if (num <= col) {
0437:                        Element colElement = null;
0438:                        for (int i = num; i <= col; i++) {
0439:                            colElement = DOM.createElement("col");
0440:                            DOM.appendChild(columnGroup, colElement);
0441:                        }
0442:                        return colElement;
0443:                    }
0444:                    return DOM.getChild(columnGroup, col);
0445:                }
0446:
0447:                /**
0448:                 * Prepare the colgroup tag for the first time, guarenteeing that it
0449:                 * exists and has at least one col tag in it.  This method corrects
0450:                 * a Mozilla issue where the col tag will affect the wrong column if
0451:                 * a col tag doesn't exist when the element is attached to the page.
0452:                 */
0453:                private void prepareColumnGroup() {
0454:                    if (columnGroup == null) {
0455:                        columnGroup = DOM.createElement("colgroup");
0456:                        DOM.insertChild(tableElem, columnGroup, 0);
0457:                        DOM.appendChild(columnGroup, DOM.createElement("col"));
0458:                    }
0459:                }
0460:            }
0461:
0462:            /**
0463:             * This class contains methods used to format a table's rows.
0464:             */
0465:            public class RowFormatter {
0466:
0467:                /**
0468:                 * Adds a style to the specified row.
0469:                 * 
0470:                 * @param row the row to which the style will be added
0471:                 * @param styleName the style name to be added
0472:                 * @see UIObject#addStyleName(String)
0473:                 * @throws IndexOutOfBoundsException
0474:                 */
0475:                public void addStyleName(int row, String styleName) {
0476:                    UIObject.setStyleName(ensureElement(row), styleName, true);
0477:                }
0478:
0479:                /**
0480:                 * Gets the TR element representing the specified row.
0481:                 * 
0482:                 * @param row the row whose TR element is to be retrieved
0483:                 * @return the row's TR element
0484:                 * @throws IndexOutOfBoundsException
0485:                 */
0486:                public Element getElement(int row) {
0487:                    checkRowBounds(row);
0488:                    return getRow(bodyElem, row);
0489:                }
0490:
0491:                /**
0492:                 * Gets the style of the specified row.
0493:                 * 
0494:                 * @param row the row to be queried
0495:                 * @return the style name
0496:                 * @see UIObject#getStyleName()
0497:                 * @throws IndexOutOfBoundsException
0498:                 */
0499:                public String getStyleName(int row) {
0500:                    return UIObject.getStyleName(getElement(row));
0501:                }
0502:
0503:                /**
0504:                 * Gets the primary style of the specified row.
0505:                 * 
0506:                 * @param row the row to be queried
0507:                 * @return the style name
0508:                 * @see UIObject#getStylePrimaryName()
0509:                 * @throws IndexOutOfBoundsException
0510:                 */
0511:                public String getStylePrimaryName(int row) {
0512:                    return UIObject.getStylePrimaryName(getElement(row));
0513:                }
0514:
0515:                /**
0516:                 * Determines whether or not this row is visible via the display style
0517:                 * attribute.
0518:                 * 
0519:                 * @param row the row whose visibility is to be set
0520:                 * @return <code>true</code> if the row is visible
0521:                 */
0522:                public boolean isVisible(int row) {
0523:                    Element e = getElement(row);
0524:                    return UIObject.isVisible(e);
0525:                }
0526:
0527:                /**
0528:                 * Removes a style from the specified row.
0529:                 * 
0530:                 * @param row the row from which the style will be removed
0531:                 * @param styleName the style name to be removed
0532:                 * @see UIObject#removeStyleName(String)
0533:                 * @throws IndexOutOfBoundsException
0534:                 */
0535:                public void removeStyleName(int row, String styleName) {
0536:                    UIObject.setStyleName(ensureElement(row), styleName, false);
0537:                }
0538:
0539:                /**
0540:                 * Sets the style name associated with the specified row.
0541:                 * 
0542:                 * @param row the row whose style name is to be set
0543:                 * @param styleName the new style name
0544:                 * @see UIObject#setStyleName(String)
0545:                 * @throws IndexOutOfBoundsException
0546:                 */
0547:                public void setStyleName(int row, String styleName) {
0548:                    UIObject.setStyleName(ensureElement(row), styleName);
0549:                }
0550:
0551:                /**
0552:                 * Sets the primary style name associated with the specified row.
0553:                 * 
0554:                 * @param row the row whose style name is to be set
0555:                 * @param styleName the new style name
0556:                 * @see UIObject#setStylePrimaryName(String)
0557:                 * @throws IndexOutOfBoundsException
0558:                 */
0559:                public void setStylePrimaryName(int row, String styleName) {
0560:                    UIObject.setStylePrimaryName(ensureElement(row), styleName);
0561:                }
0562:
0563:                /**
0564:                 * Sets the vertical alignment of the specified row.
0565:                 * 
0566:                 * @param row the row whose alignment is to be set
0567:                 * @param align the row's new vertical alignment as specified in
0568:                 *          {@link HasVerticalAlignment}
0569:                 * @throws IndexOutOfBoundsException
0570:                 */
0571:                public void setVerticalAlign(int row,
0572:                        VerticalAlignmentConstant align) {
0573:                    DOM.setStyleAttribute(ensureElement(row), "verticalAlign",
0574:                            align.getVerticalAlignString());
0575:                }
0576:
0577:                /**
0578:                 * Sets whether this row is visible.
0579:                 * 
0580:                 * @param row the row whose visibility is to be set
0581:                 * @param visible <code>true</code> to show the row, <code>false</code>
0582:                 *          to hide it
0583:                 */
0584:                public void setVisible(int row, boolean visible) {
0585:                    Element e = ensureElement(row);
0586:                    UIObject.setVisible(e, visible);
0587:                }
0588:
0589:                /**
0590:                 * Ensure the TR element representing the specified row exists for
0591:                 * subclasses that allow dynamic addition of elements.
0592:                 * 
0593:                 * @param row the row whose TR element is to be retrieved
0594:                 * @return the row's TR element
0595:                 * @throws IndexOutOfBoundsException
0596:                 */
0597:                protected Element ensureElement(int row) {
0598:                    prepareRow(row);
0599:                    return getRow(bodyElem, row);
0600:                }
0601:
0602:                protected native Element getRow(Element elem, int row)/*-{
0603:                     return elem.rows[row];
0604:                     }-*/;
0605:
0606:                /**
0607:                 * Convenience methods to set an attribute on a row.
0608:                 * 
0609:                 * @param row cell's row
0610:                 * @param attrName attribute to set
0611:                 * @param value value to set
0612:                 * @throws IndexOutOfBoundsException
0613:                 */
0614:                protected void setAttr(int row, String attrName, String value) {
0615:                    Element elem = ensureElement(row);
0616:                    DOM.setElementAttribute(elem, attrName, value);
0617:                }
0618:            }
0619:
0620:            /**
0621:             * Creates a mapping from elements to their associated widgets.
0622:             */
0623:            private static class WidgetMapper {
0624:
0625:                private static class FreeNode {
0626:                    int index;
0627:                    FreeNode next;
0628:
0629:                    public FreeNode(int index, FreeNode next) {
0630:                        this .index = index;
0631:                        this .next = next;
0632:                    }
0633:                }
0634:
0635:                private static native void clearWidgetIndex(Element elem) /*-{
0636:                     elem["__widgetID"] = null;
0637:                   }-*/;
0638:
0639:                private static native int getWidgetIndex(Element elem) /*-{
0640:                     var index = elem["__widgetID"];
0641:                     return (index == null) ? -1 : index;
0642:                   }-*/;
0643:
0644:                private static native void setWidgetIndex(Element elem,
0645:                        int index) /*-{
0646:                     elem["__widgetID"] = index;
0647:                   }-*/;
0648:
0649:                private FreeNode freeList = null;
0650:
0651:                private final ArrayList<Widget> widgetList = new ArrayList<Widget>();
0652:
0653:                /**
0654:                 * Returns the widget associated with the given element.
0655:                 * 
0656:                 * @param elem widget's element
0657:                 * @return the widget
0658:                 */
0659:                public Widget getWidget(Element elem) {
0660:                    int index = getWidgetIndex(elem);
0661:                    if (index < 0) {
0662:                        return null;
0663:                    }
0664:                    return widgetList.get(index);
0665:                }
0666:
0667:                /**
0668:                 * Adds the Widget.
0669:                 * 
0670:                 * @param widget widget to add
0671:                 */
0672:                public void putWidget(Widget widget) {
0673:                    int index;
0674:                    if (freeList == null) {
0675:                        index = widgetList.size();
0676:                        widgetList.add(widget);
0677:                    } else {
0678:                        index = freeList.index;
0679:                        widgetList.set(index, widget);
0680:                        freeList = freeList.next;
0681:                    }
0682:                    setWidgetIndex(widget.getElement(), index);
0683:                }
0684:
0685:                /**
0686:                 * Remove the widget associated with the given element.
0687:                 * 
0688:                 * @param elem the widget's element
0689:                 */
0690:                public void removeWidgetByElement(Element elem) {
0691:                    int index = getWidgetIndex(elem);
0692:                    removeImpl(elem, index);
0693:                }
0694:
0695:                /**
0696:                 * Creates an iterator of widgets.
0697:                 * 
0698:                 * @return the iterator
0699:                 */
0700:                public Iterator<Widget> widgetIterator() {
0701:                    // TODO: look at using the WidgetIterators class!
0702:                    return new Iterator<Widget>() {
0703:                        int lastIndex = -1;
0704:                        int nextIndex = -1;
0705:                        {
0706:                            findNext();
0707:                        }
0708:
0709:                        public boolean hasNext() {
0710:                            return nextIndex < widgetList.size();
0711:                        }
0712:
0713:                        public Widget next() {
0714:                            if (!hasNext()) {
0715:                                throw new NoSuchElementException();
0716:                            }
0717:                            Widget result = widgetList.get(nextIndex);
0718:                            lastIndex = nextIndex;
0719:                            findNext();
0720:                            return result;
0721:                        }
0722:
0723:                        public void remove() {
0724:                            if (lastIndex < 0) {
0725:                                throw new IllegalStateException();
0726:                            }
0727:                            Widget w = widgetList.get(lastIndex);
0728:                            assert (w.getParent() instanceof  HTMLTable);
0729:                            w.removeFromParent();
0730:                            lastIndex = -1;
0731:                        }
0732:
0733:                        private void findNext() {
0734:                            while (++nextIndex < widgetList.size()) {
0735:                                if (widgetList.get(nextIndex) != null) {
0736:                                    return;
0737:                                }
0738:                            }
0739:                        }
0740:                    };
0741:                }
0742:
0743:                private void removeImpl(Element elem, int index) {
0744:                    clearWidgetIndex(elem);
0745:                    widgetList.set(index, null);
0746:                    freeList = new FreeNode(index, freeList);
0747:                }
0748:            }
0749:
0750:            /**
0751:             * Table's body.
0752:             */
0753:            private final Element bodyElem;
0754:
0755:            /**
0756:             * Current cell formatter.
0757:             */
0758:            private CellFormatter cellFormatter;
0759:
0760:            /**
0761:             * Column Formatter.
0762:             */
0763:            private ColumnFormatter columnFormatter;
0764:
0765:            /**
0766:             * Current row formatter.
0767:             */
0768:            private RowFormatter rowFormatter;
0769:
0770:            /**
0771:             * Table element.
0772:             */
0773:            private final Element tableElem;
0774:
0775:            /**
0776:             * Current table listener.
0777:             */
0778:            private TableListenerCollection tableListeners;
0779:
0780:            private WidgetMapper widgetMap = new WidgetMapper();
0781:
0782:            /**
0783:             * Create a new empty HTML Table.
0784:             */
0785:            public HTMLTable() {
0786:                tableElem = DOM.createTable();
0787:                bodyElem = DOM.createTBody();
0788:                DOM.appendChild(tableElem, bodyElem);
0789:                setElement(tableElem);
0790:                sinkEvents(Event.ONCLICK);
0791:            }
0792:
0793:            /**
0794:             * Adds a listener to the current table.
0795:             * 
0796:             * @param listener listener to add
0797:             */
0798:            public void addTableListener(TableListener listener) {
0799:                if (tableListeners == null) {
0800:                    tableListeners = new TableListenerCollection();
0801:                }
0802:                tableListeners.add(listener);
0803:            }
0804:
0805:            /**
0806:             * Removes all widgets from this table, but does not remove other HTML or text
0807:             * contents of cells.
0808:             */
0809:            @Override
0810:            public void clear() {
0811:                for (int row = 0; row < getRowCount(); ++row) {
0812:                    for (int col = 0; col < getCellCount(row); ++col) {
0813:                        Widget child = getWidgetImpl(row, col);
0814:                        if (child != null) {
0815:                            remove(child);
0816:                        }
0817:                    }
0818:                }
0819:            }
0820:
0821:            /**
0822:             * Clears the given row and column. If it contains a Widget, it will be
0823:             * removed from the table. If not, its contents will simply be cleared.
0824:             * 
0825:             * @param row the widget's column
0826:             * @param column the widget's column
0827:             * @return true if a widget was removed
0828:             * @throws IndexOutOfBoundsException
0829:             */
0830:            public boolean clearCell(int row, int column) {
0831:                Element td = getCellFormatter().getElement(row, column);
0832:                return internalClearCell(td, true);
0833:            }
0834:
0835:            /**
0836:             * Gets the number of cells in a given row.
0837:             * 
0838:             * @param row the row whose cells are to be counted
0839:             * @return the number of cells present in the row
0840:             */
0841:            public abstract int getCellCount(int row);
0842:
0843:            /**
0844:             * Gets the {@link CellFormatter} associated with this table. Use casting to
0845:             * get subclass-specific functionality
0846:             * 
0847:             * @return this table's cell formatter
0848:             */
0849:            public CellFormatter getCellFormatter() {
0850:                return cellFormatter;
0851:            }
0852:
0853:            /**
0854:             * Gets the amount of padding that is added around all cells.
0855:             * 
0856:             * @return the cell padding, in pixels
0857:             */
0858:            public int getCellPadding() {
0859:                return DOM.getElementPropertyInt(tableElem, "cellPadding");
0860:            }
0861:
0862:            /**
0863:             * Gets the amount of spacing that is added around all cells.
0864:             * 
0865:             * @return the cell spacing, in pixels
0866:             */
0867:            public int getCellSpacing() {
0868:                return DOM.getElementPropertyInt(tableElem, "cellSpacing");
0869:            }
0870:
0871:            /**
0872:             * Gets the column formatter.
0873:             * 
0874:             * @return the column formatter
0875:             */
0876:            public ColumnFormatter getColumnFormatter() {
0877:                return columnFormatter;
0878:            }
0879:
0880:            /**
0881:             * Gets the HTML contents of the specified cell.
0882:             * 
0883:             * @param row the cell's row
0884:             * @param column the cell's column
0885:             * @return the cell's HTML contents
0886:             * @throws IndexOutOfBoundsException
0887:             */
0888:            public String getHTML(int row, int column) {
0889:                return DOM.getInnerHTML(cellFormatter.getElement(row, column));
0890:            }
0891:
0892:            /**
0893:             * Gets the number of rows present in this table.
0894:             * 
0895:             * @return the table's row count
0896:             */
0897:            public abstract int getRowCount();
0898:
0899:            /**
0900:             * Gets the RowFormatter associated with this table.
0901:             * 
0902:             * @return the table's row formatter
0903:             */
0904:            public RowFormatter getRowFormatter() {
0905:                return rowFormatter;
0906:            }
0907:
0908:            /**
0909:             * Gets the text within the specified cell.
0910:             * 
0911:             * @param row the cell's row
0912:             * @param column the cell's column
0913:             * @return the cell's text contents
0914:             * @throws IndexOutOfBoundsException
0915:             */
0916:            public String getText(int row, int column) {
0917:                checkCellBounds(row, column);
0918:                Element e = cellFormatter.getElement(row, column);
0919:                return DOM.getInnerText(e);
0920:            }
0921:
0922:            /**
0923:             * Gets the widget in the specified cell.
0924:             * 
0925:             * @param row the cell's row
0926:             * @param column the cell's column
0927:             * @return the widget in the specified cell, or <code>null</code> if none is
0928:             *         present
0929:             * @throws IndexOutOfBoundsException
0930:             */
0931:            public Widget getWidget(int row, int column) {
0932:                checkCellBounds(row, column);
0933:                return getWidgetImpl(row, column);
0934:            }
0935:
0936:            /**
0937:             * Determines whether the specified cell exists.
0938:             * 
0939:             * @param row the cell's row
0940:             * @param column the cell's column
0941:             * @return <code>true</code> if the specified cell exists
0942:             */
0943:            public boolean isCellPresent(int row, int column) {
0944:                if ((row >= getRowCount()) || (row < 0)) {
0945:                    return false;
0946:                }
0947:                if ((column < 0) || (column >= getCellCount(row))) {
0948:                    return false;
0949:                } else {
0950:                    return true;
0951:                }
0952:            }
0953:
0954:            /**
0955:             * Returns an iterator containing all the widgets in this table.
0956:             * 
0957:             * @return the iterator
0958:             */
0959:            public Iterator<Widget> iterator() {
0960:                return widgetMap.widgetIterator();
0961:            }
0962:
0963:            /**
0964:             * Method to process events generated from the browser.
0965:             * 
0966:             * @param event the generated event
0967:             */
0968:            @Override
0969:            public void onBrowserEvent(Event event) {
0970:                switch (DOM.eventGetType(event)) {
0971:                case Event.ONCLICK: {
0972:                    if (tableListeners != null) {
0973:                        // Find out which cell was actually clicked.
0974:                        Element td = getEventTargetCell(event);
0975:                        if (td == null) {
0976:                            return;
0977:                        }
0978:                        Element tr = DOM.getParent(td);
0979:                        Element body = DOM.getParent(tr);
0980:                        int row = DOM.getChildIndex(body, tr);
0981:                        int column = DOM.getChildIndex(tr, td);
0982:                        // Fire the event.
0983:                        tableListeners.fireCellClicked(this , row, column);
0984:                    }
0985:                    break;
0986:                }
0987:                default: {
0988:                    // Do nothing
0989:                }
0990:                }
0991:            }
0992:
0993:            /**
0994:             * Remove the specified widget from the table.
0995:             * 
0996:             * @param widget widget to remove
0997:             * @return was the widget removed from the table.
0998:             */
0999:            @Override
1000:            public boolean remove(Widget widget) {
1001:                // Validate.
1002:                if (widget.getParent() != this ) {
1003:                    return false;
1004:                }
1005:
1006:                // Orphan.
1007:                orphan(widget);
1008:
1009:                // Physical detach.
1010:                Element elem = widget.getElement();
1011:                DOM.removeChild(DOM.getParent(elem), elem);
1012:
1013:                // Logical detach.
1014:                widgetMap.removeWidgetByElement(elem);
1015:                return true;
1016:            }
1017:
1018:            /**
1019:             * Removes the specified table listener.
1020:             * 
1021:             * @param listener listener to remove
1022:             */
1023:            public void removeTableListener(TableListener listener) {
1024:                if (tableListeners != null) {
1025:                    tableListeners.remove(listener);
1026:                }
1027:            }
1028:
1029:            /**
1030:             * Sets the width of the table's border. This border is displayed around all
1031:             * cells in the table.
1032:             * 
1033:             * @param width the width of the border, in pixels
1034:             */
1035:            public void setBorderWidth(int width) {
1036:                DOM.setElementProperty(tableElem, "border", "" + width);
1037:            }
1038:
1039:            /**
1040:             * Sets the amount of padding to be added around all cells.
1041:             * 
1042:             * @param padding the cell padding, in pixels
1043:             */
1044:            public void setCellPadding(int padding) {
1045:                DOM.setElementPropertyInt(tableElem, "cellPadding", padding);
1046:            }
1047:
1048:            /**
1049:             * Sets the amount of spacing to be added around all cells.
1050:             * 
1051:             * @param spacing the cell spacing, in pixels
1052:             */
1053:            public void setCellSpacing(int spacing) {
1054:                DOM.setElementPropertyInt(tableElem, "cellSpacing", spacing);
1055:            }
1056:
1057:            /**
1058:             * Sets the HTML contents of the specified cell.
1059:             * 
1060:             * @param row the cell's row
1061:             * @param column the cell's column
1062:             * @param html the cell's HTML contents
1063:             * @throws IndexOutOfBoundsException
1064:             */
1065:            public void setHTML(int row, int column, String html) {
1066:                prepareCell(row, column);
1067:                Element td = cleanCell(row, column, html == null);
1068:                if (html != null) {
1069:                    DOM.setInnerHTML(td, html);
1070:                }
1071:            }
1072:
1073:            /**
1074:             * Sets the text within the specified cell.
1075:             * 
1076:             * @param row the cell's row
1077:             * @param column cell's column
1078:             * @param text the cell's text contents
1079:             * @throws IndexOutOfBoundsException
1080:             */
1081:            public void setText(int row, int column, String text) {
1082:                prepareCell(row, column);
1083:                Element td;
1084:                td = cleanCell(row, column, text == null);
1085:                if (text != null) {
1086:                    DOM.setInnerText(td, text);
1087:                }
1088:            }
1089:
1090:            /**
1091:             * Sets the widget within the specified cell.
1092:             * <p>
1093:             * Inherited implementations may either throw IndexOutOfBounds exception if
1094:             * the cell does not exist, or allocate a new cell to store the content.
1095:             * </p>
1096:             * <p>
1097:             * FlexTable will automatically allocate the cell at the correct location and
1098:             * then set the widget. Grid will set the widget if and only if the cell is
1099:             * within the Grid's bounding box.
1100:             * </p>
1101:             * 
1102:             * @param widget The widget to be added
1103:             * @param row the cell's row
1104:             * @param column the cell's column
1105:             * @throws IndexOutOfBoundsException
1106:             */
1107:            public void setWidget(int row, int column, Widget widget) {
1108:                prepareCell(row, column);
1109:                if (widget != null) {
1110:                    widget.removeFromParent();
1111:
1112:                    // Removes any existing widget.
1113:                    Element td = cleanCell(row, column, true);
1114:
1115:                    // Logical attach.
1116:                    widgetMap.putWidget(widget);
1117:
1118:                    // Physical attach.
1119:                    DOM.appendChild(td, widget.getElement());
1120:
1121:                    adopt(widget);
1122:                }
1123:            }
1124:
1125:            /**
1126:             * Bounds checks that the cell exists at the specified location.
1127:             * 
1128:             * @param row cell's row
1129:             * @param column cell's column
1130:             * @throws IndexOutOfBoundsException
1131:             */
1132:            protected void checkCellBounds(int row, int column) {
1133:                checkRowBounds(row);
1134:                if (column < 0) {
1135:                    throw new IndexOutOfBoundsException("Column " + column
1136:                            + " must be non-negative: " + column);
1137:                }
1138:                int cellSize = getCellCount(row);
1139:                if (cellSize <= column) {
1140:                    throw new IndexOutOfBoundsException("Column index: "
1141:                            + column + ", Column size: " + getCellCount(row));
1142:                }
1143:            }
1144:
1145:            /**
1146:             * Checks that the row is within the correct bounds.
1147:             * 
1148:             * @param row row index to check
1149:             * @throws IndexOutOfBoundsException
1150:             */
1151:            protected void checkRowBounds(int row) {
1152:                int rowSize = getRowCount();
1153:                if ((row >= rowSize) || (row < 0)) {
1154:                    throw new IndexOutOfBoundsException("Row index: " + row
1155:                            + ", Row size: " + rowSize);
1156:                }
1157:            }
1158:
1159:            /**
1160:             * Creates a new cell. Override this method if the cell should have initial
1161:             * contents.
1162:             * 
1163:             * @return the newly created TD
1164:             */
1165:            protected Element createCell() {
1166:                return DOM.createTD();
1167:            }
1168:
1169:            /**
1170:             * Gets the table's TBODY element.
1171:             * 
1172:             * @return the TBODY element
1173:             */
1174:            protected Element getBodyElement() {
1175:                return bodyElem;
1176:            }
1177:
1178:            /**
1179:             * Directly ask the underlying DOM what the cell count on the given row is.
1180:             * 
1181:             * @param tableBody the element
1182:             * @param row the row
1183:             * @return number of columns in the row
1184:             */
1185:            protected native int getDOMCellCount(Element tableBody, int row) /*-{
1186:              return tableBody.rows[row].cells.length;
1187:              }-*/;
1188:
1189:            /**
1190:             * Directly ask the underlying DOM what the cell count on the given row is.
1191:             * 
1192:             * @param row the row
1193:             * @return number of columns in the row
1194:             */
1195:            protected int getDOMCellCount(int row) {
1196:                return getDOMCellCount(bodyElem, row);
1197:            }
1198:
1199:            /**
1200:             * Directly ask the underlying DOM what the row count is.
1201:             * 
1202:             * @return Returns the number of rows in the table
1203:             */
1204:            protected int getDOMRowCount() {
1205:                return getDOMRowCount(bodyElem);
1206:            }
1207:
1208:            protected native int getDOMRowCount(Element elem) /*-{
1209:              return elem.rows.length;
1210:              }-*/;
1211:
1212:            /**
1213:             * Determines the TD associated with the specified event.
1214:             * 
1215:             * @param event the event to be queried
1216:             * @return the TD associated with the event, or <code>null</code> if none is
1217:             *         found.
1218:             */
1219:            protected Element getEventTargetCell(Event event) {
1220:                Element td = DOM.eventGetTarget(event);
1221:                for (; td != null; td = DOM.getParent(td)) {
1222:                    // If it's a TD, it might be the one we're looking for.
1223:                    if (DOM.getElementProperty(td, "tagName").equalsIgnoreCase(
1224:                            "td")) {
1225:                        // Make sure it's directly a part of this table before returning
1226:                        // it.
1227:                        Element tr = DOM.getParent(td);
1228:                        Element body = DOM.getParent(tr);
1229:                        if (DOM.compare(body, bodyElem)) {
1230:                            return td;
1231:                        }
1232:                    }
1233:                    // If we run into this table's body, we're out of options.
1234:                    if (DOM.compare(td, bodyElem)) {
1235:                        return null;
1236:                    }
1237:                }
1238:                return null;
1239:            }
1240:
1241:            /**
1242:             * Inserts a new cell into the specified row.
1243:             * 
1244:             * @param row the row into which the new cell will be inserted
1245:             * @param column the column before which the cell will be inserted
1246:             * @throws IndexOutOfBoundsException
1247:             */
1248:            protected void insertCell(int row, int column) {
1249:                Element tr = rowFormatter.getRow(bodyElem, row);
1250:                Element td = createCell();
1251:                DOM.insertChild(tr, td, column);
1252:            }
1253:
1254:            /**
1255:             * Inserts a number of cells before the specified cell.
1256:             * 
1257:             * @param row the row into which the new cells will be inserted
1258:             * @param column the column before which the new cells will be inserted
1259:             * @param count number of cells to be inserted
1260:             * @throws IndexOutOfBoundsException
1261:             */
1262:            protected void insertCells(int row, int column, int count) {
1263:                Element tr = rowFormatter.getRow(bodyElem, row);
1264:                for (int i = column; i < column + count; i++) {
1265:                    Element td = createCell();
1266:                    DOM.insertChild(tr, td, i);
1267:                }
1268:            }
1269:
1270:            /**
1271:             * Inserts a new row into the table.
1272:             * 
1273:             * @param beforeRow the index before which the new row will be inserted
1274:             * @return the index of the newly-created row
1275:             * @throws IndexOutOfBoundsException
1276:             */
1277:            protected int insertRow(int beforeRow) {
1278:                // Specifically allow the row count as an insert position.
1279:                if (beforeRow != getRowCount()) {
1280:                    checkRowBounds(beforeRow);
1281:                }
1282:                Element tr = DOM.createTR();
1283:                DOM.insertChild(bodyElem, tr, beforeRow);
1284:                return beforeRow;
1285:            }
1286:
1287:            /**
1288:             * Does actual clearing, used by clearCell and cleanCell. All HTMLTable
1289:             * methods should use internalClearCell rather than clearCell, as clearCell
1290:             * may be overridden in subclasses to format an empty cell.
1291:             * 
1292:             * @param td element to clear
1293:             * @param clearInnerHTML should the cell's inner html be cleared?
1294:             * @return returns whether a widget was cleared
1295:             */
1296:            protected boolean internalClearCell(Element td,
1297:                    boolean clearInnerHTML) {
1298:                Element maybeChild = DOM.getFirstChild(td);
1299:                Widget widget = null;
1300:                if (maybeChild != null) {
1301:                    widget = widgetMap.getWidget(maybeChild);
1302:                }
1303:                if (widget != null) {
1304:                    // If there is a widget, remove it.
1305:                    remove(widget);
1306:                    return true;
1307:                } else {
1308:                    // Otherwise, simply clear whatever text and/or HTML may be there.
1309:                    if (clearInnerHTML) {
1310:                        DOM.setInnerHTML(td, "");
1311:                    }
1312:                    return false;
1313:                }
1314:            }
1315:
1316:            /**
1317:             * Subclasses must implement this method. It allows them to decide what to do
1318:             * just before a cell is accessed. If the cell already exists, this method
1319:             * must do nothing. Otherwise, a subclass must either ensure that the cell
1320:             * exists or throw an {@link IndexOutOfBoundsException}.
1321:             * 
1322:             * @param row the cell's row
1323:             * @param column the cell's column
1324:             */
1325:            protected abstract void prepareCell(int row, int column);
1326:
1327:            /**
1328:             * Subclasses can implement this method. It allows them to decide what to do
1329:             * just before a column is accessed. For classes, such as
1330:             * <code>FlexTable</code>, that do not have a concept of a global column
1331:             * length can ignore this method.
1332:             * 
1333:             * @param column the cell's column
1334:             * @throws IndexOutOfBoundsException
1335:             */
1336:            protected void prepareColumn(int column) {
1337:                // By default, do nothing.
1338:            }
1339:
1340:            /**
1341:             * Subclasses must implement this method. If the row already exists, this
1342:             * method must do nothing. Otherwise, a subclass must either ensure that the
1343:             * row exists or throw an {@link IndexOutOfBoundsException}.
1344:             * 
1345:             * @param row the cell's row
1346:             */
1347:            protected abstract void prepareRow(int row);
1348:
1349:            /**
1350:             * Removes the specified cell from the table.
1351:             * 
1352:             * @param row the row of the cell to remove
1353:             * @param column the column of cell to remove
1354:             * @throws IndexOutOfBoundsException
1355:             */
1356:            protected void removeCell(int row, int column) {
1357:                checkCellBounds(row, column);
1358:                Element td = cleanCell(row, column, false);
1359:                Element tr = rowFormatter.getRow(bodyElem, row);
1360:                DOM.removeChild(tr, td);
1361:            }
1362:
1363:            /**
1364:             * Removes the specified row from the table.
1365:             * 
1366:             * @param row the index of the row to be removed
1367:             * @throws IndexOutOfBoundsException
1368:             */
1369:            protected void removeRow(int row) {
1370:                int columnCount = getCellCount(row);
1371:                for (int column = 0; column < columnCount; ++column) {
1372:                    cleanCell(row, column, false);
1373:                }
1374:                DOM.removeChild(bodyElem, rowFormatter.getRow(bodyElem, row));
1375:            }
1376:
1377:            /**
1378:             * Sets the table's CellFormatter.
1379:             * 
1380:             * @param cellFormatter the table's cell formatter
1381:             */
1382:            protected void setCellFormatter(CellFormatter cellFormatter) {
1383:                this .cellFormatter = cellFormatter;
1384:            }
1385:
1386:            protected void setColumnFormatter(ColumnFormatter formatter) {
1387:                columnFormatter = formatter;
1388:                columnFormatter.prepareColumnGroup();
1389:            }
1390:
1391:            /**
1392:             * Sets the table's RowFormatter.
1393:             * 
1394:             * @param rowFormatter the table's row formatter
1395:             */
1396:            protected void setRowFormatter(RowFormatter rowFormatter) {
1397:                this .rowFormatter = rowFormatter;
1398:            }
1399:
1400:            /**
1401:             * Removes any widgets, text, and HTML within the cell. This method assumes
1402:             * that the requested cell already exists.
1403:             * 
1404:             * @param row the cell's row
1405:             * @param column the cell's column
1406:             * @param clearInnerHTML should the cell's inner html be cleared?
1407:             * @return element that has been cleaned
1408:             */
1409:            private Element cleanCell(int row, int column,
1410:                    boolean clearInnerHTML) {
1411:                // Clear whatever is in the cell.
1412:                Element td = getCellFormatter().getRawElement(row, column);
1413:                internalClearCell(td, clearInnerHTML);
1414:                return td;
1415:            }
1416:
1417:            /**
1418:             * Gets the Widget associated with the given cell.
1419:             * 
1420:             * @param row the cell's row
1421:             * @param column the cell's column
1422:             * @return the widget
1423:             */
1424:            private Widget getWidgetImpl(int row, int column) {
1425:                Element e = cellFormatter.getRawElement(row, column);
1426:                Element child = DOM.getFirstChild(e);
1427:                if (child == null) {
1428:                    return null;
1429:                } else {
1430:                    return widgetMap.getWidget(child);
1431:                }
1432:            }
1433:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.