/** * Provide an array of column indexes in the order they should be rendered. At least one column must be specifed. * <p> * This can also be used to "hide" columns by not including them in the array. * </p> * * @param columnOrder the column order to set, or null to use default ordering. */ public void setColumnOrder(final int[] columnOrder) { if (columnOrder == null) { getOrCreateComponentModel().columnOrder = null; } else { int count = getColumnCount(); if (columnOrder.length == 0) { throw new IllegalArgumentException("Cannot have an empty column order indices."); } if (columnOrder.length > count) { throw new IllegalArgumentException( "Number of column order indices cannot be greater than the number of table columns"); } for (int idx : columnOrder) { if (idx < 0 || idx > count - 1) { throw new IllegalArgumentException( "Illegal index in column order indices [" + idx + "]"); } } getOrCreateComponentModel().columnOrder = Arrays.copyOf(columnOrder, columnOrder.length); } }
/** * @return the column AJAX targets */ protected List<AjaxTarget> getColumnAjaxTargets() { List<AjaxTarget> targets = new ArrayList<>(); WTable table = getTable(); for (int i = 0; i < table.getColumnCount(); i++) { WComponent renderer = table.getColumn(i).getRenderer(); if (renderer instanceof AjaxTarget) { targets.add((AjaxTarget) renderer); } } return targets; }
/** * 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. TableModel dataModel = getTableModel(); final int columnCount = getColumnCount(); for (int i = 0; i < columnCount; i++) { if (dataModel.isSortable(i)) { return true; } } return false; }
@Test public void testColumnAccessors() { WTable table = new WTable(); Assert.assertEquals("Table should not have any columns by default", 0, table. getColumnCount()); WTableColumn col1 = new WTableColumn("dummy", WText.class); WTableColumn col2 = new WTableColumn("dummy", WText.class); table.addColumn(col1); Assert.assertEquals("Incorrect column count", 1, table.getColumnCount()); table.addColumn(col2); Assert.assertEquals("Incorrect column count", 2, table.getColumnCount()); Assert.assertSame("Incorrect first column", col1, table.getColumn(0)); Assert.assertSame("Incorrect second column", col2, table.getColumn(1)); }
/** * Updates the bean using the table data model's {@link TableModel#setValueAt(Object, List, int)} method. This * method only updates the data for the currently set row ids. */ private void updateBeanValueForRenderedRows() { WTableRowRenderer rowRenderer = (WTableRowRenderer) repeater.getRepeatedComponent(); TableModel model = getTableModel(); int index = 0; List<RowIdWrapper> wrappers = repeater.getBeanList(); int columnCount = getColumnCount(); for (RowIdWrapper wrapper : wrappers) { UIContext rowContext = repeater.getRowContext(wrapper, index++); List<Integer> rowIndex = wrapper.getRowIndex(); Class<? extends WComponent> expandRenderer = model.getRendererClass(rowIndex); if (expandRenderer == null) { // Process Columns for (int col = 0; col < columnCount; col++) { // Check if this cell is editable if (model.isCellEditable(rowIndex, col)) { updateBeanValueForColumnInRow(rowRenderer, rowContext, rowIndex, col, model); } } } else if (model.isCellEditable(rowIndex, -1)) { // Check if this expanded row is editable updateBeanValueForRowRenderer(rowRenderer, rowContext, expandRenderer); } } }
/** * 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 WTable table, final WebXmlRenderContext renderContext) { XmlStringBuilder xml = renderContext.getWriter(); int[] columnOrder = table.getColumnOrder(); TableModel model = table.getTableModel(); final int columnCount = columnOrder == null ? table.getColumnCount() : columnOrder.length; xml.appendTagOpen("ui:thead"); xml.appendOptionalAttribute("hidden", !table.isShowColumnHeaders(), "true"); xml.appendClose(); 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 WTable table, final WebXmlRenderContext renderContext) { XmlStringBuilder xml = renderContext.getWriter(); TableModel model = table.getTableModel(); xml.appendTagOpen("ui:tbody"); xml.appendAttribute("id", table.getId() + ".body"); 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"); }
for (int i = 0; i < component.getColumnCount(); i++) { assertXpathEvaluatesTo(colHeaders[i], "//ui:table/ui:thead/ui:th[" + (i + 1) + "]/ui:decoratedlabel/ui:labelbody", component); List<Integer> row = new ArrayList<>(); row.add(i); for (int j = 0; j < component.getColumnCount(); j++) { assertXpathEvaluatesTo((String) tableModel.getValueAt(row, j), "//ui:table/ui:tbody/ui:tr[" + (i + 1)
final int numCols = columnOrder == null ? table.getColumnCount() : columnOrder.length;