JSF核心编程之7 JSF事件处理


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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值