上一篇结合Struts2实现了分页的自定义标签。标签比较简单,3个参数,单一的显示样式。下面对该标签的功能进行进一步的扩充,主要包括:

1.可以为标签指定样式。通过styleClass属性,可以为标签指定一个样式表。

2.增加了分页样式的选择。通过theme属性指定分页样式。

theme="text"的样式:

theme="number"的样式:

修改方案:

1.在tld文件中增加这两个属性的声明:

<attribute>
                <name>styleClass</name>
                <required>false</required>
                <rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
                <name>theme</name>
                <required>false</required>
                <rtexprvalue>true</rtexprvalue>
</attribute>

 2.在自定义标签类中分别增加styleClass和theme属性,并提供setter方法:

   PageTag.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.tangs.tag;

import com.opensymphony.xwork2.util.ValueStack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.components.Component;
import org.apache.struts2.views.jsp.ComponentTagSupport;

/**
 * 分页标签
 * @author tangs
 */
public class PageTag extends ComponentTagSupport {
    private String cpage;
    private String total;
    private String url;
    private String styleClass;   //新增的样式属性
    private String theme;   //新增的分页样式属性
    
    public void setTheme(String theme) {
        this.theme = theme;
    }
    
    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    public void setCpage(String cpage) {
        this.cpage = cpage;
    }

    public void setTotal(String total) {
        this.total = total;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public Component getBean(ValueStack arg0, HttpServletRequest arg1, HttpServletResponse arg2) {
        return new Pages(arg0, arg1);
    }

    protected void populateParams() {
        super.populateParams();
        
        Pages pages = (Pages)component;
        pages.setCpage(cpage);
        pages.setTotal(total);
        pages.setUrl(url);
        pages.setStyleClass(styleClass);
        pages.setTheme(theme);

    }
}

   Pages.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.tangs.tag;

import com.opensymphony.xwork2.util.ValueStack;
import java.io.IOException;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.components.Component;

/**
 * 分页逻辑Bean
 * @author tangs
 */
public class Pages extends Component {
    private HttpServletRequest request;
    private String cpage;
    private String total;
    private String url;
    private String styleClass;
    private String theme;
    
    public String getTheme() {
        return theme;
    }

    public void setTheme(String theme) {
        this.theme = theme;
    }
    
    
    public String getStyleClass() {
        return styleClass;
    }

    public void setStyleClass(String styleClass) {
        this.styleClass = styleClass;
    }

    
    public String getCpage() {
        return cpage;
    }

    public void setCpage(String cpage) {
        this.cpage = cpage;
    }

    public String getTotal() {
        return total;
    }

    public void setTotal(String total) {
        this.total = total;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
    
    
    public Pages(ValueStack arg0, HttpServletRequest request) {
        super(arg0);
        this.request = request;
    }

    @Override
    public boolean start(Writer writer) {
        boolean result = super.start(writer);
        try {
            StringBuilder str = new StringBuilder();
            boolean isValid = true;
            
            //从ValueStack中取出数值
            if (isValid) {
                if (total.startsWith("%{") && total.endsWith("}")) {
                    total = total.substring(2, total.length() -1);
                    total = (String)this.getStack().findValue(total);
                    isValid = total == null ? false : true;
                } else {
                    isValid = false;
                }
            }
            if (isValid) {
                if (cpage.startsWith("%{") && cpage.endsWith("}")) {
                    cpage = cpage.substring(2, cpage.length() - 1);
                    cpage = (String)this.getStack().findValue(cpage);
                    isValid = cpage == null ? false : true;
                } else {
                    isValid = false;
                }
            }
            if (isValid) {
                if (url.startsWith("%{") && url.endsWith("}")) {
                    url = url.substring(2, url.length() - 1);
                    url = (String)this.getStack().findValue(url);
                    isValid = url == null ? false : true;
                } else {
                    isValid = false;
                }
            }

            if (isValid) {
                Integer cpageInt = Integer.valueOf(cpage);
                str.append("<span ");
                if (styleClass != null) {
                    str.append(" class='"+styleClass+"'>");
                } else {
                    str.append(">");
                }
                
                //文本样式
                if (theme == null || "text".equals(theme)) {  //theme="text"样式
                    //当前页与总页数相等
                    if (cpage.equals(total)) {
                        //如果total = 1,则无需分页,显示“[第1页] [共1页]”
                        if ("1".equals(total)) {
                            str.append("[第 " + cpage + " 页]");
                            str.append(" [共 " + total + " 页]");
                        } else {
                            //到达最后一页,显示“[首页] [上一页] [末页]”
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=1&total="+total+"&url="+url);
                            str.append("'>[首页]</a> <a href='");
                            str.append(url);
                            str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url);
                            str.append("'>[上一页]</a> <a href='");
                            str.append(url);
                            str.append("?cpage=" + total + "&total=" + total+"&url="+url);
                            str.append("'>[末页]</a>");
                        }
                    } else {
                        //当前页与总页数不相同
                        if ("1".equals(cpage)) {
                            //第一页,显示“[首页] [下一页] [末页]”
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=1&total="+total+"&url="+url);
                            str.append("'>[首页]</a> <a href='");
                            str.append(url);
                            str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url);
                            str.append("'>[下一页]</a> <a href='");
                            str.append(url);
                            str.append("?cpage=" + total + "&total=" + total+"&url="+url);
                            str.append("'>[末页]</a>");
                        } else {
                            //不是第一页,显示“[首页] [上一页] [下一页] [末页]”
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=1&total="+total+"&url="+url);
                            str.append("'>[首页]</a> <a href='");
                            str.append(url);
                            str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url);
                            str.append("'>[上一页]</a> <a href='");
                            str.append(url);
                            str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url);
                            str.append("'>[下一页]</a> <a href='");
                            str.append(url);
                            str.append("?cpage=" + total + "&total=" + total+"&url="+url);
                            str.append("'>[末页]</a>");
                        }
                    }
                } else if ("number".equals(theme)) {  //theme="number"的数字样式 [1 2 3 4 5 6 7 8 9 10 > >>]
                    Integer totalInt = Integer.valueOf(total);
                   
                    //如果只有一页,则无需分页
                    str.append("[ ");
                    if (totalInt == 1) {
                        str.append("<strong>1</strong> ");
                    } else {
                        //计算一共分几组
                        int group = (totalInt - 1) / 10 + 1;
                        //当前第几组
                        int cgroup = (cpageInt - 1) / 10 + 1;
                        
                        if (cgroup > 1) {
                            //当前不是第一组,要显示“<< <”
                            //<<:返回前一组第一页
                            //<:返回前一页
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=" + ((cgroup - 2) * 10 + 1 ) + "&total=" + total+"&url="+url);
                            str.append("'>«</a> " );
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=" + (cpageInt - 1) + "&total=" + total+"&url="+url);
                            str.append("'>‹</a> " );
                        }
                        //10个为一组显示
                        for (int i = (cgroup - 1) * 10 + 1; i <= totalInt && i <= cgroup * 10; i++) {
                            if (cpageInt == i) { //当前页要加粗显示
                                str.append("<strong>");  
                            }
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=" + i + "&total=" + total+"&url="+url);
                            str.append("'>" + i + "</a> ");
                            if (cpageInt == i) {
                                str.append("</strong>");
                            }
                        }
                        //如果多于1组并且不是最后一组,显示“> >>”
                        if (group > 1&& cgroup != group) {
                            //>>:返回下一组最后一页
                            //>:返回下一页
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=" + (cpageInt + 1) + "&total=" + total+"&url="+url);
                            str.append("'>›</a> " );
                            str.append("<a href='");
                            str.append(url);
                            str.append("?cpage=" + ((cgroup * 10 + 10) > totalInt ? totalInt : (cgroup * 10 + 10)) + "&total=" + total+"&url="+url);
                            str.append("'>»</a> " );
                        }
                    }
                    str.append("]");
                }
                str.append("</span>");
            }
         
            writer.write(str.toString());
            
        } catch (IOException ex) {
            Logger.getLogger(Pages.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }
}

 3.在页面中使用标签

<tangs:pages cpage="%{cpage}" total="%{total}" url="%{url}" styleClass="page" theme="number"/>

 指定了styleClass和theme属性,得到的分页样式:

 

  • TagTest.rar (20.4 KB)
  • 描述: 标签源代码
  • 下载次数: 140
评论
tangshuo 2008-07-14
我这有个很奇怪的问题,刚打开页面时,数据都对的,包括:总页数,当前页数,上下页显示都对,但我单击“下一页”,页面上只显示了“共页第页”,页数都没了,也没有“上页,下页”。 我debug了下,total和cpage都为空值,哎!不知道哪有问题,页面上有值,数据就是传不到后台,

弄了一天了, 也没出结果。

麻烦你帮帮忙,很希望能得到你的答复!

谢谢了!!!!
---------------------------------------------------------------------------
如果你这个点击下一页是跳转到一个action类的某个方法中处理的话,你应该在在该action中声明cpage,total,等等这些变量作为Action的属性,这样在请求过去的时候,这些值就会被自动封装到里面(Struts2)。你可以看一下代码,这些值都是从valueStack中取出的。
caixian_2008 2008-07-11
我这有个很奇怪的问题,刚打开页面时,数据都对的,包括:总页数,当前页数,上下页显示都对,但我单击“下一页”,页面上只显示了“共页 第页”,页数都没了,也没有“上页,下页”。 我debug了下,total和cpage都为空值,哎! 不知道哪有问题,页面上有值,数据就是传不到后台,

弄了一天了, 也没出结果。

麻烦你帮帮忙,很希望能得到你的答复!

谢谢了!!!!
okjacky 2008-06-18
tangshuo你好,
1.我想问下你的标签中的url属性表示什么?是不是就是页面的相对路径?
譬如:我的列表显示页面是feedback.jsp;对应的action是/pages/ProductDetailCommViewAction.action我的url到底应该赋什么值?
2.我想问下struts2的自定义标签中是不是不能包括struts2的标签?

谢谢!希望能尽快得到你的答复;
tangshuo 2008-05-09
代码放上去了,包括src和web部分,没有包含lib,运行时需要struts2和spring的jar包,spring的可以没有,不过要把web.xml中的
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
这部分去掉
tarzan854243 2008-05-09
也能把源码发给我吗?tarzan854243@yahoo.com.cn
谢谢了
snowver 2008-05-08
能不能给我发个样例 snowver@163.com
为实现这个标签 我搞一下午还是没显示~
tangshuo 2008-05-08
其实这和在页面中使用struts自己的标签是一样的,只不过这里是使用自己写的标签。
定义一个自定义标签需要分3部分:
1.在tld文件中声明这个标签
2.编写这个标签的逻辑类
3.在页面中使用这个标签

那么,在页面中如何调用自定义标签,过程是这样的:
1.在页面中要指定引用自定义标签的位置声明:
<%@ taglib prefix="tangs" uri="/WEB-INF/tangs.tld"%>
2.在页面中使用自定义标签:
<tangs:pages cpage="%{cpage}" total="%{total}" url="%{url}" styleClass="page" theme="number"/>
当遇到<tangs:pages>这个标签时,服务器首先会到上面指定的tld文件中去寻找这个标签的声明,在这里就是到tangs.tld文件中。找到这个声明后,会获得用来处理这个标签的类,<tag-class>com.tangs.tag.PageTag</tag-class>,然后会实例化这个类,接着会调用这个类中处理标签的方法,对标签进行处理。最后将结果输出到浏览器上,我们从浏览器上也就看到了最终的结果。
wangpx 2008-05-07
麻烦你 把页面如果调用 分页标记 写相信点,这块我还是没有明白
发表评论

您还没有登录,请登录后发表评论

tangshuo
搜索本博客
我的相册
存档
最新评论