JSF支持4种事件
- 值更改事件
- 动作事件
- 阶段事件
- 系统事件(JSF2.0起支持)
当组件的值发生改变时,由包含可编辑值的组件触发值更改事件,主要包括h:inputText、h:selectOneRadio、h:selectManyMenu等
当激活按钮或链接时,动作源会触发动作事件,主要有h:commandButton、h:commandLink
从应用请求值阶段开始,JSF实现会创建事件并在每个生命周期阶段期间将其添加到事件队列中。在这些阶段后,JSF实现向已注册的监听器广播队列事件
事件监听器通过下列三种方式影响JSF生命周期
- 让生命周期正常进行
- 调用FacesContext类的RenderResponse方法以忽略生命周期的其他部分,直接跳转到呈现响应阶段
- 调用FacesContext的 responseComplete方法以忽略生命周期的其他阶段
值更改事件
<h:body>
<h:form>
<span class="emphasis">#{msgs.pageTitle}</span>
<h:panelGrid columns="2">
#{msgs.streetAddressPrompt}
<h:inputText value="#{form.streetAddress}"/>
#{msgs.cityPrompt}
<h:inputText value="#{form.city}"/>
#{msgs.statePrompt}
<h:inputText value="#{form.state}"/>
#{msgs.countryPrompt}
<h:selectOneMenu value="#{form.country}" onchange="submit()"
valueChangeListener="#{form.countryChanged}">
<f:selectItems value="#{form.countries}" var="loc"
itemLabel="#{loc.displayCountry}" itemValue="#{loc.country}"/>
</h:selectOneMenu>
</h:panelGrid>
<h:commandButton value="#{msgs.submit}"/>
</h:form>
</h:body>
@ManagedBean(name="form")
@SessionScoped
public class RegisterForm {
private String streetAddress;
private String city;
private String state;
private String country;
private static final Locale[] countries = { Locale.US, Locale.CANADA,Locale.CHINA };
public Locale[] getCountries() { return countries; }
public void setStreetAddress(String newValue) { streetAddress = newValue; }
public String getStreetAddress() { return streetAddress; }
public void setCity(String newValue) { city = newValue; }
public String getCity() { return city; }
public void setState(String newValue) { state = newValue; }
public String getState() { return state; }
public void setCountry(String newValue) { country = newValue; }
public String getCountry() { return country; }
public void countryChanged(ValueChangeEvent event) {
for (Locale loc : countries)
if (loc.getCountry().equals(event.getNewValue()))
FacesContext.getCurrentInstance().getViewRoot().setLocale(loc);
}
}
动作事件
按钮和链接触发动作事件,在接近生命结束处的“调用应用程序”阶段,触发动作事件
@ManagedBean
@SessionScoped
public class Rushmore {
private String outcome = null;
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 handleMouseClick(ActionEvent e) {
FacesContext context = FacesContext.getCurrentInstance();
String clientId = e.getComponent().getClientId(context);
Map<String, String> 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";
}
public String navigate() {
return outcome;
}
}
index.xhtml
<h:body>
<span class="instructions">#{msgs.instructions}</span>
<h:form>
<h:commandButton image="/resources/images/mountrushmore.jpg"
styleClass="imageButton"
actionListener="#{rushmore.handleMouseClick}"
action="#{rushmore.navigate}"/>
</h:form>
</h:body>
jefferson.xhtml
<h:head>
<h:outputStylesheet library="css" name="styles.css"/>
<title>${msgs.jeffersonWindowTitle}</title>
</h:head>
<h:body>
<h:form>
<span class="presidentPageTitle">#{msgs.jeffersonPageTitle}</span>
<br/>
<h:graphicImage library="images"
name="jefferson.jpg" styleClass="leftImage"/>
<span class="presidentDiscussion">#{msgs.jeffersonDiscussion}</span>
<br/>
<h:commandLink action="index"
styleClass="backLink">${msgs.indexLinkText}</h:commandLink>
</h:form>
</h:body>
事件监听器标签
f:actionListener
f:valueChangeListener