From 16eefef0dc5ada7279dfdff50df30fea96acd6b7 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Wed, 12 May 2010 15:37:33 +0000 Subject: [PATCH] opening some parts of table implementation + some refactoring svn changeset:13172/svn branch:6.4 --- .../terminal/gwt/client/ui/VScrollTable.java | 93 +++--- src/com/vaadin/ui/Table.java | 275 ++++++++++-------- 2 files changed, 193 insertions(+), 175 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index e470288d1e..bd30bac739 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -131,8 +131,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, private String[] columnOrder; - private ApplicationConnection client; - private String paintableId; + protected ApplicationConnection client; + protected String paintableId; private boolean immediate; @@ -441,7 +441,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, /** * Sends the selection to the server */ - private void sendSelectedRows(){ + private void sendSelectedRows() { // Don't send anything if selection has not changed if (!selectionChanged) { return; @@ -462,25 +462,13 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } // Send the selected row ranges - client - .updateVariable( - paintableId, - "selectedRanges", - ranges - .toArray(new String[selectedRowRanges - .size()]), - false); + client.updateVariable(paintableId, "selectedRanges", ranges + .toArray(new String[selectedRowRanges.size()]), false); } // Send the selected rows - client - .updateVariable( - paintableId, - "selected", - selectedRowKeys - .toArray(new String[selectedRowKeys - .size()]), - immediate); + client.updateVariable(paintableId, "selected", selectedRowKeys + .toArray(new String[selectedRowKeys.size()]), immediate); } @@ -754,7 +742,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, scrollBody.removeFromParent(); lazyUnregistryBag.add(scrollBody); } - scrollBody = new VScrollTableBody(); + scrollBody = createScrollBody(); scrollBody.renderInitialRows(rowData, uidl .getIntAttribute("firstrow"), uidl.getIntAttribute("rows")); @@ -807,6 +795,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, headerChangedDuringUpdate = false; } + protected VScrollTableBody createScrollBody() { + return new VScrollTableBody(); + } + /** * Selects the last rendered row in the table * @@ -1078,16 +1070,16 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, VScrollTableRow r = null; while (it.hasNext()) { r = (VScrollTableRow) it.next(); - if(r == row){ + if (r == row) { r = null; while (offset >= 0 && it.hasNext()) { r = (VScrollTableRow) it.next(); offset--; } return r; - } + } } - + return null; } @@ -2980,9 +2972,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, private char[] aligns; - VScrollTableBody() { + protected VScrollTableBody() { constructDOM(); - setElement(container); } @@ -3022,8 +3013,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, final Iterator it = rowData.getChildIterator(); aligns = tHead.getColumnAlignments(); while (it.hasNext()) { - final VScrollTableRow row = new VScrollTableRow((UIDL) it - .next(), aligns); + final VScrollTableRow row = createRow((UIDL) it.next(), aligns); addRow(row); } if (isAttached()) { @@ -3037,7 +3027,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, final Iterator it = rowData.getChildIterator(); if (firstIndex == lastRendered + 1) { while (it.hasNext()) { - final VScrollTableRow row = createRow((UIDL) it.next()); + final VScrollTableRow row = prepareRow((UIDL) it.next()); addRow(row); lastRendered++; } @@ -3047,7 +3037,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, int i = rows; while (it.hasNext()) { i--; - rowArray[i] = createRow((UIDL) it.next()); + rowArray[i] = prepareRow((UIDL) it.next()); } for (i = 0; i < rows; i++) { addRowBeforeFirstRendered(rowArray[i]); @@ -3058,7 +3048,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, while (lastRendered + 1 > firstRendered) { unlinkRow(false); } - final VScrollTableRow row = createRow((UIDL) it.next()); + final VScrollTableRow row = prepareRow((UIDL) it.next()); firstRendered = firstIndex; lastRendered = firstIndex - 1; addRow(row); @@ -3066,7 +3056,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, setContainerHeight(); fixSpacers(); while (it.hasNext()) { - addRow(createRow((UIDL) it.next())); + addRow(prepareRow((UIDL) it.next())); lastRendered++; } fixSpacers(); @@ -3112,8 +3102,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, * * @param uidl */ - private VScrollTableRow createRow(UIDL uidl) { - final VScrollTableRow row = new VScrollTableRow(uidl, aligns); + private VScrollTableRow prepareRow(UIDL uidl) { + final VScrollTableRow row = createRow(uidl, aligns); final int cells = DOM.getChildCount(row.getElement()); for (int i = 0; i < cells; i++) { final Element cell = DOM.getChild(row.getElement(), i); @@ -3128,6 +3118,10 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, return row; } + protected VScrollTableRow createRow(UIDL uidl, char[] aligns2) { + return new VScrollTableRow(uidl, aligns); + } + private void addRowBeforeFirstRendered(VScrollTableRow row) { VScrollTableRow first = null; if (renderedRows.size() > 0) { @@ -3344,7 +3338,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, // for measuring noCells = true; VScrollTableRow next = (VScrollTableRow) iterator().next(); - next.addCell("", ALIGN_LEFT, "", true); + next.addCell(null, "", ALIGN_LEFT, "", true); firstTD = item.getCells().getItem(0); } com.google.gwt.dom.client.Element wrapper = firstTD @@ -3404,9 +3398,9 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, Container { private static final int DRAGMODE_MULTIROW = 2; - ArrayList childWidgets = new ArrayList(); + protected ArrayList childWidgets = new ArrayList(); private boolean selected = false; - private final int rowKey; + protected final int rowKey; private List pendingComponentPaints; private String[] actionKeys = null; @@ -3474,8 +3468,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, // row header if (showRowHeaders) { - addCell(buildCaptionHtmlSnippet(uidl), aligns[col++], "", - true); + addCell(uidl, buildCaptionHtmlSnippet(uidl), aligns[col++], + "", true); } if (uidl.hasAttribute("al")) { @@ -3495,12 +3489,14 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } if (cell instanceof String) { - addCell(cell.toString(), aligns[col++], style, false); + addCell(uidl, cell.toString(), aligns[col++], style, + false); } else { final Paintable cellContent = client .getPaintable((UIDL) cell); - addCell((Widget) cellContent, aligns[col++], style); + addCell(uidl, (Widget) cellContent, aligns[col++], + style); paintComponent(cellContent, (UIDL) cell); } } @@ -3515,11 +3511,11 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, public VScrollTableRow() { this(0); addStyleName(CLASSNAME + "-row"); - addCell("_", 'b', "", true); + addCell(null, "_", 'b', "", true); } - public void addCell(String text, char align, String style, - boolean textIsHTML) { + public void addCell(UIDL rowUidl, String text, char align, + String style, boolean textIsHTML) { // String only content is optimized by not using Label widget final Element td = DOM.createTD(); final Element container = DOM.createDiv(); @@ -3549,7 +3545,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, getElement().appendChild(td); } - public void addCell(Widget w, char align, String style) { + public void addCell(UIDL rowUidl, Widget w, char align, String style) { final Element td = DOM.createTD(); final Element container = DOM.createDiv(); String className = CLASSNAME + "-cell-content"; @@ -3609,7 +3605,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, client.updateVariable(paintableId, "clickedKey", "" + rowKey, false); - if (getElement() == targetTdOrTr.getParentElement()) { /* A specific column was clicked */ int childIndex = DOM.getChildIndex(getElement(), @@ -3883,8 +3878,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, removeKeyFromSelectedRange(rowKey); } - - /** * Is called when a user clicks an item when holding SHIFT key down. * This will select a new range from the last cell clicked @@ -4696,8 +4689,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } // Down navigation - if (selectMode == SELECT_MODE_NONE - && keycode == getNavigationDownKey()) { + if (selectMode == SELECT_MODE_NONE && keycode == getNavigationDownKey()) { bodyContainer.setScrollPosition(bodyContainer.getScrollPosition() + scrollingVelocity); } else if (keycode == getNavigationDownKey()) { @@ -4711,8 +4703,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, } // Up navigation - if (selectMode == SELECT_MODE_NONE - && keycode == getNavigationUpKey()) { + if (selectMode == SELECT_MODE_NONE && keycode == getNavigationUpKey()) { bodyContainer.setScrollPosition(bodyContainer.getScrollPosition() - scrollingVelocity); } else if (keycode == getNavigationUpKey()) { diff --git a/src/com/vaadin/ui/Table.java b/src/com/vaadin/ui/Table.java index 4fde62d4bd..32cb5f4a96 100644 --- a/src/com/vaadin/ui/Table.java +++ b/src/com/vaadin/ui/Table.java @@ -889,7 +889,7 @@ public class Table extends AbstractSelect implements Action.Container, final int index = getCurrentPageFirstItemIndex(); Object id = null; if (index >= 0 && index < size()) { - id = ((Container.Indexed) items).getIdByIndex(index); + id = getIdByIndex(index); } if (id != null && !id.equals(currentPageFirstItemId)) { currentPageFirstItemId = id; @@ -898,12 +898,16 @@ public class Table extends AbstractSelect implements Action.Container, // If there is no item id at all, use the first one if (currentPageFirstItemId == null) { - currentPageFirstItemId = ((Container.Ordered) items).firstItemId(); + currentPageFirstItemId = firstItemId(); } return currentPageFirstItemId; } + protected Object getIdByIndex(int index) { + return ((Container.Indexed) items).getIdByIndex(index); + } + /** * Setter for property currentPageFirstItemId. * @@ -915,15 +919,14 @@ public class Table extends AbstractSelect implements Action.Container, // Gets the corresponding index int index = -1; if (items instanceof Container.Indexed) { - index = ((Container.Indexed) items) - .indexOfId(currentPageFirstItemId); + index = indexOfId(currentPageFirstItemId); } else { // If the table item container does not have index, we have to // calculates the index by hand - Object id = ((Container.Ordered) items).firstItemId(); + Object id = firstItemId(); while (id != null && !id.equals(currentPageFirstItemId)) { index++; - id = ((Container.Ordered) items).nextItemId(id); + id = nextItemId(id); } if (id == null) { index = -1; @@ -957,6 +960,10 @@ public class Table extends AbstractSelect implements Action.Container, } + protected int indexOfId(Object itemId) { + return ((Container.Indexed) items).indexOfId(itemId); + } + /** * Gets the icon Resource for the specified column. * @@ -1241,8 +1248,7 @@ public class Table extends AbstractSelect implements Action.Container, // Refresh first item id if (items instanceof Container.Indexed) { try { - currentPageFirstItemId = ((Container.Indexed) items) - .getIdByIndex(newIndex); + currentPageFirstItemId = getIdByIndex(newIndex); } catch (final IndexOutOfBoundsException e) { currentPageFirstItemId = null; } @@ -1253,48 +1259,42 @@ public class Table extends AbstractSelect implements Action.Container, // container forwards / backwards // next available item forward or backward - currentPageFirstItemId = ((Container.Ordered) items).firstItemId(); + currentPageFirstItemId = firstItemId(); // Go forwards in the middle of the list (respect borders) while (currentPageFirstItemIndex < newIndex - && !((Container.Ordered) items) - .isLastId(currentPageFirstItemId)) { + && !isLastId(currentPageFirstItemId)) { currentPageFirstItemIndex++; - currentPageFirstItemId = ((Container.Ordered) items) - .nextItemId(currentPageFirstItemId); + currentPageFirstItemId = nextItemId(currentPageFirstItemId); } // If we did hit the border - if (((Container.Ordered) items).isLastId(currentPageFirstItemId)) { + if (isLastId(currentPageFirstItemId)) { currentPageFirstItemIndex = size - 1; } // Go backwards in the middle of the list (respect borders) while (currentPageFirstItemIndex > newIndex - && !((Container.Ordered) items) - .isFirstId(currentPageFirstItemId)) { + && !isFirstId(currentPageFirstItemId)) { currentPageFirstItemIndex--; - currentPageFirstItemId = ((Container.Ordered) items) - .prevItemId(currentPageFirstItemId); + currentPageFirstItemId = prevItemId(currentPageFirstItemId); } // If we did hit the border - if (((Container.Ordered) items).isFirstId(currentPageFirstItemId)) { + if (isFirstId(currentPageFirstItemId)) { currentPageFirstItemIndex = 0; } // Go forwards once more while (currentPageFirstItemIndex < newIndex - && !((Container.Ordered) items) - .isLastId(currentPageFirstItemId)) { + && !isLastId(currentPageFirstItemId)) { currentPageFirstItemIndex++; - currentPageFirstItemId = ((Container.Ordered) items) - .nextItemId(currentPageFirstItemId); + currentPageFirstItemId = nextItemId(currentPageFirstItemId); } // If for some reason we do hit border again, override // the user index request - if (((Container.Ordered) items).isLastId(currentPageFirstItemId)) { + if (isLastId(currentPageFirstItemId)) { newIndex = currentPageFirstItemIndex = size - 1; } } @@ -1398,7 +1398,7 @@ public class Table extends AbstractSelect implements Action.Container, /** * Refreshes rendered rows */ - private void refreshRenderedCells() { + protected void refreshRenderedCells() { if (getParent() == null) { return; } @@ -1459,11 +1459,11 @@ public class Table extends AbstractSelect implements Action.Container, // Gets the first item id if (items instanceof Container.Indexed) { - id = ((Container.Indexed) items).getIdByIndex(firstIndex); + id = getIdByIndex(firstIndex); } else { - id = ((Container.Ordered) items).firstItemId(); + id = firstItemId(); for (int i = 0; i < firstIndex; i++) { - id = ((Container.Ordered) items).nextItemId(id); + id = nextItemId(id); } } @@ -1571,15 +1571,14 @@ public class Table extends AbstractSelect implements Action.Container, // Gets the next item id if (items instanceof Container.Indexed) { - Container.Indexed indexed = (Container.Indexed) items; int index = firstIndex + i + 1; - if (index < indexed.size()) { - id = indexed.getIdByIndex(index); + if (index < totalRows) { + id = getIdByIndex(index); } else { id = null; } } else { - id = ((Container.Ordered) items).nextItemId(id); + id = nextItemId(id); } filledRows++; @@ -2332,8 +2331,8 @@ public class Table extends AbstractSelect implements Action.Container, start = 0; } - for (int i = start; i < end; i++) { - final Object itemId = cells[CELL_ITEMID][i]; + for (int indexInRowbuffer = start; indexInRowbuffer < end; indexInRowbuffer++) { + final Object itemId = cells[CELL_ITEMID][indexInRowbuffer]; if (!isNullSelectionAllowed() && getNullSelectionItemId() != null && itemId == getNullSelectionItemId()) { @@ -2341,93 +2340,8 @@ public class Table extends AbstractSelect implements Action.Container, continue; } - target.startTag("tr"); - - // tr attributes - if (rowheads) { - if (cells[CELL_ICON][i] != null) { - target.addAttribute("icon", (Resource) cells[CELL_ICON][i]); - } - if (cells[CELL_HEADER][i] != null) { - target.addAttribute("caption", - (String) cells[CELL_HEADER][i]); - } - } - target.addAttribute("key", Integer.parseInt(cells[CELL_KEY][i] - .toString())); - - if (isSelected(itemId)) { - target.addAttribute("selected", true); - } - - // Actions - if (actionHandlers != null) { - final ArrayList keys = new ArrayList(); - for (final Iterator ahi = actionHandlers.iterator(); ahi - .hasNext();) { - final Action[] aa = (ahi.next()).getActions(itemId, this); - if (aa != null) { - for (int ai = 0; ai < aa.length; ai++) { - final String key = actionMapper.key(aa[ai]); - actionSet.add(aa[ai]); - keys.add(key); - } - } - } - target.addAttribute("al", keys.toArray()); - } - - /* - * For each row, if a cellStyleGenerator is specified, get the - * specific style for the cell, using null as propertyId. If there - * is any, add it to the target. - */ - if (cellStyleGenerator != null) { - String rowStyle = cellStyleGenerator.getStyle(itemId, null); - if (rowStyle != null && !rowStyle.equals("")) { - target.addAttribute("rowstyle", rowStyle); - } - } - - // cells - int currentColumn = 0; - for (final Iterator it = visibleColumns.iterator(); it - .hasNext(); currentColumn++) { - final Object columnId = it.next(); - if (columnId == null || isColumnCollapsed(columnId)) { - continue; - } - /* - * For each cell, if a cellStyleGenerator is specified, get the - * specific style for the cell. If there is any, add it to the - * target. - */ - if (cellStyleGenerator != null) { - String cellStyle = cellStyleGenerator.getStyle(itemId, - columnId); - if (cellStyle != null && !cellStyle.equals("")) { - target.addAttribute("style-" - + columnIdMap.key(columnId), cellStyle); - } - } - if ((iscomponent[currentColumn] || iseditable) - && Component.class.isInstance(cells[CELL_FIRSTCOL - + currentColumn][i])) { - final Component c = (Component) cells[CELL_FIRSTCOL - + currentColumn][i]; - if (c == null) { - target.addText(""); - } else { - c.paint(target); - } - } else { - target - .addText((String) cells[CELL_FIRSTCOL - + currentColumn][i]); - } - } - - target.endTag("tr"); + paintRow(target, rowheads, cells, iseditable, actionSet, + iscomponent, indexInRowbuffer, itemId); } target.endTag("rows"); @@ -2552,6 +2466,120 @@ public class Table extends AbstractSelect implements Action.Container, } } + private void paintRow(PaintTarget target, final boolean rowheads, + final Object[][] cells, final boolean iseditable, + final Set actionSet, final boolean[] iscomponent, + int indexInRowbuffer, final Object itemId) throws PaintException { + target.startTag("tr"); + + renderRowAttributes(target, rowheads, cells, actionSet, + indexInRowbuffer, itemId); + + // cells + int currentColumn = 0; + for (final Iterator it = visibleColumns.iterator(); it + .hasNext(); currentColumn++) { + final Object columnId = it.next(); + if (columnId == null || isColumnCollapsed(columnId)) { + continue; + } + /* + * For each cell, if a cellStyleGenerator is specified, get the + * specific style for the cell. If there is any, add it to the + * target. + */ + if (cellStyleGenerator != null) { + String cellStyle = cellStyleGenerator + .getStyle(itemId, columnId); + if (cellStyle != null && !cellStyle.equals("")) { + target.addAttribute("style-" + columnIdMap.key(columnId), + cellStyle); + } + } + if ((iscomponent[currentColumn] || iseditable) + && Component.class.isInstance(cells[CELL_FIRSTCOL + + currentColumn][indexInRowbuffer])) { + final Component c = (Component) cells[CELL_FIRSTCOL + + currentColumn][indexInRowbuffer]; + if (c == null) { + target.addText(""); + } else { + c.paint(target); + } + } else { + target + .addText((String) cells[CELL_FIRSTCOL + currentColumn][indexInRowbuffer]); + } + } + + target.endTag("tr"); + } + + private void renderRowAttributes(PaintTarget target, + final boolean rowheads, final Object[][] cells, + final Set actionSet, int indexInRowbuffer, + final Object itemId) throws PaintException { + // tr attributes + if (rowheads) { + if (cells[CELL_ICON][indexInRowbuffer] != null) { + target.addAttribute("icon", + (Resource) cells[CELL_ICON][indexInRowbuffer]); + } + if (cells[CELL_HEADER][indexInRowbuffer] != null) { + target.addAttribute("caption", + (String) cells[CELL_HEADER][indexInRowbuffer]); + } + } + target.addAttribute("key", Integer + .parseInt(cells[CELL_KEY][indexInRowbuffer].toString())); + + if (isSelected(itemId)) { + target.addAttribute("selected", true); + } + + // Actions + if (actionHandlers != null) { + final ArrayList keys = new ArrayList(); + for (final Iterator ahi = actionHandlers.iterator(); ahi + .hasNext();) { + final Action[] aa = (ahi.next()).getActions(itemId, this); + if (aa != null) { + for (int ai = 0; ai < aa.length; ai++) { + final String key = actionMapper.key(aa[ai]); + actionSet.add(aa[ai]); + keys.add(key); + } + } + } + target.addAttribute("al", keys.toArray()); + } + + /* + * For each row, if a cellStyleGenerator is specified, get the specific + * style for the cell, using null as propertyId. If there is any, add it + * to the target. + */ + if (cellStyleGenerator != null) { + String rowStyle = cellStyleGenerator.getStyle(itemId, null); + if (rowStyle != null && !rowStyle.equals("")) { + target.addAttribute("rowstyle", rowStyle); + } + } + renderRowAttributes(target, itemId); + } + + /** + * A method where extended Table implementations may add their custom + * attributes for rows. + * + * @param target + * @param itemId + */ + protected void renderRowAttributes(PaintTarget target, Object itemId) + throws PaintException { + + } + /** * Gets the cached visible table contents. * @@ -2690,7 +2718,7 @@ public class Table extends AbstractSelect implements Action.Container, requestRepaint(); } - private void resetPageBuffer() { + protected void resetPageBuffer() { firstToBeRenderedInClient = -1; lastToBeRenderedInClient = -1; reqFirstRowToPaint = -1; @@ -2753,8 +2781,7 @@ public class Table extends AbstractSelect implements Action.Container, */ @Override public boolean removeItem(Object itemId) { - final Object nextItemId = ((Container.Ordered) items) - .nextItemId(itemId); + final Object nextItemId = nextItemId(itemId); final boolean ret = super.removeItem(itemId); if (ret && (itemId != null) && (itemId.equals(currentPageFirstItemId))) { currentPageFirstItemId = nextItemId; -- 2.39.5