NEXT EXAMPLE
We will now extend the example from the previous chapter to a math trainer. The system will propose two number and the user must multiply both values and input the result.
This JSF application will use a controller which handles the JSF logic. This will allow you to create a domain model without application logic.
Tip
In general it is considered as a good design practice to keep the model independently from the application logic.This example will also demonstrate the usage of dependency injection in JSF.
2. Domain model
package de.vogella.jsf.card.model; import java.util.Random; public class Card { private int left; private int right; public Card() { Random random = new Random(); int i = 0; int j = 0; do { i = random.nextInt(10); } while (i <= 4); do { j = random.nextInt(100); } while (j <= 20); left = i; right = j; } public int getLeft() { return left; } public void setLeft(int left) { this.left = left; } public int getRight() { return right; } public void setRight(int right) { this.right = right; } }
Create the following class CardController.
This class has a field resultPanel. This field will later get connected to a UIComponent (panel) from the JSP.
package de.vogella.jsf.card.controller; import javax.faces.application.FacesMessage; import javax.faces.component.UIPanel; import javax.faces.context.FacesContext; import de.vogella.jsf.card.model.Card; public class CardController { private Card card; private UIPanel resultPanel; private int result; public CardController() { } public String checkResult() { FacesContext context = FacesContext.getCurrentInstance(); resultPanel.setRendered(true); if (checkOperation()) { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Correct", null)); } else { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Incorrect", null)); } return null; } private boolean checkOperation() { return (card.getLeft() * card.getRight() == result); } public UIPanel getResultPanel() { return resultPanel; } public void setResultPanel(UIPanel resultPanel) { this.resultPanel = resultPanel; } public int getResult() { return result; } public void setResult(int result) { this.result = result; } public String next() { FacesContext context = FacesContext.getCurrentInstance(); if (checkOperation()){ resultPanel.setRendered(false); card = new Card(); return null; } else { context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Incorrect", null)); } return null; } public Card getCard() { return card; } public void setCard(Card card) { this.card = card; } }
This class has a field resultPanel. This field will later get connected to a UIComponent (panel) from the JSP.
Double-click on faces-config.xml and select the tab
"ManagedBeans". Register the classes "CardController" and "Card" as
managed beans. The scope of card will be set to none as it will be
inserted into the ControllerCard via dependency injection. In the
initialization tab maintain the data as displayed in the screenshot.
The value #{card} refers to the managed bean "card".
The generated XML code should look like the following (you see this if you select the tab "Source".
![](http://www.vogella.com/articles/JavaServerFaces/images/controller10.gif)
The generated XML code should look like the following (you see this if you select the tab "Source".
<managed-bean> <managed-bean-name>cardController</managed-bean-name> <managed-bean-class>de.vogella.jsf.card.controller.CardController</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>card</property-name> <property-class>de.vogella.jsf.card.model.Card</property-class> <value>#{card}</value> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>card</managed-bean-name> <managed-bean-class>de.vogella.jsf.card.model.Card</managed-bean-class> <managed-bean-scope>none</managed-bean-scope> </managed-bean>
Create the following file "messages.properties" in your source
folder under the package "de.vogella.jsf.card".
left=Left Side right=Right Side result=Result show= Check next= Next
Create a new JSP page "Trainer.jsp" and change the code to the
following:
From the previously examples you should be able to read most of the fields. What is new is that is use now the binding. Binding allows to bind certain UIControls to a managed bean. This way be bind the panel for the result to the controller. The controller can then set the rendered attribute of this UIControl depending on the user settings.
To run your webapplication, select Trainer.jsp, right
mouse-click- >run as -> run on server.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="f" uri="http://java.sun.com/jsf/core"%> <%@ taglib prefix="h" uri="http://java.sun.com/jsf/html"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body> <h1> Train your Brain</h1> <h3>Please calculate the result </h3> <f:view> <f:loadBundle basename="de.vogella.jsf.card.messages" var="msg" /> <h:form> <h:panelGrid columns="3"> <h:panelGrid columns="2"> <h:outputLabel value="#{msg.left}"></h:outputLabel> <h:outputLabel id="left" value="#{cardController.card.left}"></h:outputLabel> <h:outputLabel value="#{msg.right}"></h:outputLabel> <h:outputLabel id="right" value="#{cardController.card.right}"> </h:outputLabel> <h:outputLabel value="#{msg.result}"></h:outputLabel> <h:inputText id="result" value="#{cardController.result}"></h:inputText> </h:panelGrid> </h:panelGrid> <h:commandButton action="#{cardController.checkResult}" value="#{msg.show}"></h:commandButton> <h:commandButton action="#{cardController.next}" value="#{msg.next}" type="submit"></h:commandButton> <h:messages layout="table"></h:messages> <h:panelGroup binding="#{cardController.resultPanel}" rendered="false"> <h:message for="result"></h:message> </h:panelGroup> </h:form> </f:view> </body> </html>
From the previously examples you should be able to read most of the fields. What is new is that is use now the binding. Binding allows to bind certain UIControls to a managed bean. This way be bind the panel for the result to the controller. The controller can then set the rendered attribute of this UIControl depending on the user settings.
No comments:
Post a Comment
You can enter queries here...