From 2675e2eb98e19f5825c103c3266e230c4009013b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marko=20Gr=C3=B6nroos?= Date: Mon, 28 Jul 2008 13:12:15 +0000 Subject: [PATCH] Updated book examples. Form example, editable Table with beans, QueryContainer with Select. svn changeset:5119/svn branch:trunk --- .../tests/book/BookTestApplication.java | 79 +++++++- .../toolkit/tests/book/FormExample.java | 52 ++---- .../toolkit/tests/book/TableEditableBean.java | 172 +++++++++++++++--- 3 files changed, 241 insertions(+), 62 deletions(-) diff --git a/src/com/itmill/toolkit/tests/book/BookTestApplication.java b/src/com/itmill/toolkit/tests/book/BookTestApplication.java index 0e22af8d9a..014ca1788d 100644 --- a/src/com/itmill/toolkit/tests/book/BookTestApplication.java +++ b/src/com/itmill/toolkit/tests/book/BookTestApplication.java @@ -5,19 +5,25 @@ package com.itmill.toolkit.tests.book; import java.net.URL; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Set; -import java.util.Vector; -import com.itmill.toolkit.data.Container; +import org.hsqldb.*; + import com.itmill.toolkit.data.Item; -import com.itmill.toolkit.data.Property; import com.itmill.toolkit.data.Validator; +import com.itmill.toolkit.data.Container.PropertySetChangeEvent; +import com.itmill.toolkit.data.Container.PropertySetChangeListener; import com.itmill.toolkit.data.Property.ValueChangeEvent; import com.itmill.toolkit.data.Property.ValueChangeListener; -import com.itmill.toolkit.data.util.BeanItem; +import com.itmill.toolkit.data.util.QueryContainer; import com.itmill.toolkit.data.validator.StringLengthValidator; import com.itmill.toolkit.terminal.ClassResource; import com.itmill.toolkit.terminal.DownloadStream; @@ -36,8 +42,6 @@ import com.itmill.toolkit.ui.CustomLayout; import com.itmill.toolkit.ui.DateField; import com.itmill.toolkit.ui.Embedded; import com.itmill.toolkit.ui.ExpandLayout; -import com.itmill.toolkit.ui.Field; -import com.itmill.toolkit.ui.FieldFactory; import com.itmill.toolkit.ui.Form; import com.itmill.toolkit.ui.FormLayout; import com.itmill.toolkit.ui.GridLayout; @@ -57,7 +61,6 @@ import com.itmill.toolkit.ui.TextField; import com.itmill.toolkit.ui.Tree; import com.itmill.toolkit.ui.Window; import com.itmill.toolkit.ui.Button.ClickEvent; -import com.itmill.toolkit.ui.Window.Notification; public class BookTestApplication extends com.itmill.toolkit.Application { Window main = new Window("Application window"); @@ -142,7 +145,7 @@ public class BookTestApplication extends com.itmill.toolkit.Application { "progress/window", "progress/thread", "progress", "customlayout", "spacing", "margin", "clientinfo", "fillinform/templates", "notification", "print", - "richtextfield"}; + "richtextfield", "querycontainer"}; for (int i = 0; i < examples.length; i++) { main.addComponent(new Label("" + examples[i] + "", @@ -223,6 +226,8 @@ public class BookTestApplication extends com.itmill.toolkit.Application { example_Print(main, param); } else if (example.equals("richtextfield")) { example_RichTextField(main, param); + } else if (example.equals("querycontainer")) { + example_QueryContainer(main, param); } else { ; // main.addComponent(new Label("Unknown test '"+example+"'.")); } @@ -1419,4 +1424,62 @@ public class BookTestApplication extends com.itmill.toolkit.Application { main.addComponent(show); main.addComponent(html); } + + void example_QueryContainer(final Window main, String param) { + try { + // Create a database connection + Class.forName("org.hsqldb.jdbcDriver"); + final Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:qcexample", "sa", ""); + + // Create an example table and put some data in it. + Statement st = c.createStatement(); + st.executeQuery("CREATE TABLE Prisoners (id INTEGER, name VARCHAR)"); + st.close(); + for (int i=0; i<100; i++) { + st = c.createStatement(); + st.executeQuery("INSERT INTO Prisoners (id, name) VALUES ("+i+",'I am number "+(i+1)+"')"); + st.close(); + } + + // Query the database + final QueryContainer qc = new QueryContainer("SELECT id,name FROM Prisoners", c); + + // Create a component for selecting a query result item. + Select select = new Select("Select an item"); + + // The items shown in the selection component are obtained from the query. + select.setContainerDataSource(qc); + + // The item captions are obtained from a field in the query result. + select.setItemCaptionMode(Select.ITEM_CAPTION_MODE_PROPERTY); + + // Set the name of the field from which the item captions are obtained. + select.setItemCaptionPropertyId("name"); + + // When selection changes, display the selected item. + select.setImmediate(true); + final Label selection = new Label("Currently selected: -"); + select.addListener(new ValueChangeListener() { + public void valueChange(ValueChangeEvent event) { + // Get the item id of the currently selected item + Integer itemId = (Integer) event.getProperty().getValue(); + + // Use the item ID to get the actual row from the query result. + Item qrItem = qc.getItem(itemId); + + // Display the item ID + selection.setValue("Currently selected: result row "+itemId.intValue() + + " (id="+qrItem.getItemProperty("id")+", " + + "name="+qrItem.getItemProperty("name")+")"); + } + }); + + main.addComponent(select); + main.addComponent(selection); + } catch (SQLException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } } diff --git a/src/com/itmill/toolkit/tests/book/FormExample.java b/src/com/itmill/toolkit/tests/book/FormExample.java index f4b4c304b6..2125888004 100644 --- a/src/com/itmill/toolkit/tests/book/FormExample.java +++ b/src/com/itmill/toolkit/tests/book/FormExample.java @@ -17,7 +17,6 @@ import com.itmill.toolkit.ui.Form; import com.itmill.toolkit.ui.OrderedLayout; import com.itmill.toolkit.ui.Select; import com.itmill.toolkit.ui.TextField; -import com.itmill.toolkit.ui.Button.ClickEvent; /** * This example demonstrates the most important features of the Form component: @@ -31,16 +30,13 @@ import com.itmill.toolkit.ui.Button.ClickEvent; public class FormExample extends CustomComponent { /** Contact information data model. */ public class Contact { - String name = ""; - - String address = ""; - - int postalCode = 20540; - + String name = ""; + String address = ""; + int postalCode = 20540; String city; } - /** JavaBean wrapper for the data model. */ + /** Bean wrapper for the data model. */ public class ContactBean extends Contact { public ContactBean() { } @@ -63,22 +59,20 @@ public class FormExample extends CustomComponent { public void setPostalCode(String postalCode) { try { - if (postalCode != null) { + if (postalCode != null) this.postalCode = Integer.parseInt(postalCode); - } else { + else this.postalCode = 0; - } } catch (NumberFormatException e) { this.postalCode = 0; } } public String getPostalCode() { - if (postalCode > 0) { + if (postalCode > 0) return String.valueOf(postalCode); - } else { + else return ""; - } } public void setCity(String city) { @@ -107,12 +101,13 @@ public class FormExample extends CustomComponent { public Field createField(Item item, Object propertyId, Component uiContext) { String pid = (String) propertyId; - if (pid.equals("name")) { + + if (pid.equals("name")) return new TextField("Name"); - } - if (pid.equals("address")) { + + if (pid.equals("address")) return new TextField("Street Address"); - } + if (pid.equals("postalCode")) { TextField field = new TextField("Postal Code"); field.setColumns(5); @@ -126,8 +121,7 @@ public class FormExample extends CustomComponent { return ((String) value).matches("[0-9]{5}"); } - public void validate(Object value) - throws InvalidValueException { + public void validate(Object value) throws InvalidValueException { if (!isValid(value)) { throw new InvalidValueException( "Postal code must be a number 10000-99999."); @@ -137,15 +131,15 @@ public class FormExample extends CustomComponent { field.addValidator(postalCodeValidator); return field; } + if (pid.equals("city")) { Select select = new Select("City"); final String cities[] = new String[] { "Amsterdam", "Berlin", "Helsinki", "Hong Kong", "London", "Luxemburg", "New York", "Oslo", "Paris", "Rome", "Stockholm", "Tokyo", "Turku" }; - for (int i = 0; i < cities.length; i++) { + for (int i = 0; i < cities.length; i++) select.addItem(cities[i]); - } return select; } return null; @@ -163,8 +157,7 @@ public class FormExample extends CustomComponent { // Set form caption and description texts. form.setCaption("Contact Information"); - form - .setDescription("Please enter valid name and address. Fields marked with * are required."); + form.setDescription("Please enter valid name and address. Fields marked with * are required."); // Use custom field factory to create the fields in the form. form.setFieldFactory(new MyFieldFactory()); @@ -206,23 +199,16 @@ public class FormExample extends CustomComponent { form.setReadThrough(false); // Add Commit and Discard controls to the form. - ExpandLayout footer = new ExpandLayout( - OrderedLayout.ORIENTATION_HORIZONTAL); + ExpandLayout footer = new ExpandLayout(OrderedLayout.ORIENTATION_HORIZONTAL); // The Commit button calls form.commit(). Button commit = new Button("Commit", form, "commit"); - /*commit.addListener(new Button.ClickListener() { - public void buttonClick(ClickEvent event) { - form.setValidationVisible(true); - form.commit(); - } - });*/ // The Discard button calls form.discard(). Button discard = new Button("Discard", form, "discard"); footer.addComponent(commit); footer.setComponentAlignment(commit, ExpandLayout.ALIGNMENT_RIGHT, - ExpandLayout.ALIGNMENT_TOP); + ExpandLayout.ALIGNMENT_TOP); footer.setHeight("25px"); footer.addComponent(discard); form.setFooter(footer); diff --git a/src/com/itmill/toolkit/tests/book/TableEditableBean.java b/src/com/itmill/toolkit/tests/book/TableEditableBean.java index 4d13fa7f80..1029eabee2 100644 --- a/src/com/itmill/toolkit/tests/book/TableEditableBean.java +++ b/src/com/itmill/toolkit/tests/book/TableEditableBean.java @@ -4,10 +4,15 @@ package com.itmill.toolkit.tests.book; +import java.util.Collection; +import java.util.Vector; + +import com.itmill.toolkit.data.Container; import com.itmill.toolkit.data.Item; import com.itmill.toolkit.data.Property; import com.itmill.toolkit.data.Property.ValueChangeEvent; 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; @@ -16,14 +21,20 @@ import com.itmill.toolkit.ui.Field; import com.itmill.toolkit.ui.OrderedLayout; import com.itmill.toolkit.ui.Table; +/** + * Shows how to bind a bean to a table and make it editable. + */ public class TableEditableBean extends CustomComponent { + /** + * Let's have a simple example bean. + */ public class MyBean { boolean selected; String text; public MyBean() { - selected = false; - text = "Hello"; + this.selected = false; + this.text = ""; } public boolean isSelected() { @@ -46,25 +57,135 @@ public class TableEditableBean extends CustomComponent { System.out.println("setText("+text+") called."); } }; - + + /** + * Custom field factory that sets the fields as immediate for debugging + * purposes. This is not normally necessary, unless you want to have some + * interaction that requires it. + */ public class MyFieldFactory extends BaseFieldFactory { public Field createField(Class type, Component uiContext) { - // Boolean field - if (Boolean.class.isAssignableFrom(type)) { - final CheckBox checkbox = new CheckBox(); - checkbox.setSwitchMode(true); - checkbox.setImmediate(true); - return checkbox; - } - return super.createField(type, 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 class MyTable extends Table { - /** Really adds an item and not just an item id. */ - public void addItem(Item item, Object itemId) { - + + /** + * This is a custom container that allows adding BeanItems inside it. The + * BeanItem objects must be bound to a MyBean object. The item ID is an + * Integer from 0 to 99. + * + * Most of the interface methods are implemented with just dummy + * implementations, as they are not needed in this example. + */ + public class MyContainer implements Container { + Item[] items; + int current = 0; + + public MyContainer() { + items = new Item[100]; // Yeah this is just a test } + + public boolean addContainerProperty(Object propertyId, Class type, + Object defaultValue) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public Item addItem(Object itemId) throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public Object addItem() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + /** + * This addItem method is specific for this container and allows adding + * BeanItem objects. The BeanItems must be bound to MyBean objects. + */ + public void addItem(BeanItem item) throws UnsupportedOperationException { + items[current++] = item; + } + + public boolean containsId(Object itemId) { + if (itemId instanceof Integer) { + int pos = ((Integer)itemId).intValue(); + if (pos >= 0 && pos < 100) + return items[pos] != null; + } + return false; + } + + /** + * The Table will call this method to get the property objects for the + * columns. It uses the property objects to determine the data types of + * the columns. + */ + public Property getContainerProperty(Object itemId, Object propertyId) { + if (itemId instanceof Integer) { + int pos = ((Integer)itemId).intValue(); + if (pos >= 0 && pos < 100) { + Item item = items[pos]; + + // The BeanItem provides the property objects for the items. + return item.getItemProperty(propertyId); + } + } + return null; + } + + /** Table calls this to get the column names. */ + public Collection getContainerPropertyIds() { + // This container can contain only BeanItems bound to MyBeans. + Item item = new BeanItem(new MyBean()); + + // The BeanItem knows how to get the property names from the bean. + return item.getItemPropertyIds(); + } + + public Item getItem(Object itemId) { + if (itemId instanceof Integer) { + int pos = ((Integer)itemId).intValue(); + if (pos >= 0 && pos < 100) + return items[pos]; + } + return null; + } + + public Collection getItemIds() { + Vector ids = new Vector(); + for (int i=0; i<100; i++) + ids.add(Integer.valueOf(i)); + return ids; + } + + public Class getType(Object propertyId) { + return BeanItem.class; + } + + public boolean removeAllItems() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public boolean removeContainerProperty(Object propertyId) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public boolean removeItem(Object itemId) + throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + public int size() { + return current; + } + } TableEditableBean() { @@ -77,19 +198,28 @@ public class TableEditableBean extends CustomComponent { layout.addComponent(table); table.setPageLength(8); - // Define the names and data types of columns. - table.addContainerProperty("selected", Boolean.class, null); - table.addContainerProperty("text", String.class, null); + // Use the custom container as the data source + MyContainer myContainer = new MyContainer(); + table.setContainerDataSource(myContainer); // Add a few items in the table. for (int i=0; i<5; i++) { + // Create the bean MyBean item = new MyBean(); + item.setText("MyBean " + i); + + // Have an Item that is bound to the bean BeanItem bitem = new BeanItem(item); - //table.addItem(bitem); - table.addItem(new Object[]{bitem,bitem}, new Integer(i)); + + // Add the item directly to the container using the custom addItem() + // method. We could otherwise add it to the Table as well, but + // the Container interface of Table does not allow adding items + // as such, just item IDs. + myContainer.addItem(bitem); } // Use custom field factory that sets the checkboxes in immediate mode. + // This is just for debugging purposes and is not normally necessary. table.setFieldFactory(new MyFieldFactory()); // Have a check box to switch the table between normal and editable mode. -- 2.39.5