今天谈谈自定义JSF的component,renderer,用到官方例子Image Map Example,这个可以在Oracle官方网站下载。

这个步骤是(来自官方网站):

JavaEE 8学习之Custom Component , Renderer

 

创建一个自定义的component class, 所有的component必须要继承UIComponentBase,但是如果我们只需要一个特定的功能,没有必要直接继承UIComponentBase,我们可以继承比如UICommand,所有的都在javax.faces.component里面,UI开头的。

 

@FacesComponent("DemoMap")
public class MapComponent extends UICommand {...}
@FacesComponent("DemoArea")
public class AreaComponent extends UIOutput {...}

 

上面这两行代码就是说创建一个自定义的按钮component 和Output的component,FaceComponent的意思就是告诉JSF,我现在报名了,我有个新的component叫做DemoMap和DemoArea。

DemoMap有一个或者多个DemoArea当作子component,所以这个时候这个父DemoMap要做的就是:

1. 接收子component 当前被选中的值

2. 用这些值赋给对应的父component的properties

3. 当用户点击map的时候生成一个event

4. 保存这个event的状态

5.渲染html,比如html 的html的map tag,input tag 。 MapComponent会把渲染交给Render去做

现在谈谈AreaComponent, 这个是和一个bean绑定的,这个component可以从bean里面得到形状的值,把这个值放在hidden的id里面,Rendering the area tag, including the JavaScript for the onmouseoveronmouseout, and onclick functions。,需要delegate给render去做render的task。

Delegate给render,component class需要重写 这个方法

public String getFamily() {
    return ("Map");
}

然后再render的class里就可以这样写

@FacesRenderer(componentFamily = "Map", rendererType = "DemoMap")
public class MapRenderer extends Renderer {}

下面谈一下怎么写render,这个比较复杂一点。

@Override
public void encodeBegin(FacesContext context, UIComponent component)
        throws IOException {
    if ((context == null)|| (component == null)) {
        throw new NullPointerException();
    }
    MapComponent map = (MapComponent) component;
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement("map", map);
    writer.writeAttribute("name", map.getId(), "id");
}

@Override
public void encodeEnd(FacesContext context, UIComponent component)
        throws IOException {
    if ((context == null) || (component == null)){
        throw new NullPointerException();
    }
    MapComponent map = (MapComponent) component;
    ResponseWriter writer = context.getResponseWriter();
    writer.startElement("input", map);
    writer.writeAttribute("type", "hidden", null);
    writer.writeAttribute("name", getName(context,map), "clientId");
    writer.endElement("input");
    writer.endElement("map");
}

上面这部分代码就是要渲染

<map name="bookMap">

       <input type="hidden" name="bookMap_current">
</map>

最后就是要decode,把那个隐藏html的值拿到后传回给map的component的attribute “current”注意

@Override
public void decode(FacesContext context, UIComponent component) {
    if ((context == null) || (component == null)) {
        throw new NullPointerException();
    }
    MapComponent map = (MapComponent) component;
    String key = getName(context, map);
    String value = (String) context.getExternalContext().
            getRequestParameterMap().get(key);
    if (value != null)
        map.setCurrent(value);
    }
}

注意这一句

If the component has child components, you might need to use more than one of these methods to render the component; otherwise, all rendering should be done in encodeEnd. Alternatively, you can use the encodeALL method, which encompasses all the methods.

所以,因为AreaRender没有子render,只需要一个encodeEnd就好了

 @Override
    public void encodeEnd(FacesContext context, UIComponent component)
            throws IOException {
        if ((context == null) || (component == null)) {
            throw new NullPointerException();
        }

        AreaComponent area = (AreaComponent) component;
        String targetImageId = area.findComponent(
                area.getTargetImage()).getClientId(context);
        ImageArea iarea = (ImageArea) area.getValue();
        ResponseWriter writer = context.getResponseWriter();
        StringBuilder sb;

        writer.startElement("area", area);
        writer.writeAttribute("alt", iarea.getAlt(), "alt");
        writer.writeAttribute("coords", iarea.getCoords(), "coords");
        writer.writeAttribute("shape", iarea.getShape(), "shape");
        sb = new StringBuilder("document.forms[0]['").append(targetImageId).
                append("'].src='");
        sb.append(
                getURI(context,
                (String) area.getAttributes().get("onmouseout")));
        sb.append("'");
        writer.writeAttribute("onmouseout", sb.toString(), "onmouseout");
        sb = new StringBuilder("document.forms[0]['").append(targetImageId).
                append("'].src='");
        sb.append(
                getURI(context,
                (String) area.getAttributes().get("onmouseover")));
        sb.append("'");
        writer.writeAttribute("onmouseover", sb.toString(), "onmouseover");
        sb = new StringBuilder("document.forms[0]['");
        sb.append(getName(context, area));
        sb.append("'].value='");
        sb.append(iarea.getAlt());
        sb.append("'; document.forms[0].submit()");
        writer.writeAttribute("onclick", sb.toString(), "value");
        writer.endElement("area");
    }

 

相关文章:

  • 2021-10-07
  • 2021-11-07
  • 2021-06-21
  • 2021-07-20
  • 2021-11-17
  • 2021-07-20
  • 2021-08-31
  • 2021-07-15
猜你喜欢
  • 2021-09-10
  • 2021-08-26
  • 2021-11-16
  • 2021-05-30
  • 2021-05-08
  • 2022-02-17
  • 2021-06-21
相关资源
相似解决方案