From 34892c9deb793ca6cfd581c09c300b980297b6a2 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Tue, 26 Jun 2007 11:48:18 +0000 Subject: [PATCH] somewhat scrolling scrolltable svn changeset:1788/svn branch:trunk --- .../gwt/client/DefaultWidgetFactory.java | 9 +- .../IScrollTable.java} | 297 +++++++----------- .../ui/scrolltable/IScrollTableBody.java | 235 ++++++++++++++ .../ui/scrolltable/IScrollTableRow.java | 62 ++++ .../component-themes/common/css/common.css | 51 +++ 5 files changed, 470 insertions(+), 184 deletions(-) rename src/com/itmill/toolkit/terminal/gwt/client/ui/{ITableScrollingByComposition.java => scrolltable/IScrollTable.java} (57%) create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java create mode 100644 src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableRow.java diff --git a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java index 8fb04329bb..0a22858281 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java @@ -16,7 +16,6 @@ import com.itmill.toolkit.terminal.gwt.client.ui.IPanel; import com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField; import com.itmill.toolkit.terminal.gwt.client.ui.ISelect; import com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging; -import com.itmill.toolkit.terminal.gwt.client.ui.ITableScrollingByComposition; import com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet; import com.itmill.toolkit.terminal.gwt.client.ui.ITextArea; import com.itmill.toolkit.terminal.gwt.client.ui.ITextField; @@ -25,6 +24,7 @@ import com.itmill.toolkit.terminal.gwt.client.ui.ITwinColSelect; import com.itmill.toolkit.terminal.gwt.client.ui.IUnknownComponent; import com.itmill.toolkit.terminal.gwt.client.ui.IVerticalLayout; import com.itmill.toolkit.terminal.gwt.client.ui.IWindow; +import com.itmill.toolkit.terminal.gwt.client.ui.scrolltable.IScrollTable; public class DefaultWidgetFactory implements WidgetFactory { @@ -75,8 +75,13 @@ public class DefaultWidgetFactory implements WidgetFactory { return new IPasswordField(); return new ITextField(); } - if ("table".equals(tag)) + if ("table".equals(tag)) { + if(uidl.hasAttribute("style")) { + if("scrolling".equals(uidl.getStringAttribute("style"))) + return new IScrollTable(); + } return new ITablePaging(); + } if("datefield".equals(tag)) return new IDateField(); diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITableScrollingByComposition.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTable.java similarity index 57% rename from src/com/itmill/toolkit/terminal/gwt/client/ui/ITableScrollingByComposition.java rename to src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTable.java index ecddab1467..34a5ade2a3 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITableScrollingByComposition.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTable.java @@ -1,4 +1,4 @@ -package com.itmill.toolkit.terminal.gwt.client.ui; +package com.itmill.toolkit.terminal.gwt.client.ui.scrolltable; import java.util.HashMap; import java.util.Iterator; @@ -11,7 +11,6 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlexTable; -import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.ScrollListener; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.VerticalPanel; @@ -20,8 +19,9 @@ import com.google.gwt.user.client.ui.FlexTable.FlexCellFormatter; import com.itmill.toolkit.terminal.gwt.client.Client; import com.itmill.toolkit.terminal.gwt.client.Paintable; import com.itmill.toolkit.terminal.gwt.client.UIDL; +import com.itmill.toolkit.terminal.gwt.client.ui.ITable; -public class ITableScrollingByComposition extends Composite implements Paintable, ScrollListener { +public class IScrollTable extends Composite implements Paintable, ITable, ScrollListener { /** * multiple of pagelenght which component will @@ -34,8 +34,6 @@ public class ITableScrollingByComposition extends Composite implements Paintable */ private static final double CACHE_REACT_RATE = 1; - private int firstRendered = -1; - private int lastRendered = -1; private int firstRowInViewPort = 0; private int pageLength = 15; @@ -47,36 +45,29 @@ public class ITableScrollingByComposition extends Composite implements Paintable private String id; private boolean immediate; - private FlexTable tHead = new FlexTable(); - private FlexTable tBody = new FlexTable(); + private boolean initializedAndAttached = false; + private FlexTable tHead = new FlexTable(); + private ScrollPanel bodyContainer = new ScrollPanel(); - private VerticalPanel bodyContent = new VerticalPanel(); private ScrollPanel headerContainer = new ScrollPanel(); - private HTML preSpacer = new HTML(); - private HTML postSpacer = new HTML(); - private boolean colWidthsInitialized = false; private int totalRows; private HashMap columnWidths = new HashMap(); - private int rowHeight = 0; private RowRequestHandler rowRequestHandler; + private IScrollTableBody tBody; + private int width = -1; + private int height = -1; + private int firstvisible; - public ITableScrollingByComposition() { + public IScrollTable() { + headerContainer.setStyleName("iscrolltable-header"); headerContainer.add(tHead); DOM.setStyleAttribute(headerContainer.getElement(), "overflow", "hidden"); - tBody.setStyleName("itable-tbody"); - - bodyContent.add(preSpacer); - bodyContent.add(tBody); - bodyContent.add(postSpacer); - //TODO remove debug color - DOM.setStyleAttribute(postSpacer.getElement(), "background", "gray"); - bodyContainer.add(bodyContent); bodyContainer.addScrollListener(this); VerticalPanel panel = new VerticalPanel(); @@ -97,8 +88,13 @@ public class ITableScrollingByComposition extends Composite implements Paintable this.immediate = uidl.getBooleanAttribute("immediate"); this.totalRows = uidl.getIntAttribute("totalrows"); this.pageLength = uidl.getIntAttribute("pagelength"); + this.firstvisible = uidl.getIntVariable("firstvisible"); if(uidl.hasAttribute("rowheaders")) rowHeaders = true; + if(uidl.hasAttribute("width")) + width = uidl.getIntAttribute("width"); + if(uidl.hasAttribute("height")) + width = uidl.getIntAttribute("height"); UIDL columnInfo = null; UIDL rowData = null; @@ -115,26 +111,27 @@ public class ITableScrollingByComposition extends Composite implements Paintable } updateHeader(columnInfo); - updateBody(rowData, uidl.getIntAttribute("firstrow"),uidl.getIntAttribute("rows")); - - if(!colWidthsInitialized) { - DeferredCommand.add(new Command() { - public void execute() { - initSize(); - updateSpacers(); - bodyContainer.setScrollPosition(getRowHeight()*(firstRowInViewPort -1)); - colWidthsInitialized = true; - if(totalRows - 1 > lastRendered) { - // fetch cache rows - rowRequestHandler.setReqFirstRow(lastRendered+1); - rowRequestHandler.setReqRows((int) (pageLength*CACHE_RATE)); - rowRequestHandler.deferRowFetch(); - } - } - }); + if(initializedAndAttached) { + updateBody(rowData, uidl.getIntAttribute("firstrow"),uidl.getIntAttribute("rows")); + } else { + getTBody().renderInitialRows(rowData, + uidl.getIntAttribute("firstrow"), + uidl.getIntAttribute("rows"), + totalRows); + bodyContainer.add(tBody); + initializedAndAttached = true; } } + private IScrollTableBody getTBody() { + if(tBody == null || totalRows != tBody.getTotalRows()) { + if(tBody != null) + tBody.removeFromParent(); + tBody = new IScrollTableBody(client); + } + return tBody; + } + private void updateActionMap(UIDL c) { // TODO Auto-generated method stub @@ -154,12 +151,6 @@ public class ITableScrollingByComposition extends Composite implements Paintable } /** - * Updates row data from uidl. UpdateFromUIDL delegates updating - * tBody to this method. - * - * Updates may be to different part of tBody, depending on update type. - * It can be initial row data, scroll up, scroll down... - * * @param uidl which contains row data * @param firstRow first row in data set * @param reqRows amount of rows in data set @@ -167,101 +158,22 @@ public class ITableScrollingByComposition extends Composite implements Paintable private void updateBody(UIDL uidl, int firstRow, int reqRows) { if(uidl == null || reqRows < 1) return; + + tBody.renderRows(uidl, firstRow, reqRows); + + int optimalFirstRow = (int) (firstRowInViewPort - pageLength*CACHE_RATE); + while(tBody.getFirstRendered() < optimalFirstRow) { +// client.console.log("removing row from start"); + tBody.unlinkRow(true); + } + int optimalLastRow = (int) (firstRowInViewPort + pageLength + pageLength*CACHE_RATE); + while(tBody.getLastRendered() > optimalLastRow) { +// client.console.log("removing row from the end"); + tBody.unlinkRow(false); + } - Iterator it = uidl.getChildIterator(); - - if(firstRendered == -1 || firstRow == lastRendered + 1) { - //initial data to body or appending rows to table - while(it.hasNext()) { - appendRow( (UIDL) it.next() ); - if(colWidthsInitialized) - updateSpacers(); - } -// lastRendered = firstRow + reqRows - 1; - if(firstRendered == -1) { - firstRendered = firstRow; - } - } else if(firstRendered == firstRow + reqRows) { - // add received rows before old ones - int rowsAdded = 0; - while(it.hasNext()){ - tBody.insertRow(rowsAdded); - updateSpacers(); - updateRow( (UIDL) it.next(), rowsAdded); - } - firstRendered = firstRow; - } else { - // complitely new set received, truncate body and recurse - tBody.clear(); - firstRendered = -1; - lastRendered = -1; - updateBody(uidl, firstRow, reqRows); - } - trimBody(); } - /** - * Returns calculated height of row. - * @return height in pixels - */ - private int getRowHeight() { - if(rowHeight == 0) - rowHeight = tBody.getOffsetHeight()/getRenderedRowCount(); - return rowHeight; - } - - /** - * This method removes rows from body which are "out of - * cache area" to keep amount of rendered rows sane. - */ - private void trimBody() { - int toBeRemovedFromTheBeginning = (int) (firstRowInViewPort - CACHE_RATE*pageLength) - firstRendered; - int toBeRemovedFromTheEnd = lastRendered - (int) (firstRowInViewPort + CACHE_RATE*pageLength + pageLength); - if(toBeRemovedFromTheBeginning > 0) { - // remove extra rows from the beginning of the table - while(toBeRemovedFromTheBeginning > 0) { - tBody.removeRow(0); - firstRendered++; - toBeRemovedFromTheBeginning--; - updateSpacers(); - } - } - if(toBeRemovedFromTheEnd > 0) { - // remove extra rows from the end of the table - while(toBeRemovedFromTheEnd > 0) { - tBody.removeRow(tBody.getRowCount() - 1); - toBeRemovedFromTheEnd--; - lastRendered--; - updateSpacers(); - } - } -// bodyContainer.setScrollPosition(getRowHeight()*firstRowInViewPort); - } - - private void appendRow(UIDL uidl) { - lastRendered++; - updateRow(uidl, lastRendered); - } - - private void updateRow(UIDL uidl, int rowIndex) { - int colIndex = 0; - if(rowHeaders) { - setCellContent(rowIndex, colIndex, uidl.getStringAttribute("caption")); - colIndex++; - } - - for(Iterator it = uidl.getChildIterator(); it.hasNext();) { - Object cell = it.next(); - if (cell instanceof String) { - setCellContent(rowIndex, colIndex, (String) cell); - } else { - setCellContent(rowIndex, colIndex, (UIDL) cell); - } - colIndex++; - } - Element row = tBody.getRowFormatter().getElement(rowIndex); - DOM.setIntAttribute(row, "key", uidl.getIntAttribute("key")); - } private int getColIndexByKey(String colKey) { return Integer.parseInt(colKey) - 1 + (rowHeaders ? 1 : 0); @@ -275,46 +187,10 @@ public class ITableScrollingByComposition extends Composite implements Paintable tHead.setText(0, colIndex, text); } - public void setCellContent(int rowId, int colId, UIDL cell) { - if(cell == null) - return; - Widget cellContent = client.getWidget(cell); - tBody.setWidget(rowId, colId, cellContent); - ((Paintable)cell).updateFromUIDL(cell, client); - tBody.getCellFormatter().setWordWrap(rowId, colId, false); - } - - public void setCellContent(int rowId, int colId, String text) { - HTML cellContent = new HTML(); - cellContent.setText(text); - tBody.setWidget(rowId, colId, cellContent); - } - - /** - * Run when receices its initial content. Syncs headers and bodys - * "natural widths and saves the values. - */ - private void initSize() { - int cols = tHead.getCellCount(0); - FlexCellFormatter hf = tHead.getFlexCellFormatter(); - FlexCellFormatter bf = tBody.getFlexCellFormatter(); - for (int i = 0; i < cols; i++) { - Element hCell = hf.getElement(0, i); - Element bCell = bf.getElement(1, i); - int hw = DOM.getIntAttribute(hCell, "offsetWidth"); - int cw = DOM.getIntAttribute(bCell, "offsetWidth"); - setColWidth(i , hw > cw ? hw : cw); - } - - bodyContainer.setHeight(tBody.getOffsetHeight() + "px"); - bodyContainer.setWidth((tBody.getOffsetWidth() + 20) + "px"); - - } - private void setColWidth(int colIndex, int w) { String cid = getColKeyByIndex(colIndex); tHead.getCellFormatter().setWidth(0, colIndex, w + "px"); - tBody.getCellFormatter().setWidth(0, colIndex, w + "px"); + tBody.setColWidth(colIndex, w); columnWidths.put(cid,new Integer(w)); } @@ -322,15 +198,8 @@ public class ITableScrollingByComposition extends Composite implements Paintable return ( (Integer) this.columnWidths.get(colKey)).intValue(); } - private void updateSpacers() { - int preSpacerHeight = (firstRendered)*getRowHeight(); - int postSpacerHeight = (totalRows - 1 - lastRendered)*getRowHeight(); - preSpacer.setHeight(preSpacerHeight+"px"); - postSpacer.setHeight(postSpacerHeight + "px"); - } - private int getRenderedRowCount() { - return lastRendered-firstRendered; + return tBody.getLastRendered()-tBody.getFirstRendered(); } /** @@ -339,9 +208,12 @@ public class ITableScrollingByComposition extends Composite implements Paintable * */ public void onScroll(Widget widget, int scrollLeft, int scrollTop) { + if(!initializedAndAttached) + return; + rowRequestHandler.cancel(); - firstRowInViewPort = (int) Math.ceil( scrollTop / rowHeight ); + firstRowInViewPort = (int) Math.ceil( scrollTop / tBody.getRowHeight() ); client.console.log("At scrolltop: " + scrollTop + " At row " + firstRowInViewPort); int postLimit = (int) (firstRowInViewPort + pageLength + pageLength*CACHE_REACT_RATE); @@ -350,6 +222,8 @@ public class ITableScrollingByComposition extends Composite implements Paintable int preLimit = (int) (firstRowInViewPort - pageLength*CACHE_REACT_RATE); if(preLimit < 0) preLimit = 0; + int lastRendered = tBody.getLastRendered(); + int firstRendered = tBody.getFirstRendered(); if( (postLimit <= lastRendered && preLimit >= firstRendered ) ) { @@ -384,6 +258,65 @@ public class ITableScrollingByComposition extends Composite implements Paintable } } + + + protected void onAttach() { + + super.onAttach(); + + // sync column widths + initColumnWidths(); + + if(height < 0) { + bodyContainer.setHeight((tBody.getRowHeight()*pageLength) + "px"); + } else { + bodyContainer.setHeight(height + "px"); + } + + if(width < 0) { + bodyContainer.setWidth((tBody.getOffsetWidth() + getScrollBarWidth() ) + "px"); + } else { + bodyContainer.setWidth(width + "px"); + } + + if(firstvisible > 0) + bodyContainer.setScrollPosition(firstvisible*tBody.getRowHeight()); + + DeferredCommand.add(new Command() { + public void execute() { + if(totalRows - 1 > tBody.getLastRendered()) { + // fetch cache rows + rowRequestHandler.setReqFirstRow(tBody.getLastRendered()+1); + rowRequestHandler.setReqRows((int) (pageLength*CACHE_RATE)); + rowRequestHandler.deferRowFetch(); + } + } + }); + + + } + + /** + * Run when receices its initial content. Syncs headers and bodys + * "natural widths and saves the values. + */ + private void initColumnWidths() { + int cols = tHead.getCellCount(0); + FlexCellFormatter hf = tHead.getFlexCellFormatter(); + for (int i = 0; i < cols; i++) { + Element hCell = hf.getElement(0, i); + int hw = DOM.getIntAttribute(hCell, "offsetWidth"); + int cw = tBody.getColWidth(i); + int w = (hw > cw ? hw : cw) + IScrollTableBody.CELL_EXTRA_WIDTH; + setColWidth(i , w); + } + } + + private int getScrollBarWidth() { + // TODO Auto-generated method stub + return 30; + } + private class RowRequestHandler extends Timer { private int reqFirstRow = 0; diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java new file mode 100644 index 0000000000..7b2b54b498 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableBody.java @@ -0,0 +1,235 @@ +package com.itmill.toolkit.terminal.gwt.client.ui.scrolltable; + +import java.util.Iterator; +import java.util.List; +import java.util.Vector; + +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.Widget; +import com.itmill.toolkit.terminal.gwt.client.Client; +import com.itmill.toolkit.terminal.gwt.client.UIDL; + +/** + * This Panel can only contain IScrollTAbleRow type of + * widgets. This "simulates" very large table, keeping + * spacers which take room of unrendered rows. + * + * @author mattitahvonen + * + */ +public class IScrollTableBody extends Panel { + + public static final int CELL_EXTRA_WIDTH = 20; + + protected static int DEFAULT_ROW_HEIGHT = 25; + + private int rowHeight = -1; + + private List renderedRows = new Vector(); + + private boolean initDone = false; + + private int totalRows; + + Element preSpacer = DOM.createDiv(); + Element postSpacer = DOM.createDiv(); + + Element container = DOM.createDiv(); + + Element tBody = DOM.createTBody(); + Element table = DOM.createTable(); + + private int firstRendered; + + private int lastRendered; + + private Client client; + + + IScrollTableBody(Client client) { + this.client = client; + + constructDOM(); + + setElement(container); + + } + + private void constructDOM() { + DOM.setAttribute(table, "className", "iscrolltable-table"); + DOM.setAttribute(preSpacer, "className", "iscrolltable-rowspacer"); + DOM.setAttribute(postSpacer, "className", "iscrolltable-rowspacer"); + + DOM.appendChild(table, tBody); + DOM.appendChild(container, preSpacer); + DOM.appendChild(container, table); + DOM.appendChild(container, postSpacer); + + } + + + public void renderInitialRows(UIDL rowData, int firstIndex, int rows, int totalRows) { + this.totalRows = totalRows; + this.firstRendered = firstIndex; + this.lastRendered = firstIndex + rows - 1 ; + Iterator it = rowData.getChildIterator(); + while(it.hasNext()) { + IScrollTableRow row = new IScrollTableRow((UIDL) it.next(), client); + addRow(row); + } + if(isAttached()) + fixSpacers(); + } + + public void renderRows(UIDL rowData, int firstIndex, int rows) { + Iterator it = rowData.getChildIterator(); + if(firstIndex == lastRendered + 1) { + while(it.hasNext()) { + IScrollTableRow row = createRow((UIDL) it.next()); + addRow(row); + lastRendered++; + } + fixSpacers(); + } else if(firstIndex + rows == firstRendered) { + IScrollTableRow[] rowArray = new IScrollTableRow[rows]; + int i = rows; + while(it.hasNext()) { + i--; + rowArray[i] = createRow((UIDL) it.next()); + } + for(i = 0 ; i < rows; i++) { + addRowBeforeFirstRendered(rowArray[i]); + firstRendered--; + } + } else if (firstIndex > lastRendered || firstIndex + rows < firstRendered) { + // complitely new set of rows + // create one row before truncating row + IScrollTableRow row = createRow((UIDL) it.next()); + while(lastRendered + 1 > firstRendered) + unlinkRow(false); + + addRow(row); + firstRendered = firstIndex; + this.lastRendered = firstIndex + rows - 1 ; + while(it.hasNext()) + addRow(createRow((UIDL) it.next())); + fixSpacers(); + } else { + client.console.log("Bad update" + firstIndex + "/"+ rows); + } + } + + /** + * This mehtod is used to instantiate new rows for this table. + * It automatically sets correct widths to rows cells and assigns + * correct client reference for child widgets. + * + * This method can be called only after table has been initialized + * + * @param uidl + * @param client2 + */ + private IScrollTableRow createRow(UIDL uidl) { + IScrollTableRow row = new IScrollTableRow(uidl, client); + int cells = DOM.getChildCount(row.getElement()); + for(int i = 0; i < cells; i++) { + Element cell = DOM.getChild(row.getElement(), i); + int w = getColWidth(i); + DOM.setStyleAttribute(cell, "width", w + "px"); + DOM.setStyleAttribute(DOM.getFirstChild(cell), "width", w + "px"); + } + return row; + } + + private void addRowBeforeFirstRendered(IScrollTableRow row) { + DOM.insertChild(tBody, row.getElement(), 0); + adopt(row, null); + renderedRows.add(0, row); + } + + private void addRow(IScrollTableRow row) { + DOM.appendChild(tBody, row.getElement()); + adopt(row, null); + renderedRows.add(row); + } + + public Iterator iterator() { + return renderedRows.iterator(); + } + + public void unlinkRow(boolean fromBeginning) { + if(lastRendered - firstRendered < 0) + return; + int index; + if(fromBeginning) { + index = 0; + firstRendered++; + } else { + index = renderedRows.size() - 1; + lastRendered--; + } + IScrollTableRow toBeRemoved = (IScrollTableRow) renderedRows.get(index); + this.disown(toBeRemoved); + renderedRows.remove(index); + fixSpacers(); + } + + public boolean remove(Widget w) { + throw new UnsupportedOperationException(); + } + + protected void onAttach() { + super.onAttach(); + fixSpacers(); + } + + private void fixSpacers() { + int tBodyHeight = DOM.getIntAttribute(table, "offsetHeight"); + DOM.setStyleAttribute(preSpacer, "height", getRowHeight()*firstRendered + "px"); + DOM.setStyleAttribute(postSpacer, "height", getRowHeight()*(totalRows - 1 - lastRendered) + "px"); + + } + + public int getTotalRows() { + return totalRows; + } + + public int getRowHeight() { + if(initDone) + return rowHeight; + else { + if(DOM.getChildCount(tBody) > 0) { + rowHeight = DOM.getIntAttribute(tBody, "offsetHeight")/DOM.getChildCount(tBody); + } else { + return DEFAULT_ROW_HEIGHT; + } + initDone = true; + return rowHeight; + } + } + + public int getColWidth(int i) { + Element e = DOM.getChild(DOM.getChild(tBody, 0), i); + return DOM.getIntAttribute(e, "offsetWidth"); + } + + public void setColWidth(int colIndex, int w) { + int rows = DOM.getChildCount(tBody); + for(int i = 0; i < rows; i++) { + Element cell = DOM.getChild(DOM.getChild(tBody, i), colIndex); + DOM.setStyleAttribute(cell, "width", w + "px"); + DOM.setStyleAttribute(DOM.getFirstChild(cell), "width", w + "px"); + } + } + + public int getLastRendered() { + return lastRendered; + } + + public int getFirstRendered() { + return firstRendered; + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableRow.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableRow.java new file mode 100644 index 0000000000..9608dcd397 --- /dev/null +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/scrolltable/IScrollTableRow.java @@ -0,0 +1,62 @@ +package com.itmill.toolkit.terminal.gwt.client.ui.scrolltable; + +import java.util.Iterator; +import java.util.Vector; + +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.ui.Label; +import com.google.gwt.user.client.ui.Panel; +import com.google.gwt.user.client.ui.Widget; +import com.itmill.toolkit.terminal.gwt.client.Client; +import com.itmill.toolkit.terminal.gwt.client.Paintable; +import com.itmill.toolkit.terminal.gwt.client.UIDL; + +public class IScrollTableRow extends Panel { + + Vector childWidgets = new Vector(); + + private IScrollTableRow() { + setElement(DOM.createElement("tr")); + } + + public IScrollTableRow(UIDL uidl, Client client) { + this(); + if(uidl.hasAttribute("caption")) + addCell(uidl.getStringAttribute("caption")); + Iterator cells = uidl.getChildIterator(); + while(cells.hasNext()) { + Object cell = cells.next(); + if (cell instanceof String) { + addCell(cell.toString()); + } else { + Widget cellContent = client.getWidget((UIDL) cell); + (( Paintable) cellContent).updateFromUIDL((UIDL) cell, client); + } + } + } + + public void addCell(String text) { + addCell(new Label(text)); + } + + public void addCell(Widget w) { + Element td = DOM.createTD(); + Element container = DOM.createDiv(); + DOM.setAttribute(container, "className", "iscrolltable-cellContent"); + DOM.appendChild(td, container); + DOM.appendChild(getElement(), td); + adopt(w, container); + childWidgets.add(w); + } + + public Iterator iterator() { + return childWidgets.iterator(); + } + + public boolean remove(Widget w) { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css index 7cd3202b4d..0e70e15a0b 100644 --- a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css +++ b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/common/css/common.css @@ -14,4 +14,55 @@ input, select, textarea, button { select { padding: 0; margin: 0; +} + +/* TODO move table styles to separate file */ + +.iscrolltable-header table { + border-collapse:collapse; + margin:0; + padding:0; + border:0; + background: yellow; + table-layout: fixed; +} + +.iscrolltable-header table td { + margin:0; + padding:0; + border:0; +} + + + +.iscrolltable-table { + border-collapse:collapse; + margin:0; + padding:0; + border:0; + background: yellow; + table-layout: fixed; +} + +.iscrolltable-table td { + border:0; + margin:0; + padding:0; + background: green; +} +iscrolltable-table tr { + background: blue; + border:0; + margin:0; + padding:0; +} + +.iscrolltable-rowspacer { + height: 10px; + background: brown; +} + +.iscrolltable-table .iscrolltable-cellContent { + white-space: nowrap; + overflow: hidden; } \ No newline at end of file -- 2.39.5