DataTable.java revision e8819cdf80ca0e0602d22551a50f970aa68e108d
1e8819cdf80ca0e0602d22551a50f970aa68e108dmblighpackage afeclient.client; 2e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 3e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 4e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 5e8819cdf80ca0e0602d22551a50f970aa68e108dmblighimport com.google.gwt.json.client.JSONArray; 6e8819cdf80ca0e0602d22551a50f970aa68e108dmblighimport com.google.gwt.json.client.JSONObject; 7e8819cdf80ca0e0602d22551a50f970aa68e108dmblighimport com.google.gwt.json.client.JSONValue; 8e8819cdf80ca0e0602d22551a50f970aa68e108dmblighimport com.google.gwt.user.client.ui.Composite; 9e8819cdf80ca0e0602d22551a50f970aa68e108dmblighimport com.google.gwt.user.client.ui.FlexTable; 10e8819cdf80ca0e0602d22551a50f970aa68e108dmblighimport com.google.gwt.user.client.ui.Widget; 11e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 12e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh/** 13e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * A table to display data from JSONObjects. Each row displays data from one 14e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * JSONObject. A header row with column titles is automatically generated, and 15e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * support is included for adding other arbitrary header rows. 16e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * <br><br> 17e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Styles: 18e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * <ul> 19e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * <li>.data-table - the entire table 20e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * <li>.data-row-header - the column title row 21e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * <li>.data-row-one/.data-row-two - data row styles. These two are alternated. 22e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * </ul> 23e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 24e8819cdf80ca0e0602d22551a50f970aa68e108dmblighpublic class DataTable extends Composite { 25e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public static final String HEADER_STYLE = "data-row-header"; 26e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public static final String CLICKABLE_STYLE = "data-row-clickable"; 27e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 28e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected FlexTable table; 29e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 30e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected String[][] columns; 31e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected int headerRow = 0; 32e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected boolean clickable = false; 33e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 34e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 35e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @param columns An array specifying the name of each column and the field 36e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * to which it corresponds. The array should have the form 37e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * {{'field_name1', 'Column Title 1'}, 38e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * {'field_name2', 'Column Title 2'}, ...}. 39e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 40e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public DataTable(String[][] columns) { 41e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh this.columns = columns; 42e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table = new FlexTable(); 43e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh initWidget(table); 44e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 45e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.setCellSpacing(0); 46e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.setCellPadding(0); 47e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.setStyleName("data-table"); 48e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 49e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh for (int i = 0; i < columns.length; i++) { 50e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.setText(0, i, columns[i][1]); 51e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 52e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 53e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.getRowFormatter().setStylePrimaryName(0, HEADER_STYLE); 54e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 55e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 56e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected void setRowStyle(int row) { 57e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.getRowFormatter().setStyleName(row, "data-row"); 58e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh if ((row & 1) == 0) { 59e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.getRowFormatter().addStyleName(row, "data-row-alternate"); 60e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 61e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh if (clickable) { 62e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.getRowFormatter().addStyleName(row, CLICKABLE_STYLE); 63e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 64e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 65e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 66e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public void setClickable(boolean clickable) { 67e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh this.clickable = clickable; 68e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh for(int i = headerRow + 1; i < table.getRowCount(); i++) 69e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh setRowStyle(i); 70e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 71e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 72e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 73e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Clear all data rows from the table. Leaves the header rows intact. 74e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 75e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public void clear() { 76e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh while (getRowCount() > 0) { 77e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh removeRow(0); 78e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 79e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 80e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 81e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 82e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * This gets called for every JSONObject that gets added to the table using 83e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * addRow(). This allows subclasses to customize objects before they are 84e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * added to the table, for example to reformat fields or generate new 85e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * fields from the existing data. 86e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @param row The row object about to be added to the table. 87e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 88e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected void preprocessRow(JSONObject row) {} 89e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 90e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected String getTextForValue(JSONValue value) { 91e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh if (value.isNumber() != null) 92e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh return Integer.toString((int) value.isNumber().getValue()); 93e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh else if (value.isString() != null) 94e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh return value.isString().stringValue(); 95e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh else if (value.isNull() != null) 96e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh return ""; 97e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh else 98e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh throw new IllegalArgumentException(value.toString()); 99e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 100e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 101e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh protected String[] getRowText(JSONObject row) { 102e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh String[] rowText = new String[columns.length]; 103e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh for (int i = 0; i < columns.length; i++) { 104e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh String columnKey = columns[i][0]; 105e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh JSONValue columnValue = row.get(columnKey); 106e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh rowText[i] = getTextForValue(columnValue); 107e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 108e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh return rowText; 109e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 110e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 111e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 112e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Add a row from an array of Strings, one String for each column. 113e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @param rowData Data for each column, in left-to-right column order. 114e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 115e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public void addRowFromData(String[] rowData) { 116e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh int row = table.getRowCount(); 117e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh for(int i = 0; i < columns.length; i++) 118e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.setHTML(row, i, rowData[i]); 119e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh setRowStyle(row); 120e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 121e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 122e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 123e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Add a row from a JSONObject. Columns will be populated by pulling fields 124e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * from the objects, as dictated by the columns information passed into the 125e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * DataTable constructor. 126e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 127e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public void addRow(JSONObject row) { 128e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh preprocessRow(row); 129e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh addRowFromData(getRowText(row)); 130e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 131e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 132e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 133e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Add all objects in a JSONArray. 134e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @param rows An array of JSONObjects 135e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @throws IllegalArgumentException if any other type of JSONValue is in the 136e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * array. 137e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 138e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public void addRows(JSONArray rows) { 139e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh for (int i = 0; i < rows.size(); i++) { 140e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh JSONObject row = rows.get(i).isObject(); 141e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh if (row == null) 142e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh throw new IllegalArgumentException("rows must be JSONObjects"); 143e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh addRow(row); 144e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 145e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 146e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 147e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 148e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Remove a data row from the table. 149e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @param row The index of the row, where the first data row is indexed 0. 150e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Header rows are ignored. 151e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 152e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public void removeRow(int row) { 153e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh int realRow = row + getHeaderRowCount(); 154e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.removeRow(realRow); 155e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh for(int i = realRow; i < table.getRowCount(); i++) 156e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh setRowStyle(i); 157e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 158e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 159e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 160e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Returns the number of data rows in the table. The actual number of 161e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * visible table rows is more than this, due to the header rows. 162e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 163e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public int getRowCount() { 164e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh return table.getRowCount() - getHeaderRowCount(); 165e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 166e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 167e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 168e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Adds a header row to the table. This is an extra row that is added above 169e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * the row of column titles and below any other header rows that have been 170e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * added. The row consists of a single cell. 171e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @param widget A widget to add to the cell. 172e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * @return The row index of the new header row. 173e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 174e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public int addHeaderRow(Widget widget) { 175e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh int row = table.insertRow(headerRow); 176e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh headerRow++; 177e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.getFlexCellFormatter().setColSpan(row, 0, columns.length); 178e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh table.setWidget(row, 0, widget); 179e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh return row; 180e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 181e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh 182e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh /** 183e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh * Returns the number of header rows, including the column title row. 184e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh */ 185e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh public int getHeaderRowCount() { 186e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh return headerRow + 1; 187e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh } 188e8819cdf80ca0e0602d22551a50f970aa68e108dmbligh} 189