From 548c1f952f7b3a09631045d8d6e28f3ea97b81ba Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marko=20Gr=C3=B6nroos?= Date: Tue, 12 Aug 2008 14:36:14 +0000 Subject: [PATCH] For #1836. Added editing to generated column example. Reformatted bad automatic source formatting. svn changeset:5177/svn branch:trunk --- .../GeneratedColumnExample.java | 211 ++++++++++-------- 1 file changed, 122 insertions(+), 89 deletions(-) diff --git a/src/com/itmill/toolkit/demo/featurebrowser/GeneratedColumnExample.java b/src/com/itmill/toolkit/demo/featurebrowser/GeneratedColumnExample.java index b40bc8fb7b..417828480f 100644 --- a/src/com/itmill/toolkit/demo/featurebrowser/GeneratedColumnExample.java +++ b/src/com/itmill/toolkit/demo/featurebrowser/GeneratedColumnExample.java @@ -10,12 +10,28 @@ import com.itmill.toolkit.data.Item; import com.itmill.toolkit.data.Property; import com.itmill.toolkit.data.Container.Indexed; import com.itmill.toolkit.data.util.BeanItem; +import com.itmill.toolkit.ui.AbstractField; +import com.itmill.toolkit.ui.BaseFieldFactory; +import com.itmill.toolkit.ui.CheckBox; import com.itmill.toolkit.ui.Component; import com.itmill.toolkit.ui.CustomComponent; import com.itmill.toolkit.ui.ExpandLayout; +import com.itmill.toolkit.ui.Field; import com.itmill.toolkit.ui.Label; import com.itmill.toolkit.ui.Table; - +import com.itmill.toolkit.ui.Button.ClickEvent; +import com.itmill.toolkit.ui.Button.ClickListener; + +/** + * This example demonstrates the use of generated columns in a table. + * Generated columns can be used for formatting values or calculating + * them from other columns (or properties of the items). + * + * For the data model, we use POJOs bound to a custom Container + * with BeanItem items. + * + * @author magi + */ public class GeneratedColumnExample extends CustomComponent { /** * The business model: fill-up at a gas station. @@ -28,30 +44,26 @@ public class GeneratedColumnExample extends CustomComponent { public FillUp() { } - public FillUp(int day, int month, int year, double quantity, - double total) { - date = new GregorianCalendar(year, month - 1, day).getTime(); + public FillUp(int day, int month, int year, double quantity, double total) { + date = new GregorianCalendar(year, month-1, day).getTime(); this.quantity = quantity; this.total = total; } /** Calculates price per unit of quantity (€/l). */ public double price() { - if (quantity != 0.0) { + if (quantity != 0.0) return total / quantity; - } else { + else return 0.0; - } } /** Calculates average daily consumption between two fill-ups. */ public double dailyConsumption(FillUp other) { double difference_ms = date.getTime() - other.date.getTime(); double days = difference_ms / 1000 / 3600 / 24; - if (days < 0.5) { - days = 1.0; // Avoid division by zero if two fill-ups on the - // same day. - } + if (days < 0.5) + days = 1.0; // Avoid division by zero if two fill-ups on the same day. return quantity / days; } @@ -95,11 +107,11 @@ public class GeneratedColumnExample extends CustomComponent { * Most of the interface methods are implemented with just dummy * implementations, as they are not needed in this example. */ - public class MyContainer implements Container, Indexed { + public class MySimpleIndexedContainer implements Container,Indexed { Vector items; Object itemtemplate; - - public MyContainer(Object itemtemplate) { + + public MySimpleIndexedContainer(Object itemtemplate) { this.itemtemplate = itemtemplate; items = new Vector(); // Yeah this is just a test } @@ -128,9 +140,8 @@ public class GeneratedColumnExample extends CustomComponent { public boolean containsId(Object itemId) { if (itemId instanceof Integer) { int pos = ((Integer) itemId).intValue(); - if (pos >= 0 && pos < items.size()) { + if (pos >= 0 && pos < items.size()) return items.get(pos) != null; - } } return false; } @@ -145,7 +156,7 @@ public class GeneratedColumnExample extends CustomComponent { int pos = ((Integer) itemId).intValue(); if (pos >= 0 && pos < items.size()) { Item item = (Item) items.get(pos); - + // The BeanItem provides the property objects for the items. return item.getItemProperty(propertyId); } @@ -163,19 +174,17 @@ public class GeneratedColumnExample extends CustomComponent { public Item getItem(Object itemId) { if (itemId instanceof Integer) { - int pos = ((Integer) itemId).intValue(); - if (pos >= 0 && pos < items.size()) { + int pos = ((Integer)itemId).intValue(); + if (pos >= 0 && pos < items.size()) return (Item) items.get(pos); - } } return null; } public Collection getItemIds() { Vector ids = new Vector(items.size()); - for (int i = 0; i < items.size(); i++) { + for (int i = 0; i < items.size(); i++) ids.add(Integer.valueOf(i)); - } return ids; } @@ -250,17 +259,15 @@ public class GeneratedColumnExample extends CustomComponent { public Object nextItemId(Object itemId) { int pos = indexOfId(itemId); - if (pos >= items.size() - 1) { + if (pos >= items.size() - 1) return null; - } return getIdByIndex(pos + 1); } public Object prevItemId(Object itemId) { int pos = indexOfId(itemId); - if (pos <= 0) { + if (pos <= 0) return null; - } return getIdByIndex(pos - 1); } } @@ -271,8 +278,7 @@ public class GeneratedColumnExample extends CustomComponent { * Generates the cell containing the Date value. The column is * irrelevant in this use case. */ - public Component generateCell(Table source, Object itemId, - Object columnId) { + public Component generateCell(Table source, Object itemId, Object columnId) { Property prop = source.getItem(itemId).getItemProperty(columnId); if (prop.getType().equals(Date.class)) { Label label = new Label(String.format("%tF", @@ -300,17 +306,14 @@ public class GeneratedColumnExample extends CustomComponent { * Generates the cell containing the Double value. The column is * irrelevant in this use case. */ - public Component generateCell(Table source, Object itemId, - Object columnId) { + public Component generateCell(Table source, Object itemId, Object columnId) { Property prop = source.getItem(itemId).getItemProperty(columnId); if (prop.getType().equals(Double.class)) { Label label = new Label(String.format(format, new Object[] { (Double) prop.getValue() })); - - // Set styles for the column: one indicating that it's a value - // and a more - // specific one with the column name in it. This assumes that - // the column + + // Set styles for the column: one indicating that it's a value and a more + // specific one with the column name in it. This assumes that the column // name is proper for CSS. label.addStyleName("column-type-value"); label.addStyleName("column-" + (String) columnId); @@ -322,8 +325,7 @@ public class GeneratedColumnExample extends CustomComponent { /** Table column generator for calculating price column. */ class PriceColumnGenerator implements Table.ColumnGenerator { - public Component generateCell(Table source, Object itemId, - Object columnId) { + public Component generateCell(Table source, Object itemId, Object columnId) { // Retrieve the item. BeanItem item = (BeanItem) source.getItem(itemId); @@ -350,8 +352,7 @@ public class GeneratedColumnExample extends CustomComponent { /** * Generates a cell containing value calculated from the item. */ - public Component generateCell(Table source, Object itemId, - Object columnId) { + public Component generateCell(Table source, Object itemId, Object columnId) { Indexed indexedSource = (Indexed) source.getContainerDataSource(); // Can not calculate consumption for the first item. @@ -362,15 +363,11 @@ public class GeneratedColumnExample extends CustomComponent { } // Index of the previous item. - Object prevItemId = new Integer(indexedSource - .indexOfId(indexedSource.prevItemId(itemId))); + Object prevItemId = indexedSource.prevItemId(itemId); // Retrieve the POJOs. - FillUp fillup = (FillUp) ((BeanItem) indexedSource.getItem(itemId)) - .getBean(); - FillUp prev = (FillUp) ((BeanItem) source.getItem(prevItemId)) - .getBean(); - ; + FillUp fillup = (FillUp) ((BeanItem) indexedSource.getItem(itemId)).getBean(); + FillUp prev = (FillUp) ((BeanItem) source.getItem(prevItemId)).getBean(); // Do the business logic return generateCell(fillup, prev); @@ -406,73 +403,109 @@ public class GeneratedColumnExample extends CustomComponent { } } + /** + * Custom field factory that sets the fields as immediate. + */ + public class ImmediateFieldFactory extends BaseFieldFactory { + public Field createField(Class type, Component uiContext) { + // Let the BaseFieldFactory create the fields + Field field = super.createField(type, uiContext); + + // ...and just set them as immediate + ((AbstractField)field).setImmediate(true); + + return field; + } + } + public GeneratedColumnExample() { final Table table = new Table(); // Define table columns. These include also the column for the generated // column, because we want to set the column label to something // different than the property ID. - table - .addContainerProperty("date", Date.class, null, "Date", null, - null); - table.addContainerProperty("quantity", Double.class, null, - "Quantity (l)", null, null); - table.addContainerProperty("price", Double.class, null, "Price (€/l)", - null, null); - table.addContainerProperty("total", Double.class, null, "Total (€)", - null, null); - table.addContainerProperty("consumption", Double.class, null, - "Consumption (l/day)", null, null); - table.addContainerProperty("dailycost", Double.class, null, - "Daily Cost (€/day)", null, null); + table.addContainerProperty("date", Date.class, null, "Date", null, null); + table.addContainerProperty("quantity", Double.class, null, "Quantity (l)", null, null); + table.addContainerProperty("price", Double.class, null, "Price (€/l)", null, null); + table.addContainerProperty("total", Double.class, null, "Total (€)", null, null); + table.addContainerProperty("consumption", Double.class, null, "Consumption (l/day)", null, null); + table.addContainerProperty("dailycost", Double.class, null, "Daily Cost (€/day)", null, null); // Define the generated columns and their generators. - table.addGeneratedColumn("date", new DateColumnGenerator()); - table - .addGeneratedColumn("quantity", new ValueColumnGenerator( - "%.2f l")); - table.addGeneratedColumn("price", new PriceColumnGenerator()); - table.addGeneratedColumn("total", new ValueColumnGenerator("%.2f €")); - table.addGeneratedColumn("consumption", - new ConsumptionColumnGenerator()); - table.addGeneratedColumn("dailycost", new DailyCostColumnGenerator()); + table.addGeneratedColumn("date", new DateColumnGenerator()); + table.addGeneratedColumn("quantity", new ValueColumnGenerator("%.2f l")); + table.addGeneratedColumn("price", new PriceColumnGenerator()); + table.addGeneratedColumn("total", new ValueColumnGenerator("%.2f €")); + table.addGeneratedColumn("consumption", new ConsumptionColumnGenerator()); + table.addGeneratedColumn("dailycost", new DailyCostColumnGenerator()); // Create a data source and bind it to the table. - MyContainer data = new MyContainer(new FillUp()); + MySimpleIndexedContainer data = new MySimpleIndexedContainer(new FillUp()); table.setContainerDataSource(data); // Generated columns are automatically placed after property columns, so // we have to set the order of the columns explicitly. - table.setVisibleColumns(new Object[] { "date", "quantity", "price", - "total", "consumption", "dailycost" }); + table.setVisibleColumns(new Object[] { "date", "quantity", "price", "total", "consumption", "dailycost" }); // Add some data. - data.addItem(new BeanItem(new FillUp(19, 2, 2005, 44.96, 51.21))); - data.addItem(new BeanItem(new FillUp(30, 3, 2005, 44.91, 53.67))); - data.addItem(new BeanItem(new FillUp(20, 4, 2005, 42.96, 49.06))); - data.addItem(new BeanItem(new FillUp(23, 5, 2005, 47.37, 55.28))); - data.addItem(new BeanItem(new FillUp(6, 6, 2005, 35.34, 41.52))); - data.addItem(new BeanItem(new FillUp(30, 6, 2005, 16.07, 20.00))); - data.addItem(new BeanItem(new FillUp(2, 7, 2005, 36.40, 36.19))); - data.addItem(new BeanItem(new FillUp(6, 7, 2005, 39.17, 50.90))); - data.addItem(new BeanItem(new FillUp(27, 7, 2005, 43.43, 53.03))); - data.addItem(new BeanItem(new FillUp(17, 8, 2005, 20, 29.18))); - data.addItem(new BeanItem(new FillUp(30, 8, 2005, 46.06, 59.09))); - data.addItem(new BeanItem(new FillUp(22, 9, 2005, 46.11, 60.36))); + data.addItem(new BeanItem(new FillUp(19, 2, 2005, 44.96, 51.21))); + data.addItem(new BeanItem(new FillUp(30, 3, 2005, 44.91, 53.67))); + data.addItem(new BeanItem(new FillUp(20, 4, 2005, 42.96, 49.06))); + data.addItem(new BeanItem(new FillUp(23, 5, 2005, 47.37, 55.28))); + data.addItem(new BeanItem(new FillUp(6, 6, 2005, 35.34, 41.52))); + data.addItem(new BeanItem(new FillUp(30, 6, 2005, 16.07, 20.00))); + data.addItem(new BeanItem(new FillUp(2, 7, 2005, 36.40, 36.19))); + data.addItem(new BeanItem(new FillUp(6, 7, 2005, 39.17, 50.90))); + data.addItem(new BeanItem(new FillUp(27, 7, 2005, 43.43, 53.03))); + data.addItem(new BeanItem(new FillUp(17, 8, 2005, 20, 29.18))); + data.addItem(new BeanItem(new FillUp(30, 8, 2005, 46.06, 59.09))); + data.addItem(new BeanItem(new FillUp(22, 9, 2005, 46.11, 60.36))); data.addItem(new BeanItem(new FillUp(14, 10, 2005, 41.51, 50.19))); data.addItem(new BeanItem(new FillUp(12, 11, 2005, 35.24, 40.00))); data.addItem(new BeanItem(new FillUp(28, 11, 2005, 45.26, 53.27))); + // Have a check box that allows the user to make the quantity + // and total columns editable. + final CheckBox editable = new CheckBox("Edit the input values - calculated columns are regenerated"); + editable.setImmediate(true); + editable.addListener(new ClickListener() { + public void buttonClick(ClickEvent event) { + table.setEditable(editable.booleanValue()); + + // The columns may not be generated when we want to have them + // editable. + if (editable.booleanValue()) { + table.removeGeneratedColumn("quantity"); + table.removeGeneratedColumn("total"); + } else { + // In non-editable mode we want to show the formatted values. + table.addGeneratedColumn("quantity", new ValueColumnGenerator("%.2f l")); + table.addGeneratedColumn("total", new ValueColumnGenerator("%.2f €")); + } + // The visible columns are affected by removal and addition of + // generated columns so we have to redefine them. + table.setVisibleColumns( + new Object[] { "date","quantity","price","total","consumption", "dailycost" }); + } + }); + + // Use a custom field factory to set the edit fields as immediate. + // This is used when the table is in editable mode. + table.setFieldFactory(new ImmediateFieldFactory()); + + // Setting the table itself as immediate has no relevance in this example, + // because it is relevant only if the table is selectable and we want to + // get the selection changes immediately. + table.setImmediate(true); + table.setHeight("100%"); ExpandLayout layout = new ExpandLayout(); - layout - .addComponent(new Label( - "Table with column generators that format and calculate cell values.")); + layout.addComponent(new Label("Table with column generators that format and calculate cell values.")); layout.addComponent(table); - layout - .addComponent(new Label( - "Columns displayed in blue are calculated. Others are simply formatted.")); + layout.addComponent(editable); + layout.addComponent(new Label("Columns displayed in blue are calculated from Quantity and Total. "+ + "Others are simply formatted.")); layout.expand(table); layout.setSizeFull(); setCompositionRoot(layout); -- 2.39.5