diff options
Diffstat (limited to 'documentation/datamodel/datamodel-container.asciidoc')
-rw-r--r-- | documentation/datamodel/datamodel-container.asciidoc | 834 |
1 files changed, 0 insertions, 834 deletions
diff --git a/documentation/datamodel/datamodel-container.asciidoc b/documentation/datamodel/datamodel-container.asciidoc deleted file mode 100644 index 8f88e7c8bf..0000000000 --- a/documentation/datamodel/datamodel-container.asciidoc +++ /dev/null @@ -1,834 +0,0 @@ ---- -title: Collecting Items in Containers -order: 5 -layout: page ---- - -[[datamodel.container]] -= Collecting Items in Containers - -((("[classname]#Container#", id="term.datamodel.container", range="startofrange"))) - - -The [classname]#Container# interface is the highest containment level of the -Vaadin data model, for containing items (rows) which in turn contain properties -(columns). Containers can therefore represent tabular data, which can be viewed -in a [classname]#Table# or some other selection component, as well as -hierarchical data. - -The items contained in a container are identified by an __item identifier__ or -__IID__, and the properties by a __property identifier__ or __PID__. - -[[datamodel.container.intro]] -== Basic Use of Containers - -The basic use of containers involves creating one, adding items to it, and -binding it as a container data source of a component. - -[[datamodel.container.intro.default]] -=== Default Containers and Delegation - -Before saying anything about creation of containers, it should be noted that all -components that can be bound to a container data source are by default bound to -a default container. For example, [classname]#Table# is bound to a -[classname]#IndexedContainer#, [classname]#Tree# to a -[classname]#HierarchicalContainer#, and so forth. - -All of the user interface components using containers also implement the -relevant container interfaces themselves, so that the access to the underlying -data source is delegated through the component. - - ----- -// Create a table with one column -Table table = new Table("My Table"); -table.addContainerProperty("col1", String.class, null); - -// Access items and properties through the component -table.addItem("row1"); // Create item by explicit ID -Item item1 = table.getItem("row1"); -Property property1 = item1.getItemProperty("col1"); -property1.setValue("some given value"); - -// Equivalent access through the container -Container container = table.getContainerDataSource(); -container.addItem("row2"); -Item item2 = container.getItem("row2"); -Property property2 = item2.getItemProperty("col1"); -property2.setValue("another given value"); ----- - - -[[datamodel.container.intro.creating]] -=== Creating and Binding a Container - -A container is created and bound to a component as follows: - - ----- -// Create a container of some type -Container container = new IndexedContainer(); - -// Initialize the container as required by the container type -container.addContainerProperty("name", String.class, "none"); -container.addContainerProperty("volume", Double.class, 0.0); - -... add items ... - -// Bind it to a component -Table table = new Table("My Table"); -table.setContainerDataSource(container); ----- - -Most components that can be bound to a container allow passing it also in the -constructor, in addition to using [methodname]#setContainerDataSource()#. -Creation of the container depends on its type. For some containers, such as the -[classname]#IndexedContainer#, you need to define the contained properties -(columns) as was done above, while some others determine them otherwise. The -definition of a property with [methodname]#addContainerProperty()# requires a -unique property ID, type, and a default value. You can also give -[parameter]#null#. - -Vaadin has a several built-in in-memory container implementations, such as -[classname]#IndexedContainer# and [classname]#BeanItemContainer#, which are easy -to use for setting up nonpersistent data storages. For persistent data, either -the built-in [classname]#SQLContainer# or the [classname]#JPAContainer# add-on -container can be used. - - -[[datamodel.container.intro.adding]] -=== Adding Items and Accessing Properties - -Items can be added to a container with the [methodname]#addItem()# method. The -parameterless version of the method automatically generates the item ID. - - ----- -// Create an item -Object itemId = container.addItem(); ----- - -Properties can be requested from container by first requesting an item with -[methodname]#getItem()# and then getting the properties from the item with -[methodname]#getItemProperty()#. - - ----- -// Get the item object -Item item = container.getItem(itemId); - -// Access a property in the item -Property<String> nameProperty = - item.getItemProperty("name"); - -// Do something with the property -nameProperty.setValue("box"); ----- - -You can also get a property directly by the item and property ids with -[methodname]#getContainerProperty()#. - - ----- -container.getContainerProperty(itemId, "volume").setValue(5.0); ----- - - -[[datamodel.container.intro.givenid]] -=== Adding Items by Given ID - -Some containers, such as [classname]#IndexedContainer# and -[classname]#HierarchicalContainer#, allow adding items by a given ID, which can -be any [classname]#Object#. - - ----- -Item item = container.addItem("agivenid"); -item.getItemProperty("name").setValue("barrel"); -Item.getItemProperty("volume").setValue(119.2); ----- - -Notice that the actual item __is not__ given as a parameter to the method, only -its ID, as the interface assumes that the container itself creates all the items -it contains. Some container implementations can provide methods to add -externally created items, and they can even assume that the item ID object is -also the item itself. Lazy containers might not create the item immediately, but -lazily when it is accessed by its ID. - - - -[[datamodel.container.inner]] -== Container Subinterfaces - -The [classname]#Container# interface contains inner interfaces that container -implementations can implement to fulfill different features required by -components that present container data. - -[interfacename]#Container.Filterable#:: Filterable containers allow filtering the contained items by filters, as -described in <<datamodel.container.filtered>>. - -[interfacename]#Container.Hierarchical#:: Hierarchical containers allow representing hierarchical relationships between -items and are required by the [classname]#Tree# and [classname]#TreeTable# -components. The [classname]#HierarchicalContainer# is a built-in in-memory -container for hierarchical data, and is used as the default container for the -tree components. The [classname]#FilesystemContainer# provides access to -browsing the content of a file system. Also [classname]#JPAContainer# is -hierarchical, as described in -<<dummy/../../../framework/jpacontainer/jpacontainer-usage#jpacontainer.usage.hierarchical,"Hierarchical -Container">>. - -[interfacename]#Container.Indexed#:: An indexed container allows accessing items by an index number, not just their -item ID. This feature is required by some components, especially -[classname]#Table#, which needs to provide lazy access to large containers. The -[classname]#IndexedContainer# is a basic in-memory implementation, as described -in <<datamodel.container.indexedcontainer>>. - -[interfacename]#Container.Ordered#:: An ordered container allows traversing the items in successive order in either -direction. Most built-in containers are ordered. - -[interfacename]#Container.SimpleFilterable#:: This interface enables filtering a container by string matching with -[methodname]#addContainerFilter()#. The filtering is done by either searching -the given string anywhere in a property value, or as its prefix. - -[interfacename]#Container.Sortable#:: A sortable container is required by some components that allow sorting the -content, such as [classname]#Table#, where the user can click a column header to -sort the table by the column. Some other components, such as -[classname]#Calendar#, may require that the content is sorted to be able to -display it properly. Depending on the implementation, sorting can be done only -when the [methodname]#sort()# method is called, or the container is -automatically kept in order according to the last call of the method. - - - -See the API documentation for a detailed description of the interfaces. - - -[[datamodel.container.indexedcontainer]] -== [classname]#IndexedContainer# - -The [classname]#IndexedContainer# is an in-memory container that implements the -[interfacename]#Indexed# interface to allow referencing the items by an index. -[classname]#IndexedContainer# is used as the default container in most selection -components in Vaadin. - -The properties need to be defined with [methodname]#addContainerProperty()#, -which takes the property ID, type, and a default value. This must be done before -any items are added to the container. - - ----- -// Create the container -IndexedContainer container = new IndexedContainer(); - -// Define the properties (columns) -container.addContainerProperty("name", String.class, "noname"); -container.addContainerProperty("volume", Double.class, -1.0d); - -// Add some items -Object content[][] = { {"jar", 2.0}, {"bottle", 0.75}, - {"can", 1.5}}; -for (Object[] row: content) { - Item newItem = container.getItem(container.addItem()); - newItem.getItemProperty("name").setValue(row[0]); - newItem.getItemProperty("volume").setValue(row[1]); -} ----- - -New items are added with [methodname]#addItem()#, which returns the item ID of -the new item, or by giving the item ID as a parameter as was described earlier. -Note that the [classname]#Table# component, which has -[classname]#IndexedContainer# as its default container, has a conveniency -[methodname]#addItem()# method that allows adding items as object vectors -containing the property values. - -The container implements the [interfacename]#Container.Indexed# feature to allow -accessing the item IDs by their index number, with [methodname]#getIdByIndex()#, -etc. The feature is required mainly for internal purposes of some components, -such as [classname]#Table#, which uses it to enable lazy transmission of table -data to the client-side. - - -[[datamodel.container.beancontainer]] -== [classname]#BeanContainer# - -The [classname]#BeanContainer# is an in-memory container for JavaBean objects. -Each contained bean is wrapped inside a [classname]#BeanItem# wrapper. The item -properties are determined automatically by inspecting the getter and setter -methods of the class. This requires that the bean class has public visibility, -local classes for example are not allowed. Only beans of the same type can be -added to the container. - -The generic has two parameters: a bean type and an item identifier type. The -item identifiers can be obtained by defining a custom resolver, using a specific -item property for the IDs, or by giving item IDs explicitly. As such, it is more -general than the [classname]#BeanItemContainer#, which uses the bean object -itself as the item identifier, making the use usually simpler. Managing the item -IDs makes [classname]#BeanContainer# more complex to use, but it is necessary in -some cases where the [methodname]#equals()# or [methodname]#hashCode()# methods -have been reimplemented in the bean. - - ----- -// Here is a JavaBean -public class Bean implements Serializable { - String name; - double energy; // Energy content in kJ/100g - - public Bean(String name, double energy) { - this.name = name; - this.energy = energy; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public double getEnergy() { - return energy; - } - - public void setEnergy(double energy) { - this.energy = energy; - } -} - -void basic(VerticalLayout layout) { - // Create a container for such beans with - // strings as item IDs. - BeanContainer<String, Bean> beans = - new BeanContainer<String, Bean>(Bean.class); - - // Use the name property as the item ID of the bean - beans.setBeanIdProperty("name"); - - // Add some beans to it - beans.addBean(new Bean("Mung bean", 1452.0)); - beans.addBean(new Bean("Chickpea", 686.0)); - beans.addBean(new Bean("Lentil", 1477.0)); - beans.addBean(new Bean("Common bean", 129.0)); - beans.addBean(new Bean("Soybean", 1866.0)); - - // Bind a table to it - Table table = new Table("Beans of All Sorts", beans); - layout.addComponent(table); -} ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beancontainer.basic[on-line example, window="_blank"]. - -To use explicit item IDs, use the methods [methodname]#addItem(Object, Object)#, -[methodname]#addItemAfter(Object, Object, Object)#, and -[methodname]#addItemAt(int, Object, Object)#. - -It is not possible to add additional properties to the container, except -properties in a nested bean. - -[[datamodel.container.beancontainer.nestedproperties]] -=== Nested Properties - -((("nested bean properties", id="term.datamodel.container.beancontainer.nestedproperties", range="startofrange"))) - - -If you have a nested bean with an 1:1 relationship inside a bean type contained -in a [classname]#BeanContainer# or [classname]#BeanItemContainer#, you can add -its properties to the container by specifying them with -[methodname]#addNestedContainerProperty()#. The feature is defined at the level -of [classname]#AbstractBeanContainer#. -((("[methodname]#addNestedContainerProperty()#"))) - -As with the bean in a bean container, also a nested bean must have public -visibility or otherwise an access exception is thrown. An intermediate reference -from a bean in the bean container to a nested bean may have a null value. - -For example, let us assume that we have the following two beans with the first -one nested inside the second one. - - ----- -/** Bean to be nested */ -public class EqCoord implements Serializable { - double rightAscension; /* In angle hours */ - double declination; /* In degrees */ - - ... setters and getters for the properties ... -} - -/** Bean referencing a nested bean */ -public class Star implements Serializable { - String name; - EqCoord equatorial; /* Nested bean */ - - ... setters and getters for the properties ... -} ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.nestedbean[on-line example, window="_blank"]. - -After creating the container, you can declare the nested properties by -specifying their property identifiers with the -[methodname]#addNestedContainerProperty()# in dot notation. - - ----- -// Create a container for beans -BeanItemContainer<Star> stars = - new BeanItemContainer<Star>(Star.class); - -// Declare the nested properties to be used in the container -stars.addNestedContainerProperty("equatorial.rightAscension"); -stars.addNestedContainerProperty("equatorial.declination"); - -// Add some items -stars.addBean(new Star("Sirius", new EqCoord(6.75, 16.71611))); -stars.addBean(new Star("Polaris", new EqCoord(2.52, 89.26417))); - -// Here the nested bean reference is null -stars.addBean(new Star("Vega", null)); ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.nestedbean[on-line example, window="_blank"]. - -If you bind such a container to a [classname]#Table#, you probably also need to -set the column headers. Notice that the entire nested bean itself is still a -property in the container and would be displayed in its own column. The -[methodname]#toString()# method is used for obtaining the displayed value, which -is by default an object reference. You normally do not want this, so you can -hide the column with [methodname]#setVisibleColumns()#. -((("[methodname]#setVisibleColumns()#"))) - - ----- -// Put them in a table -Table table = new Table("Stars", stars); -table.setColumnHeader("equatorial.rightAscension", "RA"); -table.setColumnHeader("equatorial.declination", "Decl"); -table.setPageLength(table.size()); - -// Have to set explicitly to hide the "equatorial" property -table.setVisibleColumns("name", - "equatorial.rightAscension", "equatorial.declination"); ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.nestedbean[on-line example, window="_blank"]. - -The resulting table is shown in -<<figure.datamodel.container.beancontainer.nestedproperties>>. - -[[figure.datamodel.container.beancontainer.nestedproperties]] -.[classname]#Table# Bound to a [classname]#BeanContainer# with Nested Properties -image::img/beanitemcontainer-nested-beans.png[] - -The bean binding in [classname]#AbstractBeanContainer# normally uses the -[classname]#MethodProperty# implementation of the [classname]#Property# -interface to access the bean properties using the setter and getter methods. For -nested properties, the [classname]#NestedMethodProperty# implementation is used. -((("[classname]#MethodProperty#"))) -((("[classname]#NestedMethodProperty#"))) - -(((range="endofrange", startref="term.datamodel.container.beancontainer.nestedproperties"))) - -ifdef::web[] -[[datamodel.container.beancontainer.idresolver]] -=== Defining a Bean ID Resolver - -If a bean ID resolver is set using [methodname]#setBeanIdResolver()# or -[methodname]#setBeanIdProperty()#, the methods [methodname]#addBean()#, -[methodname]#addBeanAfter()#, [methodname]#addBeanAt()# and -[methodname]#addAll()# can be used to add items to the container. If one of -these methods is called, the resolver is used to generate an identifier for the -item (must not return [parameter]#null#). - -Note that explicit item identifiers can also be used when a resolver has been -set by calling the [methodname]#addItem*()# methods - the resolver is only used -when adding beans using the [methodname]#addBean*()# or -[methodname]#addAll(Collection)# methods. - -endif::web[] - - -[[datamodel.container.beanitemcontainer]] -== [classname]#BeanItemContainer# - -[classname]#BeanItemContainer# is a container for JavaBean objects where each -bean is wrapped inside a [classname]#BeanItem# wrapper. The item properties are -determined automatically by inspecting the getter and setter methods of the -class. This requires that the bean class has public visibility, local classes -for example are not allowed. Only beans of the same type can be added to the -container. - -[classname]#BeanItemContainer# is a specialized version of the -[classname]#BeanContainer# described in <<datamodel.container.beancontainer>>. -It uses the bean itself as the item identifier, which makes it a bit easier to -use than [classname]#BeanContainer# in many cases. The latter is, however, -needed if the bean has reimplemented the [methodname]#equals()# or -[methodname]#hashCode()# methods. - -Let us revisit the example given in <<datamodel.container.beancontainer>> using -the [classname]#BeanItemContainer#. - - ----- -// Create a container for the beans -BeanItemContainer<Bean> beans = - new BeanItemContainer<Bean>(Bean.class); - -// Add some beans to it -beans.addBean(new Bean("Mung bean", 1452.0)); -beans.addBean(new Bean("Chickpea", 686.0)); -beans.addBean(new Bean("Lentil", 1477.0)); -beans.addBean(new Bean("Common bean", 129.0)); -beans.addBean(new Bean("Soybean", 1866.0)); - -// Bind a table to it -Table table = new Table("Beans of All Sorts", beans); ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.beanitemcontainer.basic[on-line example, window="_blank"]. - -It is not possible to add additional properties to a -[classname]#BeanItemContainer#, except properties in a nested bean, as described -in <<datamodel.container.beancontainer>>. ((("nested bean -properties"))) - - -ifdef::web[] -[[datamodel.container.iterating]] -== Iterating Over a Container - -As the items in a [classname]#Container# are not necessarily indexed, iterating -over the items has to be done using an [classname]#Iterator#. The -[methodname]#getItemIds()# method of [classname]#Container# returns a -[classname]#Collection# of item identifiers over which you can iterate. The -following example demonstrates a typical case where you iterate over the values -of check boxes in a column of a [classname]#Table# component. The context of the -example is the example used in -<<dummy/../../../framework/components/components-table#components.table,"Table">>. - - ----- -// Collect the results of the iteration into this string. -String items = ""; - -// Iterate over the item identifiers of the table. -for (Iterator i = table.getItemIds().iterator(); i.hasNext();) { - // Get the current item identifier, which is an integer. - int iid = (Integer) i.next(); - - // Now get the actual item from the table. - Item item = table.getItem(iid); - - // And now we can get to the actual checkbox object. - Button button = (Button) - (item.getItemProperty("ismember").getValue()); - - // If the checkbox is selected. - if ((Boolean)button.getValue() == true) { - // Do something with the selected item; collect the - // first names in a string. - items += item.getItemProperty("First Name") - .getValue() + " "; - } -} - -// Do something with the results; display the selected items. -layout.addComponent (new Label("Selected items: " + items)); ----- - -Notice that the [methodname]#getItemIds()# returns an __unmodifiable -collection__, so the [classname]#Container# may not be modified during -iteration. You can not, for example, remove items from the -[classname]#Container# during iteration. The modification includes modification -in another thread. If the [classname]#Container# is modified during iteration, a -[classname]#ConcurrentModificationException# is thrown and the iterator may be -left in an undefined state. - -endif::web[] - -[[datamodel.container.gpc]] -== [classname]#GeneratedPropertyContainer# - -[classname]#GeneratedPropertyContainer# is a container wrapper that allows -defining generated values for properties (columns). The generated properties can -shadow properties with the same IDs in the wrapped container. Removing a -property from the wrapper hides it. - -The container is especially useful with [classname]#Grid#, which does not -support generated columns or hiding columns like [classname]#Table# does. - -[[datamodel.container.gpc.wrapping]] -=== Wrapping a Container - -A container to be wrapped must be a [interfacename]#Container.Indexed#. It can -optionally also implement [interfacename]#Container.Sortable# or -[interfacename]#Container.Filterable# to enable sorting and filtering the -container, respectively. - -For example, let us consider the following container with some regular columns: - - ----- -IndexedContainer container = new IndexedContainer(); -container.addContainerProperty("firstname", String.class, null); -container.addContainerProperty("lastname", String.class, null); -container.addContainerProperty("born", Integer.class, null); -container.addContainerProperty("died", Integer.class, null); - -// Wrap it -GeneratedPropertyContainer gpcontainer = - new GeneratedPropertyContainer(container); ----- - - -[[datamodel.container.gpc.properties]] -=== Generated Properties - -Now, you can add generated properties in the container with -[methodname]#addGeneratedProperty()# by specifying a property ID and a -[interfacename]#PropertyValueGenerator#. The method takes the ID of the -generated property as first parameter; you can use a same ID as in the wrapped -container to shadow its properties. - -You need to implement [methodname]#getType()#, which must return the class -object of the value type of the property, and [methodname]#getValue()#, which -returns the property value for the given item. The item ID and the property ID -of the generated property are also given in case they are needed. You can access -other properties of the item to compute the property value. - - ----- -gpcontainer.addGeneratedProperty("lived", - new PropertyValueGenerator<Integer>() { - @Override - public Integer getValue(Item item, Object itemId, - Object propertyId) { - int born = (Integer) - item.getItemProperty("born").getValue(); - int died = (Integer) - item.getItemProperty("died").getValue(); - return Integer.valueOf(died - born); - } - - @Override - public Class<Integer> getType() { - return Integer.class; - } -}); ----- - -You can access other items in the container, also their generated properties, -although you should beware of accidental recursion. - - -[[datamodel.container.gpc.using]] -=== Using [classname]#GeneratedPropertyContainer# - -Finally, you need to bind the [classname]#GeneratedPropertyContainer# to the -component instead of the wrapped container. - - ----- -Grid grid = new Grid(gpcontainer); ----- - -When using [classname]#GeneratedPropertyContainer# in [classname]#Grid#, notice -that generated columns are read-only, so you can not add grid rows with -[methodname]#addRow()#. In editable mode, editor fields are not generated for -generated columns. - - -[[datamodel.container.gpc.sorting]] -=== Sorting - -Even though the [classname]#GeneratedPropertyContainer# implements -[interfacename]#Container.Sortable#, the wrapped container must also support it -or otherwise sorting is disabled. Also, the generated properties are not -normally sortable, but require special handling to enable sorting. - - - -[[datamodel.container.filtered]] -== [classname]#Filterable# Containers - -((("Container", "Filterable", id="term.datamodel.container.filtered.filterable", range="startofrange"))) - - -((("[classname]#Filter# (in [classname]#Container#)", id="term.datamodel.container.filtered.filters", range="startofrange"))) - - -Containers that implement the [classname]#Container.Filterable# interface can be -filtered. For example, the built-in [classname]#IndexedContainer# and the bean -item containers implement it. Filtering is typically used for filtering the -content of a [classname]#Table#. -((("[classname]#IndexedContainer#"))) -((("[classname]#Table#"))) - -Filters implement the [classname]#Filter# interface and you add them to a -filterable container with the [methodname]#addContainerFilter()# method. -Container items that pass the filter condition are kept and shown in the -filterable component. -((("[methodname]#addContainerFilter()#"))) - - ----- -Filter filter = new SimpleStringFilter("name", - "Douglas", true, false); -table.addContainerFilter(filter); ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.basic[on-line example, window="_blank"]. - -If multiple filters are added to a container, they are evaluated using the -logical AND operator so that only items that are passed by all the filters are -kept. - -[[datamodel.container.filtered.composite]] -=== Atomic and Composite Filters - -Filters can be classified as __atomic__ and __composite__. Atomic filters, such -as [classname]#SimpleStringFilter#, define a single condition, usually for a -specific container property. Composite filters make filtering decisions based on -the result of one or more other filters. The built-in composite filters -implement the logical operators AND, OR, or NOT. - -For example, the following composite filter would filter out items where the -[literal]#++name++# property contains the name "Douglas" somewhere __or__ where -the [literal]#++age++# property has value less than 42. The properties must have -[classname]#String# and [classname]#Integer# types, respectively. - - ----- - -filter = new Or(new SimpleStringFilter("name", - "Douglas", true, false), - new Compare.Less("age", 42)); ----- - - -[[datamodel.container.filtered.builtin]] -=== Built-In Filter Types - -The built-in filter types are the following: - -[classname]#SimpleStringFilter#:: ((("[classname]#SimpleStringFilter#"))) -+ -Passes items where the specified property, that must be of [classname]#String# -type, contains the given [parameter]#filterString# as a substring. If -[parameter]#ignoreCase# is [parameter]#true#, the search is case insensitive. If -the [parameter]#onlyMatchPrefix# is [parameter]#true#, the substring may only be -in the beginning of the string, otherwise it may be elsewhere as well. - -[classname]#IsNull#:: ((("[classname]#IsNull# (filter)"))) -+ -Passes items where the specified property has null value. For in-memory -filtering, a simple [literal]#++==++# check is performed. For other containers, -the comparison implementation is container dependent, but should correspond to -the in-memory null check. - -[classname]#Equal#,[classname]#Greater#, - [classname]#Less#, - [classname]#GreaterOrEqual#, and[classname]#LessOrEqual#:: ((("[classname]#Equal# (filter)"))) -((("[classname]#Greater# (filter)"))) -((("[classname]#Less# (filter)"))) -((("[classname]#GreaterOrEqual# (filter)"))) -((("[classname]#LessOrEqual# (filter)"))) -+ -The comparison filter implementations compare the specified property value to -the given constant and pass items for which the comparison result is true. The -comparison operators are included in the abstract [classname]#Compare# class. - -+ -For the [classname]#Equal# filter, the [methodname]#equals()# method for the -property is used in built-in in-memory containers. In other types of containers, -the comparison is container dependent and may use, for example, database -comparison operations. - -+ -For the other filters, the property value type must implement the -[classname]#Comparable# interface to work with the built-in in-memory -containers. Again for the other types of containers, the comparison is container -dependent. - -[classname]#And#and[classname]#Or#:: ((("[classname]#And# (filter)"))) -((("[classname]#Or# (filter)"))) -+ -These logical operator filters are composite filters that combine multiple other -filters. - -[classname]#Not#:: ((("[classname]#Not# (filter)"))) -+ -The logical unary operator filter negates which items are passed by the filter -given as the parameter. - - - - -[[datamodel.container.filtered.custom]] -=== Implementing Custom Filters - -A custom filter needs to implement the [classname]#Container.Filter# interface. - -A filter can use a single or multiple properties for the filtering logic. The -properties used by the filter must be returned with the -[methodname]#appliesToProperty()# method. If the filter applies to a -user-defined property or properties, it is customary to give the properties as -the first argument for the constructor of the filter. - - ----- -class MyCustomFilter implements Container.Filter { - protected String propertyId; - protected String regex; - - public MyCustomFilter(String propertyId, String regex) { - this.propertyId = propertyId; - this.regex = regex; - } - - /** Tells if this filter works on the given property. */ - @Override - public boolean appliesToProperty(Object propertyId) { - return propertyId != null && - propertyId.equals(this.propertyId); - } ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.custom[on-line example, window="_blank"]. - -The actual filtering logic is done in the [methodname]#passesFilter()# method, -which simply returns [literal]#++true++# if the item should pass the filter and -[literal]#++false++# if it should be filtered out. - - ----- - /** Apply the filter on an item to check if it passes. */ - @Override - public boolean passesFilter(Object itemId, Item item) - throws UnsupportedOperationException { - // Acquire the relevant property from the item object - Property p = item.getItemProperty(propertyId); - - // Should always check validity - if (p == null || !p.getType().equals(String.class)) - return false; - String value = (String) p.getValue(); - - // The actual filter logic - return value.matches(regex); - } -} ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.custom[on-line example, window="_blank"]. - -You can use such a custom filter just like any other: - - ----- -c.addContainerFilter( - new MyCustomFilter("Name", (String) tf.getValue())); ----- -See the http://demo.vaadin.com/book-examples-vaadin7/book#datamodel.container.filter.custom[on-line example, window="_blank"]. - - -(((range="endofrange", startref="term.datamodel.container.filtered.filters"))) -(((range="endofrange", startref="term.datamodel.container.filtered.filterable"))) - -(((range="endofrange", startref="term.datamodel.container"))) - - |