/** * @return a String representation of this component, for debugging purposes. */ @Override public String toString() { TableDataModel model = getDataModel(); return toString(model.getClass().getSimpleName() + ", " + model.getRowCount() + " rows", -1, -1); }
@Override public String getText() { MyTableDataModel model = (MyTableDataModel) table.getDataModel(); String[][] data = model.getData(); StringBuffer buf = new StringBuffer("Saved data:\n"); for (String[] row : data) { for (String col : row) { buf.append(col); buf.append('\t'); } buf.append('\n'); } return buf.toString(); } };
@Override public String getText() { MyTableDataModel model = (MyTableDataModel) table.getDataModel(); String[][] data = model.getData(); StringBuffer buf = new StringBuffer("Saved data:\n"); for (String[] row : data) { for (String col : row) { buf.append(col); buf.append('\t'); } buf.append('\n'); } return buf.toString(); } };
@Override public void execute(final ActionEvent event) { StringBuffer buf = new StringBuffer("Selection:\n"); for (int row : table.getSelectedRows()) { buf.append(table.getDataModel().getValueAt(row, 0)) .append(' ') .append(table.getDataModel().getValueAt(row, 1)) .append('\n'); } selectionText.setText(buf.toString()); } });
@Override public void execute(final ActionEvent event) { List<Integer> selectedRows = table.getSelectedRows(); if (!selectedRows.isEmpty()) { MyTableDataModel model = (MyTableDataModel) table.getDataModel(); model.setEditRow(selectedRows.get(0)); } } });
@Override public String getData() { UIContext uic = UIContextHolder.getCurrent(); int row = getRowIndex((SubUIContext) uic); return table.getDataModel().getRowHeader(row); } });
/** * Retrieves the renderer class for a given row. * * @return the renderer class for a given row (if it's an expanded row), otherwise null. */ private Class<? extends WComponent> getRowRendererClass() { UIContext uic = UIContextHolder.getCurrent(); if (table.getDataModel() instanceof TreeTableDataModel && uic instanceof SubUIContext) { int row = getRowIndex((SubUIContext) uic); TreeTableDataModel dataModel = (TreeTableDataModel) table.getDataModel(); TableTreeNode node = dataModel.getNodeAtLine(row); return node.getRendererClass(); } return null; }
/** * Provides data to a component rendering a column. * * @param beanProviderBound the component rendering the column. * @return a bean value for component that is rendering the specified row/column */ @Override public Object getBean(final BeanProviderBound beanProviderBound) { UIContext uic = UIContextHolder.getCurrent(); // Make sure we have the correct uic while (uic instanceof SubUIContext && !((SubUIContext) uic).isInContext( (WComponent) beanProviderBound)) { uic = ((SubUIContext) uic).getParentContext(); } if (!(uic instanceof SubUIContext)) { LOG.error("Unable to handle UIContext type: " + uic.getClass().getName()); return null; } int row = rowRenderer.getRowIndex((SubUIContext) uic); if (columnIndex < 0) { // This is not a column renderer, it must be an additional row renderer TreeTableDataModel dataModel = (TreeTableDataModel) rowRenderer.table.getDataModel(); return dataModel.getNodeAtLine(row).getData(); } else { return rowRenderer.table.getDataModel().getValueAt(row, columnIndex); } }
/** * @param currentPage The currentPage to set. */ public void setCurrentPage(final int currentPage) { if (currentPage < 0) { throw new IllegalArgumentException("Page number must be greater than or equal to zero."); } TableModel model = getOrCreateComponentModel(); model.currentPage = Math.min(model.getMaxPage(), currentPage); // Notify the table model that the page has changed TableDataModel dataModel = getDataModel(); if (dataModel instanceof ScrollableTableDataModel) { int startIndex = getCurrentPage() * getRowsPerPage(); int endIndex = Math.min(dataModel.getRowCount() - 1, startIndex + getRowsPerPage() - 1); ((ScrollableTableDataModel) dataModel).setCurrentRows(startIndex, endIndex); } }
/** * Indicates whether the table supports sorting. * * @return true if the table and model both support sorting, false otherwise. */ public boolean isSortable() { // First check global override which turns sorting off if (getSortMode() == SortMode.NONE) { return false; } // Otherwise, the table is sortable if at least one column is sortable. TableDataModel dataModel = getDataModel(); final int columnCount = getColumnCount(); for (int i = 0; i < columnCount; i++) { if (dataModel.isSortable(i)) { return true; } } return false; }
/** * Determine the row ids for the provided index range. * * @param startIndex the startIndex * @param endIndex the endIndex * @return the list of rowIds for the provided index range */ private List<Integer> getRowIds(final int startIndex, final int endIndex) { // If the table is sorted, we may require a mapping for table row index <--> data model index. int[] rowIndexMapping = getComponentModel().rowIndexMapping; // Check if sort mapping needs updating if (isSorted() && rowIndexMapping != null && rowIndexMapping.length != getDataModel(). getRowCount()) { rowIndexMapping = getDataModel().sort(getSortColumnIndex(), isSortAscending()); getOrCreateComponentModel().rowIndexMapping = rowIndexMapping; } if (rowIndexMapping == null) { // No mapping, return from startIndex to endIndex return new RowIdList(startIndex, endIndex); } else { List<Integer> rowIds = new ArrayList<>(endIndex - startIndex + 1); for (int i = startIndex; i <= endIndex; i++) { rowIds.add(rowIndexMapping[i]); } return rowIds; } }
/** * Sort the table data by the specified column. * * @param sortCol the column to sort * @param sortAsc true if sort ascending, otherwise sort descending */ public void sort(final int sortCol, final boolean sortAsc) { int[] rowIndexMappings = getDataModel().sort(sortCol, sortAsc); getOrCreateComponentModel().rowIndexMapping = rowIndexMappings; setSort(sortCol, sortAsc); if (rowIndexMappings == null) { // There's no way to correlate the previously selected row indices // with the new order of rows, so we need to clear out the selection. setSelectedRows(null); setExpandedRows(null); } }
/** * Updates the bean using the table data model's {@link TableDataModel#setValueAt(Object, int, int)} method. */ @Override public void updateBeanValue() { TableDataModel model = getDataModel(); if (model instanceof ScrollableTableDataModel) { LOG.warn("UpdateBeanValue only updating the current page for ScrollableTableDataModel"); updateBeanValueCurrentPageOnly(); } else if (model.getRowCount() > 0) { // Temporarily widen the pagination on the repeater to hold all rows // Calling setBean with a non-null value overrides the DataTableBeanProvider repeater.setBean(new RowIdList(0, model.getRowCount() - 1)); updateBeanValueCurrentPageOnly(); repeater.setBean(null); } }
TableDataModel model = table.getDataModel(); WRepeater repeater = table.getRepeater(); List<?> beanList = repeater.getBeanList();
/** * Retrieves the ending row index for the current page. Will always return the row count minus 1 for tables which * are not paginated. * * @return the starting row index for the current page. */ private int getCurrentPageEndRow() { TableDataModel model = getDataModel(); int rowsPerPage = getRowsPerPage(); int endRow = model.getRowCount() - 1; if (getPaginationMode() != PaginationMode.NONE) { if (model instanceof TreeTableDataModel) { // For tree tables, pagination only occurs on first-level nodes (ie. those // underneath the root node), however they might not be consecutively // numbered. Therefore, the start and end row indices need to be adjusted. TreeTableDataModel treeModel = (TreeTableDataModel) model; TreeNode root = treeModel.getNodeAtLine(0).getRoot(); int endNode = Math.min(root.getChildCount() - 1, (getCurrentPage() + 1) * rowsPerPage - 1); endRow = ((TableTreeNode) root.getChildAt(endNode)).getRowIndex() - 1 // -1 as the root is not included in the table + ((TableTreeNode) root.getChildAt(endNode)).getNodeCount(); } else { endRow = Math.min(model.getRowCount() - 1, (getCurrentPage() + 1) * rowsPerPage - 1); } } return endRow; }
@Test public void testDataModelAccessors() { WDataTable table = new WDataTable(); TableDataModel model1 = new SimpleTableDataModel(new String[0][0]); TableDataModel model2 = new SimpleTableDataModel(new String[0][0]); table.setDataModel(model1); Assert.assertSame("Incorrect default data model", model1, table.getDataModel()); table.setLocked(true); setActiveContext(createUIContext()); table.setDataModel(model2); Assert.assertSame("Incorrect data model for modified session", model2, table.getDataModel()); setActiveContext(createUIContext()); Assert.assertSame("Incorrect data model for other sessions", model1, table.getDataModel()); }
/** * Retrieves the starting row index for the current page. Will always return zero for tables which are not * paginated. * * @return the starting row index for the current page. */ private int getCurrentPageStartRow() { int startRow = 0; if (getPaginationMode() != PaginationMode.NONE) { int rowsPerPage = getRowsPerPage(); TableDataModel model = getDataModel(); if (model instanceof TreeTableDataModel) { // For tree tables, pagination only occurs on first-level nodes (ie. those // underneath the root node), however they might not be consecutively // numbered. Therefore, the start and end row indices need to be adjusted. TreeTableDataModel treeModel = (TreeTableDataModel) model; TreeNode root = treeModel.getNodeAtLine(0).getRoot(); int startNode = getCurrentPage() * rowsPerPage; startRow = ((TableTreeNode) root.getChildAt(startNode)).getRowIndex() - 1; // -1 as the root is not included in the table } else { startRow = getCurrentPage() * rowsPerPage; } } return startRow; }
TableDataModel model = getDataModel();
/** * Paints the column headings for the given table. * * @param table the table to paint the headings for. * @param renderContext the RenderContext to paint to. */ private void paintColumnHeadings(final WDataTable table, final WebXmlRenderContext renderContext) { XmlStringBuilder xml = renderContext.getWriter(); int[] columnOrder = table.getColumnOrder(); TableDataModel model = table.getDataModel(); final int columnCount = table.getColumnCount(); xml.appendTagOpen("ui:thead"); xml.appendOptionalAttribute("hidden", !table.isShowColumnHeaders(), "true"); xml.appendClose(); if (table.isShowRowHeaders()) { paintColumnHeading(table.getRowHeaderColumn(), false, renderContext); } for (int i = 0; i < columnCount; i++) { int colIndex = columnOrder == null ? i : columnOrder[i]; WTableColumn col = table.getColumn(colIndex); if (col.isVisible()) { boolean sortable = model.isSortable(colIndex); paintColumnHeading(col, sortable, renderContext); } } xml.appendEndTag("ui:thead"); }
/** * Paints the rows of the table. * * @param table the table to paint the rows for. * @param renderContext the RenderContext to paint to. */ private void paintRows(final WDataTable table, final WebXmlRenderContext renderContext) { XmlStringBuilder xml = renderContext.getWriter(); TableDataModel model = table.getDataModel(); xml.appendTagOpen("ui:tbody"); xml.appendAttribute("id", table.getRepeater().getId()); xml.appendClose(); if (model.getRowCount() == 0) { xml.appendTag("ui:nodata"); xml.appendEscaped(table.getNoDataMessage()); xml.appendEndTag("ui:nodata"); } else { // If has at least one visible col, paint the rows. final int columnCount = table.getColumnCount(); for (int i = 0; i < columnCount; i++) { if (table.getColumn(i).isVisible()) { doPaintRows(table, renderContext); break; } } } xml.appendEndTag("ui:tbody"); }