Action Events Action events are fired by command components buttons, links, etc. when the component is activated. As we saw in "Life Cycle Events" on page 268, action events are fired during the Invoke Application phase, near the end of the life cycle. You typically attach action listeners to command components in JSP. For example, you can add an action listener to a link, like this: <h:commandLink actionListener="#{bean.linkActivated}"> ... </h:commandLink> Command components submit requests when they are activated, so there is no need to use onchange to force form submits as we did with value change events in "Value Change Events" on page 269. When you activate a command or link, the surrounding form is submitted and the JSF implementation subsequently fires action events. It is important to distinguish between action listeners and actions. In a nutshell, actions are designed for business logic and participate in navigation handling, whereas action listeners typically perform user interface logic and do not participate in navigation handling. Action listeners sometimes work in concert with actions when an action needs information about the user interface. For example, the application shown in Figure 7-4 uses an action and an action listener to react to mouse clicks by forwarding to a JSP page. If you click on a president's face, the application forwards to a JSF page with information about that president. Note that an action alone cannot implement that behavior an action can navigate to the appropriate page, but it cannot determine the appropriate page because it knows nothing about the image button in the user interface or the mouse click. The application shown in Figure 7-4 uses a button with an image, like this: <h:commandButton image="mountrushmore.jpg" actionListener="#{rushmore.listen}" action="#{rushmore.act}"/> When you click a president, a listener which has access to the mouse click coordinates determines which president was selected. But the listener cannot affect navigation, so it stores an outcome corresponding to the selected president in an instance field: public class Rushmore { private String outcome; private Rectangle washingtonRect = new Rectangle(70,30,40,40); private Rectangle jeffersonRect = new Rectangle(115,45,40,40); private Rectangle rooseveltRect = new Rectangle(135,65,40,40); private Rectangle lincolnRect = new Rectangle(175,62,40,40); public void listen(ActionEvent e) { FacesContext context = FacesContext.getCurrentInstance(); String clientId = e.getComponent().getClientId(context); Map requestParams = context.getExternalContext(). getRequestParameterMap(); int x = new Integer((String) requestParams.get(clientId + ".x")).intValue(); int y = new Integer((String) requestParams.get(clientId + ".y")).intValue(); outcome = null; if (washingtonRect.contains(new Point(x,y))) outcome = "washington"; if (jeffersonRect.contains(new Point(x,y))) outcome = "jefferson"; if (rooseveltRect.contains(new Point(x,y))) outcome = "roosevelt"; if (lincolnRect.contains(new Point(x,y))) outcome = "lincoln"; } } The action associated with the button uses the outcome to affect navigation: public String act() { return outcome; } Note that the JSF implementation always invokes action listeners before actions. Note | JSF insists that you separate user interface logic and business logic by refusing to give actions access to events or the components that fire them. In the preceding example, the action cannot access the client ID of the component that fired the event, information that is necessary for extraction of mouse coordinates from the request parameters. Because the action knows nothing about the user interface, we must add an action listener to the mix to implement the required behavior. | The directory structure for the application shown in Figure 7-4 is shown in Figure 7-5. The application is shown in Listing 7-6 through Listing 7-13. Listing 7-6. rushmore/web/index.jsp 1. <html> 2. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 3. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 4. <f:view> 5. <head> 6. <link href="styles.css" rel="stylesheet" type="text/css"/> 7. <title> 8. <h:outputText value="#{msgs.indexWindowTitle}"/> 9. </title> 10. </head> 11. 12. <body> 13. <h:outputText value="#{msgs.instructions}" 14. style/> 15. <h:form> 16. <h:commandButton image="mountrushmore.jpg" 17. style 18. actionListener="#{rushmore.handleMouseClick}" 19. action="#{rushmore.navigate}"/> 20. </h:form> 21. </body> 22. </f:view> 23. </html>
| Listing 7-7. rushmore/web/lincoln.jsp 1. <<html> 2. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 3. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 4. <f:view> 5. <head> 6. <link href="styles.css" rel="stylesheet" type="text/css"/> 7. <title> 8. <h:outputText value="#{msgs.lincolnWindowTitle}"/> 9. </title> 10. </head> 11. 12. <body> 13. <h:form> 14. <h:outputText value="#{msgs.lincolnPageTitle}" 15. style/> 16. <p/> 17. <h:outputText value="#{msgs.lincolnDiscussion}" 18. style/> 19. <p> 20. <h:commandLink action="index" 21. style> 22. ${msgs.indexLinkText} 23. </h:commandLink> 24. </p> 25. </h:form> 26. </body> 27. </f:view> 28. </html>
| Listing 7-8. rushmore/web/jefferson.jsp 1. <html> 2. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 3. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 4. <f:view> 5. <head> 6. <link href="styles.css" rel="stylesheet" type="text/css"/> 7. <title>${msgs.jeffersonWindowTitle}</title> 8. </head> 9. 10. <body> 11. <h:form> 12. <h:outputText value="#{msgs.jeffersonPageTitle}" 13. style/> 14. <p/> 15. <h:outputText value="#{msgs.jeffersonDiscussion}" 16. style/> 17. <p> 18. <h:commandLink action="index" 19. style> 20. ${msgs.indexLinkText} 21. </h:commandLink> 22. </p> 23. </h:form> 24. </body> 25. </f:view> 26. </html>
| Listing 7-9. rushmore/web/roosevelt.jsp 1. <html> 2. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 3. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 4. <f:view> 5. <head> 6. <link href="styles.css" rel="stylesheet" type="text/css"/> 7. <title> 8. <h:outputText value="#{msgs.rooseveltWindowTitle}"/> 9. </title> 10. </head> 11. 12. <body> 13. <h:form> 14. <h:outputText value="#{msgs.rooseveltPageTitle}" 15. style/> 16. <p/> 17. <h:outputText value="#{msgs.rooseveltDiscussion}" 18. style/> 19. <p> 20. <h:commandLink action="index" 21. style> 22. ${msgs.indexLinkText} 23. </h:commandLink> 24. </p> 25. </h:form> 26. </body> 27. </f:view> 28. </html>
| Listing 7-10. rushmore/web/washington.jsp 1. <html> 2. <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> 3. <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> 4. <f:view> 5. <head> 6. <link href="styles.css" rel="stylesheet" type="text/css"/> 7. <title> 8. <h:outputText value="#{msgs.washingtonWindowTitle}"/> 9. </title> 10. </head> 11. 12. <body> 13. <h:form> 14. <h:outputText value="#{msgs.washingtonPageTitle}" 15. style/> 16. <p/> 17. <h:outputText value="#{msgs.washingtonDiscussion}" 18. style/> 19. <p> 20. <h:commandLink action="index" 21. style> 22. ${msgs.indexLinkText} 23. </h:commandLink> 24. </p> 25. </h:form> 26. </body> 27. </f:view> 28. </html>
| Listing 7-11. rushmore/src/java/com/corejsf/Rushmore.java 1. package com.corejsf; 2. 3. import java.awt.Point; 4. import java.awt.Rectangle; 5. import java.util.Map; 6. import javax.faces.context.FacesContext; 7. import javax.faces.event.ActionEvent; 8. 9. public class Rushmore { 10. private String outcome = null; 11. private Rectangle washingtonRect = new Rectangle(70, 30, 40, 40); 12. private Rectangle jeffersonRect = new Rectangle(115, 45, 40, 40); 13. private Rectangle rooseveltRect = new Rectangle(135, 65, 40, 40); 14. private Rectangle lincolnRect = new Rectangle(175, 62, 40, 40); 15. 16. public void handleMouseClick(ActionEvent e) { 17. FacesContext context = FacesContext.getCurrentInstance(); 18. String clientId = e.getComponent().getClientId(context); 19. Map requestParams = context.getExternalContext().getRequestParameterMap(); 20. 21. int x = new Integer((String) requestParams.get(clientId + ".x")) 22. .intValue(); 23. int y = new Integer((String) requestParams.get(clientId + ".y")) 24. .intValue(); 25. 26. outcome = null; 27. 28. if (washingtonRect.contains(new Point(x, y))) 29. outcome = "washington"; 30. 31. if (jeffersonRect.contains(new Point(x, y))) 32. outcome = "jefferson"; 33. 34. if (rooseveltRect.contains(new Point(x, y))) 35. outcome = "roosevelt"; 36. 37. if (lincolnRect.contains(new Point(x, y))) 38. outcome = "lincoln"; 39. } 40. 41. public String navigate() { 42. return outcome; 43. } 44. }
| Listing 7-12. rushmore/web/WEB-INF/faces-config.xml 1. <?xml version="1.0"?> 2. <faces-config xmlns="http://java.sun.com/xml/ns/javaee" 3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 5. http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd" 6. version="1.2"> 7. <application> 8. <resource-bundle> 9. <base-name>com.corejsf.messages</base-name> 10. <var>msgs</var> 11. </resource-bundle> 12. </application> 13. 14. <navigation-rule> 15. <navigation-case> 16. <from-outcome>index</from-outcome> 17. <to-view-id>/index.jsp</to-view-id> 18. </navigation-case> 19. </navigation-rule> 20. 21. <navigation-rule> 22. <from-view-id>/index.jsp</from-view-id> 23. <navigation-case> 24. <from-outcome>washington</from-outcome> 25. <to-view-id>/washington.jsp</to-view-id> 26. </navigation-case> 27. <navigation-case> 28. <from-outcome>jefferson</from-outcome> 29. <to-view-id>/jefferson.jsp</to-view-id> 30. </navigation-case> 31. <navigation-case> 32. <from-outcome>roosevelt</from-outcome> 33. <to-view-id>/roosevelt.jsp</to-view-id> 34. </navigation-case> 35. <navigation-case> 36. <from-outcome>lincoln</from-outcome> 37. <to-view-id>/lincoln.jsp</to-view-id> 38. </navigation-case> 39. </navigation-rule> 40. 41. <managed-bean> 42. <managed-bean-name>rushmore</managed-bean-name> 43. <managed-bean-class>com.corejsf.Rushmore</managed-bean-class> 44. <managed-bean-scope>session</managed-bean-scope> 45. </managed-bean> 46. 47. </faces-config>
| Listing 7-13. rushmore/src/java/com/corejsf/messages.properties 1. instructions=For information about a president, click on the president's face. 2. 3. indexWindowTitle=Actions and Action Listeners 4. indexLinkText=Back... 5. jeffersonWindowTitle=President Jefferson 6. rooseveltWindowTitle=President Roosevelt 7. lincolnWindowTitle=President Lincoln 8. washingtonWindowTitle=President Washington 9. 10. jeffersonPageTitle=Thomas Jefferson 11. rooseveltPageTitle=Theodore Roosevelt 12. lincolnPageTitle=Abraham Lincoln 13. washingtonPageTitle=George Washington 14. 15. jeffersonTabText=Jefferson 16. rooseveltTabText=Roosevelt 17. lincolnTabText=Lincoln 18. washingtonTabText=Washington 19. 20. lincolnDiscussion=President Lincoln was known as the Great Emancipator because \ 21. he was instrumental in abolishing slavery in the United States. He was born \ 22. into a poor family in Kentucky in 1809, elected president in 1860, and \ 23. assassinated by John Wilkes Booth in 1865. 24. 25. washingtonDiscussion=George Washington was the first president of the United \ 26. States. He was born in 1732 in Virginia, was elected Commander in Chief of \ 27. the Continental Army in 1775, and forced the surrender of Cornwallis at Yorktown \ 28. in 1781. He was inaugurated on April 30, 1789. 29. 30. rooseveltDiscussion=Theodore Roosevelt was the 26th president of the United \ 31. States. In 1901 he became president after the assassination of President \ 32. McKinley. At only 42, he was the youngest president in U.S. history. 33. 34. jeffersonDiscussion=Thomas Jefferson, the 3rd U.S. president, was born in \ 35. 1743 in Virginia. Jefferson was tall and awkward, and was not known as a \ 36. great public speaker. Jefferson became minister to France in 1785, after \ 37. Benjamin Franklin held that post. In 1796, Jefferson was a reluctant \ 38. presidential candiate, and missed winning the election by a mere three votes. \ 39. He served as president from 1801 to 1809.
| |