This chapter describes the default
visualizations for domain objects.
6.1) Simple Data Types
The following basic data types are
supported by this framework and are visualized as follows:
Click the date sample to show the
date picker. Try changing some values to see the default
validations in action (leave focus to apply change):
- primitive types are not null validated
- numbers and chars are validated by range limits
- fractional digits are only allowed on appropriate number
types
- dates have to be in correct format
- enum literals are validated against value manipulation
Currently there is no out of the box support for java.time,
joda-time or any other
custom type library for dates or numbers. This is because there is
a simple workaround, just convert between the types in your
getters/setters if you want a field of an unsupported type. You can
still externalize the original type via @Hidden methods for your
internal coding needs. Just make sure to convert to a supported
type for the framework or completely handle the binding yourself
with a BindingInterceptor and custom components.
By default the framework displays
all properties of a class which have a public getter method
defined. If there is also a public setter method defined, the
displayed field is editable, otherwise it is read-only. You could
also provide public fields (which is the same as a getter and a
setter combined), even though this is rather unusual when following
the JavaBeans pattern.
Every field is preceded by a label with a text that is derived from
the property name. CamelCase
syntax causes a whitespace splitting (e.g.
getNumberOfChildren()
is displayed as "Number Of Children"). These labels were explicitly
removed from the above samples.
6.2) Collections & Arrays
If the property is a collection/array of a simple data type, it is
always mapped to a
select
tag. This will show it as a combo box. You can set a
size
attribute to convert it to a list as done below (the lists are
disabled because the properties do not have a setter). But what we
are going for here are tables, not lists or combo boxes.
So to do it correct, you have to use the proper types. Arrays and
collections for complex data types are by default mapped to tables.
The table contains one row for each element of the
collection/array. To achieve a detailed visualization of domain
objects from a collection, the collection should be typed using
Java generics. Otherwise the framework can only display "the least
common denominator" which is
toString()
for all contained objects. The table displays only the data of the
contained type. As a consequence, if the collection also contains
objects of derived types, the additional properties of these types
are not displayed (e.g. a collection of vehicles contains cars and
bikes with additional properties, but the generic type is of car.
Thus the table displays only the properties of the vehicle base
class). Also note that tables only allow shallow columns to be
displayed, everything else is displayed as
toString()
. You see this below in the
nested
column that contains
column3
in a structured type.
If you want to see a more realistic table example, please open the
Ajax Data Table example
from the Wicket Examples Rebuilt item in the top menu.
6.3) Structured Data Types
Domain objects may be structured by
one class referencing another class. The related objects are in
this case displayed within the UI of the referencing object. To
separate the fields from each other, the fields for referenced
objects are displayed under a separation line with the name of the
reference as a caption.
The following example shows a more
comprehensive model for a car. The motor with its methods for
turning it off and on are implemented in a separate class. There is
a number of additional attributes with different data types now.
All trips which have been made with that car are associated by an
array.
public class Car implements Serializable {
private String licenseNumber;
private CarBrand brand;
private long kmMileage;
private BigDecimal purchasePrice;
private boolean technicalControl;
private Date registrationDate;
private Trip[] tripBook;
private Motor motor;
// constructor, getters/setters omitted here
}
public class Motor implements Serializable {
private int powerInHP;
private MotorState state;
// constructor, getters/setters omitted here
public void turnOn() { this.state = MotorState.on; }
public void turnOff() { this.state = MotorState.off; }
}
public class Trip implements Serializable {
private String from;
private String to;
private int distanceInKM;
// constructor, getters/setters omitted here
}
This results in the following
panel:
This looks better than the previous
examples, but it allows logically incorrect input values. To fix
this, the next chapter explains how to add validations.