From 060e0d53300801b3dea0d3e6c97c62f073b8a06a Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Wed, 1 Apr 2009 13:04:09 +0000 Subject: [PATCH] fixes #2806 (column expand ratios for Table). Also added some test cases. svn changeset:7271/svn branch:6.0 --- .../terminal/gwt/client/ui/IScrollTable.java | 92 ++++++++++++++----- .../components/table/ColumnExpandRatio.java | 70 ++++++++++++++ .../tests/components/table/ColumnWidths.java | 68 ++++++++++++++ src/com/itmill/toolkit/ui/Table.java | 87 ++++++++++++++++-- 4 files changed, 286 insertions(+), 31 deletions(-) create mode 100644 src/com/itmill/toolkit/tests/components/table/ColumnExpandRatio.java create mode 100644 src/com/itmill/toolkit/tests/components/table/ColumnWidths.java diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java index f62eaf592b..2f7f61d1c7 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IScrollTable.java @@ -541,6 +541,7 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { int i = 0; int totalExplicitColumnsWidths = 0; int total = 0; + float expandRatioDivider = 0; final int[] widths = new int[tHead.visibleCells.size()]; @@ -553,11 +554,18 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { // server has defined column width explicitly totalExplicitColumnsWidths += w; } else { - // get and store greater of header width and column width, and - // store it as a minimumn natural col width - final int hw = hCell.getOffsetWidth(); - final int cw = tBody.getColWidth(i); - w = (hw > cw ? hw : cw) + IScrollTableBody.CELL_EXTRA_WIDTH; + if (hCell.getExpandRatio() > 0) { + expandRatioDivider += hCell.getExpandRatio(); + w = IScrollTableBody.CELL_EXTRA_WIDTH + + IScrollTableBody.CELL_CONTENT_PADDING; + } else { + // get and store greater of header width and column width, + // and + // store it as a minimumn natural col width + final int hw = hCell.getOffsetWidth(); + final int cw = tBody.getColWidth(i); + w = (hw > cw ? hw : cw) + IScrollTableBody.CELL_EXTRA_WIDTH; + } hCell.setNaturalMinimumColumnWidth(w); } widths[i] = w; @@ -596,7 +604,6 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { int totalWidthR = total - totalExplicitColumnsWidths; if (totalWidthR > 0) { needsReLayout = true; - /* * If the table has a relative width and there is enough space * for a scrollbar we reserve this in the last column @@ -619,23 +626,40 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { extraSpace -= scrollbarWidthReserved; scrollbarWidthReservedInColumn = columnindex; } - - // now we will share this sum relatively to those without - // explicit width - headCells = tHead.iterator(); - i = 0; - HeaderCell hCell; - while (headCells.hasNext()) { - hCell = (HeaderCell) headCells.next(); - if (hCell.getWidth() == -1) { - int w = widths[i]; - final int newSpace = extraSpace * w / totalWidthR; - w += newSpace; - widths[i] = w; + if (expandRatioDivider > 0) { + // visible columns have some active expand ratios, excess + // space is divided according to them + headCells = tHead.iterator(); + i = 0; + while (headCells.hasNext()) { + HeaderCell hCell = (HeaderCell) headCells.next(); + if (hCell.getExpandRatio() > 0) { + int w = widths[i]; + final int newSpace = (int) (extraSpace * (hCell + .getExpandRatio() / expandRatioDivider)); + w += newSpace; + widths[i] = w; + } + i++; + } + } else { + // now we will share this sum relatively to those without + // explicit width + headCells = tHead.iterator(); + i = 0; + while (headCells.hasNext()) { + HeaderCell hCell = (HeaderCell) headCells.next(); + if (hCell.getWidth() == -1) { + int w = widths[i]; + final int newSpace = extraSpace * w / totalWidthR; + w += newSpace; + widths[i] = w; + } + i++; } - i++; } } + } else { // bodys size will be more than available and scrollbar will appear } @@ -1000,6 +1024,8 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { boolean definedWidth = false; + private float expandRatio = 0; + public void setSortable(boolean b) { sortable = b; } @@ -1039,6 +1065,8 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { public void setWidth(int w, boolean ensureDefinedWidth) { if (ensureDefinedWidth) { definedWidth = true; + // on column resize expand ratio becomes zero + expandRatio = 0; } if (width == w) { return; @@ -1327,6 +1355,14 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { } } + public void setExpandRatio(float floatAttribute) { + expandRatio = floatAttribute; + } + + public float getExpandRatio() { + return expandRatio; + } + } /** @@ -1441,6 +1477,9 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { } else if (recalcWidths) { c.setUndefinedWidth(); } + if (col.hasAttribute("er")) { + c.setExpandRatio(col.getFloatAttribute("er")); + } } // check for orphaned header cells for (String cid : availableCells.keySet()) { @@ -2556,11 +2595,14 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { Iterator headCells = tHead.iterator(); int usedMinimumWidth = 0; int totalExplicitColumnsWidths = 0; + float expandRatioDivider = 0; while (headCells.hasNext()) { final HeaderCell hCell = (HeaderCell) headCells.next(); usedMinimumWidth += hCell.getNaturalColumnWidth(); if (hCell.isDefinedWidth()) { totalExplicitColumnsWidths += hCell.getWidth(); + } else { + expandRatioDivider += hCell.getExpandRatio(); } } @@ -2585,7 +2627,15 @@ public class IScrollTable extends FlowPanel implements Table, ScrollListener { hCell = (HeaderCell) headCells.next(); if (!hCell.isDefinedWidth()) { int w = hCell.getNaturalColumnWidth(); - final int newSpace = w + extraSpace * w / totalWidthR; + int newSpace; + if (expandRatioDivider > 0) { + // divide excess space by expand ratios + newSpace = (int) (w + extraSpace + * hCell.getExpandRatio() / expandRatioDivider); + } else { + // divide relatively to natural column widths + newSpace = w + extraSpace * w / totalWidthR; + } setColWidth(i, newSpace, false); } i++; diff --git a/src/com/itmill/toolkit/tests/components/table/ColumnExpandRatio.java b/src/com/itmill/toolkit/tests/components/table/ColumnExpandRatio.java new file mode 100644 index 0000000000..94c2c5c4fc --- /dev/null +++ b/src/com/itmill/toolkit/tests/components/table/ColumnExpandRatio.java @@ -0,0 +1,70 @@ +package com.itmill.toolkit.tests.components.table; + +import com.itmill.toolkit.data.Item; +import com.itmill.toolkit.data.util.IndexedContainer; +import com.itmill.toolkit.tests.components.TestBase; +import com.itmill.toolkit.ui.Label; +import com.itmill.toolkit.ui.Table; + +public class ColumnExpandRatio extends TestBase { + + @Override + protected String getDescription() { + return "Column expand ratios can be used to adjust the way " + + "how excess horizontal space is divided among columns."; + + } + + @Override + protected Integer getTicketNumber() { + return 2806; + } + + private static final int ROWS = 100; + + @Override + public void setup() { + Table table1 = initTable(); + addComponent(new Label("Plain table")); + addComponent(table1); + + } + + private Table initTable() { + Table table = new Table(); + table.setWidth("100%"); + + IndexedContainer idx = new IndexedContainer(); + idx.addContainerProperty("firstname", String.class, null); + idx.addContainerProperty("lastname", String.class, null); + Item i = idx.addItem(1); + i.getItemProperty("firstname").setValue("John"); + i.getItemProperty("lastname").setValue("Johnson"); + + i = idx.addItem(2); + i.getItemProperty("firstname").setValue("Jane"); + i.getItemProperty("lastname").setValue("Janeine"); + + for (int index = 3; index < ROWS; index++) { + i = idx.addItem(index); + i.getItemProperty("firstname").setValue("Jane"); + i.getItemProperty("lastname").setValue("Janeine"); + } + + idx.addContainerProperty("fixed 50px column", String.class, ""); + + idx.addContainerProperty("Expanded with 2", String.class, "foobar"); + + table.setContainerDataSource(idx); + + table.setColumnHeader("firstname", "FirstName"); + table.setColumnHeader("lastname", "LastName (1)"); + + table.setColumnWidth("fixed 50px column", 50); + table.setColumnExpandRatio("Expanded with 2", 2); + table.setColumnExpandRatio("lastname", 1); + + return table; + } + +} diff --git a/src/com/itmill/toolkit/tests/components/table/ColumnWidths.java b/src/com/itmill/toolkit/tests/components/table/ColumnWidths.java new file mode 100644 index 0000000000..af03414db5 --- /dev/null +++ b/src/com/itmill/toolkit/tests/components/table/ColumnWidths.java @@ -0,0 +1,68 @@ +package com.itmill.toolkit.tests.components.table; + +import com.itmill.toolkit.data.Item; +import com.itmill.toolkit.data.util.IndexedContainer; +import com.itmill.toolkit.tests.components.TestBase; +import com.itmill.toolkit.ui.Label; +import com.itmill.toolkit.ui.Table; + +public class ColumnWidths extends TestBase { + + @Override + protected String getDescription() { + return "On window resize undefined " + + "columns (by server or user (dragged)) columns " + + "must consume the excess space. Space is divided " + + "by default according to natural widths of columns." + + " Lastname should get 1/3 of excess spsace, the las column 2/3."; + + } + + @Override + protected Integer getTicketNumber() { + return 2804; + } + + private static final int ROWS = 100; + + @Override + public void setup() { + Table table1 = initTable(); + addComponent(new Label("Plain table")); + addComponent(table1); + + } + + private Table initTable() { + Table table = new Table(); + table.setWidth("100%"); + + IndexedContainer idx = new IndexedContainer(); + idx.addContainerProperty("firstname", String.class, null); + idx.addContainerProperty("lastname", String.class, null); + Item i = idx.addItem(1); + i.getItemProperty("firstname").setValue("John"); + i.getItemProperty("lastname").setValue("Johnson"); + i = idx.addItem(2); + i.getItemProperty("firstname").setValue("Jane"); + i.getItemProperty("lastname").setValue("Janeine"); + + for (int index = 3; index < ROWS; index++) { + i = idx.addItem(index); + i.getItemProperty("firstname").setValue("Jane"); + i.getItemProperty("lastname").setValue("Janeine"); + } + + idx.addContainerProperty("150pxfixedCol", String.class, "foobar"); + + table.setContainerDataSource(idx); + + table.setColumnHeader("firstname", "FirstName"); + table.setColumnHeader("lastname", "LastName"); + + table.setColumnWidth("150pxfixedCol", 150); + + return table; + } + +} diff --git a/src/com/itmill/toolkit/ui/Table.java b/src/com/itmill/toolkit/ui/Table.java index 424495ae42..b91fa614fd 100644 --- a/src/com/itmill/toolkit/ui/Table.java +++ b/src/com/itmill/toolkit/ui/Table.java @@ -189,9 +189,10 @@ public class Table extends AbstractSelect implements Action.Container, private HashMap columnAlignments = new HashMap(); /** - * Holds column widths in pixels for visible columns (by propertyId). + * Holds column widths in pixels (Integer) or expand ratios (Float) for + * visible columns (by propertyId). */ - private final HashMap columnWidths = new HashMap(); + private final HashMap columnWidths = new HashMap(); /** * Holds column generators @@ -648,6 +649,10 @@ public class Table extends AbstractSelect implements Action.Container, * small or very big values. Setting width to -1 (default) means that theme * will make decision of width. * + *

+ * Column can either have a fixed width or expand ratio. The latter one set + * is used. See @link {@link #setColumnExpandRatio(Object, float)}. + * * @param columnId * colunmns property id * @param width @@ -655,20 +660,78 @@ public class Table extends AbstractSelect implements Action.Container, * @since 4.0.3 */ public void setColumnWidth(Object columnId, int width) { - columnWidths.put(columnId, new Integer(width)); + if (width < 0) { + columnWidths.remove(columnId); + } else { + columnWidths.put(columnId, new Integer(width)); + } } /** - * Gets the width of column + * Sets the column expand ratio for given column. + *

+ * Expand ratios can be defined to customize the way how excess space is + * divided among columns. Table can have excess space if it has its width + * defined and there is horizontally more space than columns consume + * naturally. Excess space is the space that is not used by columns with + * explicit width (see {@link #setColumnWidth(Object, int)}) or with natural + * width (no width nor expand ratio). + * + *

+ * By default (without expand ratios) the excess space is divided + * proportionally to columns natural widths. + * + *

+ * Only expand ratios of visible columns are used in final calculations. + * + *

+ * Column can either have a fixed width or expand ratio. The latter one set + * is used. + * + *

+ * A column with expand ratio is considered to be minimum width by default + * (if no excess space exists). The minimum width is defined by terminal + * implementation. + * + *

+ * If terminal implementation supports re-sizeable columns the column + * becomes fixed width column if users resizes the column. + * + * @param columnId + * colunmns property id + * @param expandRatio + * the expandRatio used to divide excess space for this column + */ + public void setColumnExpandRatio(Object columnId, float expandRatio) { + if (expandRatio < 0) { + columnWidths.remove(columnId); + } else { + columnWidths.put(columnId, new Float(expandRatio)); + } + } + + public float getColumnExpandRatio(Object propertyId) { + final Object width = columnWidths.get(propertyId); + if (width == null || !(width instanceof Float)) { + return -1; + } + final Float value = (Float) width; + return value.floatValue(); + + } + + /** + * Gets the pixel width of column * * @param propertyId * @return width of colun or -1 when value not set */ public int getColumnWidth(Object propertyId) { - final Integer value = columnWidths.get(propertyId); - if (value == null) { + final Object width = columnWidths.get(propertyId); + if (width == null || !(width instanceof Integer)) { return -1; } + final Integer value = (Integer) width; return value.intValue(); } @@ -2157,11 +2220,15 @@ public class Table extends AbstractSelect implements Action.Container, if (!ALIGN_LEFT.equals(getColumnAlignment(columnId))) { target.addAttribute("align", getColumnAlignment(columnId)); } - if (getColumnWidth(columnId) > -1) { - target.addAttribute("width", String - .valueOf(getColumnWidth(columnId))); + if (columnWidths.containsKey(columnId)) { + if (getColumnWidth(columnId) > -1) { + target.addAttribute("width", String + .valueOf(getColumnWidth(columnId))); + } else { + target.addAttribute("er", + getColumnExpandRatio(columnId)); + } } - target.endTag("column"); } } -- 2.39.5