1.三种事件:
阶段事情,生命周期事情
值变化事件
动作事件
2JSF生命周期(包含6个阶段)
重建视图->应用请求值->处理事件(直接事件)->处理验证->处理事件(值事件)->
呈现响应<-处理事件(动作事件)<-调用应用程序<-处理事件<-更新模型值
3值变化事件 valueChangeListener
例:根据下拉选项来重构视图
<h:selectOneMenu value="#{newsBean.news.typeId}" οnchange="submit()"
valueChangeListener="#{newsBean.typeChanged}" immediate="true">
<f:selectItems value="#{newsBean.typeNames}"/>
</h:selectOneMenu>
事件javax.faces.event.ValueChangeEvent
public void typeChanged(ValueChangeEvent event)
{
FacesContext context=FacesContext.getCurrentInstance();
if(("中国").equals((String)event.getNewValue()))
{
//如果选择的是国内,就显示省市
}
else
{
//显示州
//context.getViewRoot().setLocale(Locale.US);//显示美国的视图
}
context.renderResponse();
}
4动作事件
动作之前调用动作监听器
事件:javax.faces.event.ActionEvent;
<h:commandButton image="face.jpg" actionListener="#{newsBean.handleMouseClick}" action="#{newsBean.navigate}" immediate="true">
</h:commandButton>
private String outcome=null;
private Rectangle firstRect=new Rectangle(70,30,40,40);
private Rectangle secondRect=new Rectangle(115,45,40,40);
public void handMouseClick(ActionEvent e){
FacesContext context= FacesContext.getCurrentInstance();
String clientId=e.getComponent().getClientId(context);
Map requestParams=context.getExternalContext().getRequestParameterMap();
int x=Integer.parseInt((String)requestParams.get(clientId+".x"));
int y=Integer.parseInt((String)requestParams.get(clientId+".y"));
outcome=null;
if(firstRect.contains(new Point(x,y)))
{
outcome="firstPage"; //如果点击第一个矩形中的点,就跳转到第一个页面
}
if(secondRect.contains(new Point(x,y)))
{
outcome="secondtPage";//如果点击第二个矩形中的点,就跳转到第二个页面
}
}
public String navigate()
{
return outcome;
}
5事件监听器标签 (这个标签比直接写到组件中的好处就是:一个组件可以同时有多个 监听器)
但标签监听器是在属性指定的监听器后面被调用
1)
<h:selectOneMenu value="#{newsBean.news.typeId}" οnchange="submit()" immediate="true">
<f:valueChangeListener type="com.pp.TypeListner"/>
<f:selectItems value="#{newsBean.typeNames}"/>
</h:selectOneMenu>
自定义的事件监听器必须继承ValueChangeListener
import java.util.Locale;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.event.ValueChangeListener;
public class TypeListner implements ValueChangeListener{
public void processValueChange(ValueChangeEvent event) {
FacesContext context= FacesContext.getCurrentInstance();
if("中国".equals((String)event.getNewValue())){
context.getViewRoot().setLocale(Locale.CHINA);
} else{ //... }}
context.renderResponse();
}
2) <h:commandButton image="face.jpg" action="#{newsBean.navigate}" immediate="true">
<f:actionListener type="com.pp.NewsListener"/>
</h:commandButton>
import javax.faces.event.ActionEvent;
import javax.faces.event.ActionListener;
public class NewsListener implements ActionListener {
private String outcome=null;
private Rectangle firstRect=new Rectangle(70,30,40,40);
private Rectangle secondRect=new Rectangle(115,45,40,40);
public void processAction(ActionEvent event) {
FacesContext context= FacesContext.getCurrentInstance();
String clientId=event.getComponent().getClientId(context);
Map requestParams=context.getExternalContext().getRequestParameterMap();
int x=Integer.parseInt((String)requestParams.get(clientId+".x"));
int y=Integer.parseInt((String)requestParams.get(clientId+".y"));
outcome=null;
if(firstRect.contains(new Point(x,y)))
{
outcome="firstPage"; //如果点击第一个矩形中的点,就跳转到第一个页面
}
if(secondRect.contains(new Point(x,y)))
{
outcome="secondtPage";//如果点击第二个矩形中的点,就跳转到第二个页面
}
}
6直接组件
直接事件在应用请求值阶段之后激发
但我们想跳过其他组件的验证。
值事件要两点:
1) immediate="true"
2) context.renderResponse();
动作事件直接写 immediate="true"因为所有动作,直接或间接的,不管它们什么时候触发,
都直接进入呈现响应阶段。
7**从UI到服务器传递数据
有三个方法
1)f:param
此标签能将一个参数添加到组件
<h:commandButton action="#{newsBean.viewNews}">
<f:param value="china" name="typeCode" />
</h:commandButton>
FacesContext context= FacesContext.getCurrentInstance();
Map<String,String > params=context.getExternalContext().getRequestParameterMap();
String typeCode=params.get("typeCode");
2)f:setPropertyActionListener
<h:commandButton action="#{newsBean.view}">
<f:setPropertyActionListener target="#{newsBean.typeCode}" value="china"/>
</h:commandButton>
是属性可直接用
private String typeCode;
3)f:attribute
<h:commandButton actionListener="#{newsBean.change}">
<f:attribute value="china" name="typeCode" />
</h:commandButton>
public void Change(ActionEvent event)
{
UIComponent component= event.getComponent();
Map<String,Object> attrs=component.getAttributes();
String typeCode=(String)attrs.get("typeCode");
//...
}
8阶段事件 可用于调试,略。。。。
知识补充:
javax.faces.event.FacesEvent
javax.faces.context.FacesContext
java.util.Locale
java.util.Map
java.awt.Rectangle
contains(int x, int y)
检查此 Rectangle 是否包含指定位置的点(x,y)。
java.awt.Point new Point(x,y)