Java tutorial
/* * Copyright 2008 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.google.gwt.user.client.ui; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.TableCellElement; import com.google.gwt.dom.client.TableRowElement; import com.google.gwt.user.client.DOM; /** * A rectangular grid that can contain text, html, or a child * {@link com.google.gwt.user.client.ui.Widget} within its cells. It must be * resized explicitly to the desired number of rows and columns. * <p> * <img class='gallery' src='doc-files/Table.png'/> * </p> * <p> * <h3>Example</h3> {@example com.google.gwt.examples.GridExample} * </p> * * <h3>Use in UiBinder Templates</h3> * <p> * Grid widget consists of <g:row> elements. Each <g:row> element can * contain one or more <g:cell> or <g:customCell> elements. Using * <g:cell> attribute it is possible to place pure HTML content. * <g:customCell> is used as a container for * {@link com.google.gwt.user.client.ui.Widget} type objects. (Note that the * tags of the row, cell and customCell elements are not capitalized. This is * meant to signal that the item is not a runtime object, and so cannot have a * <code>ui:field</code> attribute.) * <p> * For example: * * <pre> * <g:Grid> * <g:row styleName="optionalHeaderStyle"> * <g:customCell styleName="optionalFooCellStyle"> * <g:Label>foo</g:Label> * </g:customCell> * <g:customCell styleName="optionalBarCellStyle"> * <g:Label>bar</g:Label> * </g:customCell> * </g:row> * <g:row> * <g:cell> * <div>foo</div> * </g:cell> * <g:cell> * <div>bar</div> * </g:cell> * </g:row> * </g:Grid> * </pre> */ public class Grid extends HTMLTable { /** * Native method to add rows into a table with a given number of columns. * * @param table * the table element * @param rows * number of rows to add * @param columns * the number of columns per row */ private static void addRows(Element table, int rows, int columns) { for (int rowIdx = 0; rowIdx < rows; rowIdx++) { TableRowElement row = Document.get().createTRElement(); for (int cellIdx = 0; cellIdx < columns; cellIdx++) { TableCellElement cell = Document.get().createTDElement(); cell.setInnerText("\u00A0"); row.appendChild(cell); } table.appendChild(row); } } private static native void addRows0(Element table, int rows, int columns) /*-{ var td = $doc.createElement("td"); td.innerHTML = " "; var row = $doc.createElement("tr"); for(var cellNum = 0; cellNum < columns; cellNum++) { var cell = td.cloneNode(true); row.appendChild(cell); } table.appendChild(row); for(var rowNum = 1; rowNum < rows; rowNum++) { table.appendChild(row.cloneNode(true)); } }-*/; /** * Number of columns in the current grid. */ protected int numColumns; /** * Number of rows in the current grid. */ protected int numRows; /** * Constructor for <code>Grid</code>. */ public Grid() { super(); setCellFormatter(new CellFormatter()); setRowFormatter(new RowFormatter()); setColumnFormatter(new ColumnFormatter()); } /** * Constructs a grid with the requested size. * * @param rows * the number of rows * @param columns * the number of columns * @throws IndexOutOfBoundsException */ public Grid(int rows, int columns) { this(); resize(rows, columns); } /** * Replaces the contents of the specified cell with a single space. * * @param row * the cell's row * @param column * the cell's column * @throws IndexOutOfBoundsException */ @Override public boolean clearCell(int row, int column) { Element td = getCellFormatter().getElement(row, column); boolean b = internalClearCell(td, false); td.setInnerHTML(" "); return b; } /** * Return number of columns. For grid, row argument is ignored as all grids * are rectangular. */ @Override public int getCellCount(int row) { return numColumns; } /** * Gets the number of columns in this grid. * * @return the number of columns */ public int getColumnCount() { return numColumns; } /** * Return number of rows. */ @Override public int getRowCount() { return numRows; } /** * Inserts a new row into the table. If you want to add multiple rows at * once, use {@link #resize(int, int)} or {@link #resizeRows(int)} as they * are more efficient. * * @param beforeRow * the index before which the new row will be inserted * @return the index of the newly-created row * @throws IndexOutOfBoundsException */ @Override public int insertRow(int beforeRow) { // Physically insert the row int index = super.insertRow(beforeRow); numRows++; // Add the columns to the new row for (int i = 0; i < numColumns; i++) { insertCell(index, i); } return index; } @Override public void removeRow(int row) { super.removeRow(row); numRows--; } /** * Resizes the grid. * * @param rows * the number of rows * @param columns * the number of columns * @throws IndexOutOfBoundsException */ public void resize(int rows, int columns) { resizeColumns(columns); resizeRows(rows); } /** * Resizes the grid to the specified number of columns. * * @param columns * the number of columns * @throws IndexOutOfBoundsException */ public void resizeColumns(int columns) { if (numColumns == columns) { return; } if (columns < 0) { throw new IndexOutOfBoundsException("Cannot set number of columns to " + columns); } if (numColumns > columns) { // Fewer columns. Remove extraneous cells. for (int i = 0; i < numRows; i++) { for (int j = numColumns - 1; j >= columns; j--) { removeCell(i, j); } } } else { // More columns. add cells where necessary. for (int i = 0; i < numRows; i++) { for (int j = numColumns; j < columns; j++) { insertCell(i, j); } } } numColumns = columns; // Update the size of the colgroup. getColumnFormatter().resizeColumnGroup(columns, false); } /** * Resizes the grid to the specified number of rows. * * @param rows * the number of rows * @throws IndexOutOfBoundsException */ public void resizeRows(int rows) { if (numRows == rows) { return; } if (rows < 0) { throw new IndexOutOfBoundsException("Cannot set number of rows to " + rows); } if (numRows < rows) { addRows(getBodyElement(), rows - numRows, numColumns); numRows = rows; } else { while (numRows > rows) { // Fewer rows. Remove extraneous ones. removeRow(numRows - 1); } } } /** * Creates a new, empty cell. */ @Override protected Element createCell() { Element td = super.createCell(); // Add a non-breaking space to the TD. This ensures that the cell is // displayed. td.setInnerHTML(" "); return DOM.asOld(td); } /** * Checks that a cell is a valid cell in the table. * * @param row * the cell's row * @param column * the cell's column * @throws IndexOutOfBoundsException */ @Override protected void prepareCell(int row, int column) { // Ensure that the indices are not negative. prepareRow(row); if (column < 0) { throw new IndexOutOfBoundsException("Cannot access a column with a negative index: " + column); } if (column >= numColumns) { throw new IndexOutOfBoundsException("Column index: " + column + ", Column size: " + numColumns); } } /** * Checks that the column index is valid. * * @param column * The column index to be checked * @throws IndexOutOfBoundsException * if the column is negative */ @Override protected void prepareColumn(int column) { super.prepareColumn(column); /** * Grid does not lazily create cells, so simply ensure that the * requested column and column are valid */ if (column >= numColumns) { throw new IndexOutOfBoundsException("Column index: " + column + ", Column size: " + numColumns); } } /** * Checks that the row index is valid. * * @param row * The row index to be checked * @throws IndexOutOfBoundsException * if the row is negative */ @Override protected void prepareRow(int row) { // Ensure that the indices are not negative. if (row < 0) { throw new IndexOutOfBoundsException("Cannot access a row with a negative index: " + row); } /** * Grid does not lazily create cells, so simply ensure that the * requested row and column are valid */ if (row >= numRows) { throw new IndexOutOfBoundsException("Row index: " + row + ", Row size: " + numRows); } } }