0. Introduction
Medium and large application (management applications that use many entities) can follow a Domain Driven Design.
I like this approach as I think that integrates with object-oriented paradigm. Each entity is defined by its properties (attributes) and its interaction with the rest (methods).
If we can survey into an entity to see its definition (attributes and methods) we can create some visual prototypes with controls to edit its properties with buttons (or equivalent components) to execute its methods.
The main idea is considering an object like a set of attributes and methods. Exploring this set may enable us to build dynamically this prototype. The most important thing is that all windows look like very similar and so, training process gets simple. Once you see how to use a window, the rest of the windows are siblings.
So our prototype should be able to add components to the window dynamically using information from the attributes (type, validation restrictions etc) and the methods (parameters, result, etc.)
The main tools are supplied by Java (Reflection, Bean Validation, etc) but we also need that JSF enables us to add components programmatically at run-time.
1. Creating a JSF component using Java
There are mainly 2 ways of creating a JSF component
1. Using new Component(). For instance to create a HtmlInputText:
HtmlInputText txtControl2= new HtmlInputText();
2. Using FacesContext.getCurrentInstance().getApplication().createComponent().
The last one is mainly recommended.
1. Using new Component(). For instance to create a HtmlInputText:
HtmlInputText txtControl2= new HtmlInputText();
2. Using FacesContext.getCurrentInstance().getApplication().createComponent().
HtmlInputText txtControl2= =(HtmlInputText) FacesContext.getCurrentInstance().getApplication().createComponent(HtmlInputText.COMPONENT_TYPE);
The last one is mainly recommended.
2. Binding a JSF container component in a facelets file
Let's create a bean that has a form attribute. We need a @Postconstruct init method (line 27) to create the formDynamicBeanExample.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package org.ximodante.jsf.dynamic; import java.io.Serializable; import javax.annotation.PostConstruct; import javax.faces.component.html.HtmlForm; /******************************************************** * CAREFUL USE: import javax.faces.view.ViewScoped * DO NOT USE: import javax.bean.view.ViewScoped ********************************************************/ import javax.faces.view.ViewScoped; import javax.inject.Named; import lombok.Getter; import lombok.Setter; @Named @ViewScoped public class DynamicBeanExample implements Serializable { private static final long serialVersionUID = 1L; @Getter @Setter private HtmlForm myForm; @PostConstruct public void init() { myForm = new HtmlForm(); } } |
Note Lombok getter and setter annotations!
Now our facelet file is
dynamic01.xhtml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui"> <h:head> </h:head> <h:body> <h:form binding="#{dynamicBeanExample.myForm}"> Hello..... </h:form> </h:body> </html> |
Note in line 11 how the form is bound to the form created in the bean.
3. Adding JSF child components to a container.
The getChildren() method return a list of the nested components of a container. Adding a created component is as easy as using add method of a List.1 2 3 4 | HtmlOutputLabel lbl=new HtmlOutputLabel(); lbl.setValue("This is a Label"); myForm.getChildren().add(lbl); |
This code can be merged to the init method of the bean (DynamicBeanExample.java) to add a label to the form.
Now we have got a super simple and useless form. But it is a good example for educational purposes only!
No hay comentarios:
Publicar un comentario