About Me

My photo
Ernakulam, Kerala, India
I am Sajadh, author of this blog. I run this with loads of passion.
If you are into java, you may find lot of interesting things around ...
Advance thanks for your queries to sajadhaja90@gmail.com.

Thursday, 14 February 2013

JSF1.x Sample application -2 [ Controller ]

                                                                                                                    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.

1. Create JSF Project

Create a new Dynamic Web Project "de.vogella.jsf.card".

2. Domain model

Create a new package de.vogella.jsf.card.model and the following class.

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;
  }
  
} 

3. Controller

Create the following class CardController.

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.

4. Register your managed beans- Dependency injection

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".

<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> 

5. Resource bundle for messages

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 

6. JavaServer Page with JSF components

Create a new JSP page "Trainer.jsp" and change the code to the following:

<%@ 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.

7. Run your webapplication

To run your webapplication, select Trainer.jsp, right mouse-click- >run as -> run on server.


                                                                                             NEXT EXAMPLE

No comments:

Post a Comment

You can enter queries here...