2017-06-06 61 views
0

我最近在应用程序中实现的目的是使用自己的分页 - 所以我需要知道(分类)视图中有多少个文档来计算所需的页面。Xpages从视图中重复控制/文档 - 最佳实践

this known problem
<xp:repeat id="repeat1" rows="30" 
       value="#{javascript:viewScope.counterArray}" 
       indexVar="counter" var="row" disableTheme="true" 
       removeRepeat="true"> 
       <li> 
        <xp:link escape="true" 
         text="#{javascript:(counter + 1) + ' (' + row.toString() + ')'}" id="link3" 
         disableTheme="true"> 
         <xp:eventHandler event="onclick" 
          submit="true"> 
          <xp:this.action> 
           <xp:executeScript> 
            <xp:this.script><![CDATA[#{javascript:viewScope.put("repeatFirstIndex", row);}]]></xp:this.script> 
           </xp:executeScript> 
          </xp:this.action> 
         </xp:eventHandler> 
        </xp:link> 
       </li> 
      </xp:repeat> 

Becaue我必须做一个变通方法,通过控制重复查询的文档数。

<xp:repeat id="blindRepeat" rows="0" value="#{viewStories}"></xp:repeat> 

我用this sample code得到重复控制的正确迭代次数。

<xp:this.beforePageLoad><![CDATA[#{javascript: 
var counterArray = []; 
var numberOfStories = getComponent("blindRepeat").getRowCount(); 
var numberOfPagesNecessary = Math.ceil(numberOfStories/sessionScope.get("ListPagerPerPage")); 
for (var i = 0; i < (numberOfPagesNecessary - 1); i++) { 
    counterArray[i] = i*sessionScope.get("ListPagerPerPage"); 
    viewScope.lastPage = i*sessionScope.get("ListPagerPerPage"); 
} 
viewScope.counterArray = counterArray;}]]></xp:this.beforePageLoad> 

但就在这里,我遇到了一个两难22: 我只能用一个重复控制,因为我不能直接从视图中获得的文件richt数,像克努特赫尔曼(1)不,但重复控制不可用,所以我不能像Per Henrik Lausten(2)提出的那样使用它。

一位同事提议在一个嵌套在盲循环控制(所以它应该绘制)后面但在分页重复控制之前的脚本块中填充数组(所以viewScope应该保持正确的数字),但是这个解决方案似乎相当片状给我。

所以我询问是否有针对这种情况一个“最佳实践” - 我想在这取决于所考虑的的一些JavaScript

+0

而你不想使用''的原因是? – shillem

+0

由于(与许多xp:元素一样)无法调整以查看分页在模板中的显示方式,因此我给出了 –

+1

这不是事实:您可以使用主题指令和自定义渲染器的组合。 – shillem

回答

3

及时执行一个正确的方式,而不是解决这个问题你在给你的问题的评论中给出的理由,我建议你实现你自己的传呼机自定义渲染器。

faces-config.xml声明如下:

<render-kit> 
    <renderer> 
     <component-family>com.ibm.xsp.Pager 
     </component-family> 
     <renderer-type>com.ibm.xsp.XPager 
     </renderer-type> 
     <renderer-class>com.irc.xsp.renderer.UIPagerRenderer 
     </renderer-class> 
    </renderer> 
</render-kit> 

哪里com.irc.xsp.renderer.UIPagerRenderer是渲染类。显然你可以任意命名。只需在两个地方使用相同的名称即可。

渲染器可以是这个样子:

package com.irc.xsp.renderer; 

import java.io.IOException; 
import java.util.Iterator; 
import java.util.List; 
import java.util.Map; 

import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import javax.faces.context.ResponseWriter; 

import com.ibm.commons.util.StringUtil; 
import com.ibm.xsp.FacesExceptionEx; 
import com.ibm.xsp.component.UIPager; 
import com.ibm.xsp.component.UIPagerControl; 
import com.ibm.xsp.component.xp.XspPager; 
import com.ibm.xsp.component.xp.XspPagerControl; 
import com.ibm.xsp.context.FacesContextEx; 
import com.ibm.xsp.event.PagerEvent; 
import com.ibm.xsp.extsn.ResourceHandler; 
import com.ibm.xsp.renderkit.html_extended.XPagerRenderer; 
import com.ibm.xsp.util.AjaxUtilEx; 
import com.ibm.xsp.util.FacesUtil; 
import com.ibm.xsp.util.JavaScriptUtil; 
import com.ibm.xsp.util.TypedUtil; 

public class UIPagerRenderer extends XPagerRenderer { 

    public static final String VAR_PAGE = "page"; //$NON-NLS-1$ 

    private enum Property { 
     LIST_ITEM_CLASS, PAGER_LINK_CLASS, ACTIVE_CLASS("active"), DISABLED_CLASS("disabled"); 

     String className; 

     Property() { 
     } 

     Property(String s) { 
      this.className = s; 
     } 

     String getClassName() { 
      return className; 
     } 

    } 

    @Override 
    public void decode(FacesContext context, UIComponent component) { 
     super.decode(context, component); 

     // check that this component cause the submit 
     if (decodeCausedSubmit(context, component)) { 
      PagerEvent pagerEvent = new PagerEvent(component); 

      String hiddenValue = FacesUtil.getHiddenFieldValue(context); 
      if (StringUtil.isNotEmpty(hiddenValue)) { 
       int pos = hiddenValue.lastIndexOf('_'); 
       if (pos > -1) { 
        hiddenValue = hiddenValue.substring(pos + 1); 
        if (isFirst(hiddenValue)) { 
         pagerEvent.setAction(PagerEvent.ACTION_FIRST); 
        } else if (isLast(hiddenValue)) { 
         pagerEvent.setAction(PagerEvent.ACTION_LAST); 
        } else if (isNext(hiddenValue)) { 
         pagerEvent.setAction(PagerEvent.ACTION_NEXT); 
        } else if (isPrevious(hiddenValue)) { 
         pagerEvent.setAction(PagerEvent.ACTION_PREVIOUS); 
        } else { 
         try { 
          int value = Integer.parseInt(hiddenValue); 
          pagerEvent.setAction(PagerEvent.ACTION_GOTOPAGE); 
          pagerEvent.setPage(value); 
         } catch (NumberFormatException nfe) { 
          return; // just don't queue the event 
         } 
        } 
       } else { 
        return; 
       } 
      } 
      ((UIPager) component).queueEvent(pagerEvent); 
     } 
    } 

    private boolean decodeCausedSubmit(FacesContext context, UIComponent component) { 
     String currentClientId = component.getClientId(context); 
     String hiddenValue = FacesUtil.getHiddenFieldValue(context); 

     if (currentClientId != null && hiddenValue != null) { 
      return StringUtil.indexOfIgnoreCase(hiddenValue, currentClientId) > -1; 
     } 
     return false; 
    } 

    @Override 
    public boolean getRendersChildren() { 
     return true; 
    } 

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

     List<?> controls = component.getChildren(); 

     if (controls.isEmpty()) { 
      return; 
     } 

     XspPager pager = (XspPager) component; 
     UIPager.PagerState pagerState = ((UIPager) component).createPagerState(); 

     if (pagerState == null) { 
      throw new FacesExceptionEx(ResourceHandler.getString("PagerRenderer.Pagerisnotassociatedwithanydataco")); 
     } 

     encodePagerContent(context, context.getResponseWriter(), pager, pagerState, controls, false); 
    } 

    protected void encodePagerContent(FacesContext context, ResponseWriter writer, XspPager pager, 
      UIPager.PagerState pagerState, List<?> controls, boolean rtl) throws IOException { 
     // Compute the pages that should be displayed 
     int pageCount = pagerState.getPageCount(); 
     int startCount = getStartCount(pagerState, pageCount); 
     int endCount = getEndCount(pagerState, pageCount, startCount); 

     String pagerId = pager.getClientId(context); 

     String pagerRole = pager.getRole(); 
     String pagerTitle = pager.getTitle(); 
     String pagerOuterClass = pager.getOuterStyleClass(); 
     String pagerAriaLabel = pager.getAriaLabel(); 
     boolean closeOuterTag = false; 

     if (isAnyAssigned(pagerRole, pagerTitle, pagerOuterClass, pagerAriaLabel)) { 
      writer.startElement("div", null); // $NON-NLS-1$ 

      writeNonNullAttributeOnly(writer, "role", pagerRole); 
      writeNonNullAttributeOnly(writer, "title", pagerTitle); 
      writeNonNullAttributeOnly(writer, "class", pagerOuterClass); 
      writeNonNullAttributeOnly(writer, "aria-label", pagerAriaLabel); 

      closeOuterTag = true; 
     } 

     writer.startElement("ul", null); 

     writeNonNullAttributeOnly(writer, "class", pager.getStyleClass()); 
     writeNonNullAttributeOnly(writer, "id", pagerId); 

     Iterator<?> it = controls.iterator(); 

     while (it.hasNext()) { 
      Object obj = it.next(); 

      if (obj instanceof XspPagerControl) { 
       XspPagerControl control = (XspPagerControl) obj; 
       String type = control.getType(); 

       if (StringUtil.isNotEmpty(type)) { 
        if (isFirst(type) || isNext(type) || isPrevious(type) 
          || (isLast(type) && pager.isAlwaysCalculateLast())) { 
         encodeAction(context, writer, pager, pagerState, pagerId, control, type, startCount, endCount, 
           rtl); 

         continue; 
        } else if (isLast(type) && !pager.isAlwaysCalculateLast()) { 
         if (!pagerState.hasMoreRows()) { 
          encodeAction(context, writer, pager, pagerState, pagerId, control, type, startCount, 
            endCount, rtl); 
         } else { 
          writer.startElement("li", null); 
          writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS 
            .getClassName(), Property.DISABLED_CLASS.getClassName())); 

          writer.startElement("a", null); 
          writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName()); 
          writer.writeText(getMayBeMorePages(), null); 
          writer.endElement("a"); 

          writer.endElement("li"); 
         } 

         continue; 
        } else if (type.equalsIgnoreCase(UIPagerControl.TYPE_GROUP)) { 
         encodeGroup(context, writer, pager, pagerState, pagerId, control, startCount, endCount); 

         continue; 
        } else if (type.equalsIgnoreCase(UIPagerControl.TYPE_STATUS)) { 
         encodeStatus(context, writer, pager, pagerState, control, startCount, endCount); 

         continue; 
        } else if (isSeparator(type)) { 
         encodeSeparator(context, writer, control, type); 

         continue; 
        } else if (type.equalsIgnoreCase(UIPagerControl.TYPE_GOTO)) { 
         encodeGoto(); 

         continue; 
        } 
       } 

       // "Unknown control type {0}" 
       String msg = com.ibm.xsp.extsn.ResourceHandler.getString("PagerRenderer.Unknowncontroltype0"); //$NON-NLS-1$ 
       msg = StringUtil.format(msg, type); 
       throw new FacesExceptionEx(msg); 
      } 
     } 

     writer.endElement("ul"); 

     if (closeOuterTag) { 
      writer.endElement("div"); 
     } 
    } 

    protected void encodeAction(FacesContext context, ResponseWriter writer, XspPager pager, 
      UIPager.PagerState pagerState, String pagerId, XspPagerControl control, String type, int startCount, 
      int endCount, boolean rtl) throws IOException { 
     String controlId = pagerId + "__" + type; 
     String defaultText = ""; 
     String ariaLabel = ""; 
     boolean renderLink = true; 

     //TODO need to handle BIDI here for the unicode symbols 
     if (isFirst(type)) { 
      renderLink = pagerState.getCurrentPage() > startCount; 
      // "\u00AB" FirstSymbol 
      defaultText = "\u00AB"; //$NON-NLS-1$ 
      // "First page" 
      ariaLabel = ResourceHandler.getString("PagerRenderer.First"); //$NON-NLS-1$ 
     } else if (isPrevious(type)) { 
      renderLink = pagerState.getCurrentPage() > startCount; 
      // "\u2039" PreviousSymbol 
      defaultText = "\u2039"; //$NON-NLS-1$ 
      // "Previous page" 
      ariaLabel = ResourceHandler.getString("PagerRenderer.Previous"); //$NON-NLS-1$ 
     } else if (isNext(type)) { 
      renderLink = pagerState.getCurrentPage() < endCount - 1; 
      // "\u203A" NextSymbol 
      defaultText = "\u203A"; //$NON-NLS-1$; 
      // "Next page" 
      ariaLabel = ResourceHandler.getString("PagerRenderer.Next"); //$NON-NLS-1$ 
     } else if (isLast(type)) { 
      renderLink = pagerState.getCurrentPage() < endCount - 1; 
      // "\u00BB" LastSymbol 
      defaultText = "\u00BB"; //$NON-NLS-1$ 
      // "Last page" 
      ariaLabel = ResourceHandler.getString("PagerRenderer.Last"); //$NON-NLS-1$ 
     } 

     writer.startElement("li", null); 
     String listItemClass = Property.LIST_ITEM_CLASS.getClassName(); 

     if (!renderLink) { 
      //If current page is the first, disable first/previous pagers 
      //and if current page is the last, disable last/next pagers 
      listItemClass = com.irc.util.StringUtil.concat(listItemClass, Property.DISABLED_CLASS.getClassName()); 
     } 

     writeNonNullAttributeOnly(writer, "class", listItemClass); 

     // Generate the image link 
     String val = (String) control.getValue(); 

     if (StringUtil.isEmpty(val)) { 
      val = defaultText; 
     } 

     // Generate the text link 
     if (StringUtil.isNotEmpty(val)) { 
      writer.startElement("a", null); // $NON-NLS-1$ 

      if (renderLink) { 
       writer.writeAttribute("aria-disabled", "false", null); // $NON-NLS-1$ $NON-NLS-2$ 
       writer.writeAttribute("href", "#", null); // $NON-NLS-1$ $NON-NLS-2$ 
      } else { 
       //add a11y attributes 
       writer.writeAttribute("aria-disabled", "true", null); // $NON-NLS-1$ $NON-NLS-2$ 
      } 

      writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName()); 

      writer.writeAttribute("id", controlId + "__lnk", null); // $NON-NLS-1$ $NON-NLS-2$ 
      writer.writeAttribute("role", "button", null); // $NON-NLS-1$ $NON-NLS-2$ 
      writer.writeAttribute("aria-label", ariaLabel, null); // $NON-NLS-1$ 
      writer.writeText(val, null); 
      writer.endElement("a"); // $NON-NLS-1$ 

      if (renderLink) { 
       setupSubmitOnClick(context, pager, pagerState, controlId, controlId + "__lnk"); // $NON-NLS-1$ 
      } 
     } 

     writer.endElement("li"); // $NON-NLS-1$ 
    } 

    protected void encodeGroup(FacesContext context, ResponseWriter writer, XspPager pager, 
      UIPager.PagerState pagerState, String pagerId, XspPagerControl control, int startCount, int endCount) 
      throws IOException { 
     // Save the old page value 
     Map<String, Object> requestMap = TypedUtil.getRequestMap(context.getExternalContext()); 
     Object oldPage = requestMap.get(VAR_PAGE); 
     String controlId = pagerId + "__" + control.getType();//$NON-NLS-1$ 

     // Encode the pages 
     for (int i = startCount; i < endCount; i++) { 
      // Push the page number 
      requestMap.put(VAR_PAGE, i + 1); 
      boolean renderLink = (i != pagerState.getCurrentPage()); 

      writer.startElement("li", null); // $NON-NLS-1$ 
      String listItemClass = Property.LIST_ITEM_CLASS.getClassName(); 

      if (!renderLink) { 
       listItemClass = com.irc.util.StringUtil.concat(listItemClass, Property.ACTIVE_CLASS.getClassName()); 
      } 

      writeNonNullAttributeOnly(writer, "class", listItemClass); 

      // Generate the image link 
      String val = (String) control.getValue(); 

      if (StringUtil.isEmpty(val)) { 
       val = Integer.toString(i + 1); 
      } 

      // Generate the text link 
      if (StringUtil.isNotEmpty(val)) { // Generate the text link 
       writer.startElement("a", control); //$NON-NLS-1$ 
       writer.writeAttribute("id", controlId + "__lnk__" + i, null); // $NON-NLS-1$ $NON-NLS-2$ 
       // "Page {0}" 
       String ariaLabel = ResourceHandler.getString("PagerRenderer.Gotopage0"); //$NON-NLS-1$ 
       ariaLabel = StringUtil.format(ariaLabel, val); 
       writer.writeAttribute("aria-label", ariaLabel, null); // $NON-NLS-1$ 
       writer.writeAttribute("role", "button", null); // $NON-NLS-1$ $NON-NLS-2$ 

       writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName()); 

       if (renderLink) { //make sure the a is tab-able     
        writer.writeAttribute("tabindex", "0", null); // $NON-NLS-1$ $NON-NLS-2$ 
        writer.writeAttribute("aria-pressed", "false", null); // $NON-NLS-1$ $NON-NLS-2$ 
       } else { 
        writer.writeAttribute("aria-pressed", "true", null); // $NON-NLS-1$ $NON-NLS-2$ 
       } 

       writer.writeText(val, null); 
       writer.endElement("a"); // $NON-NLS-1$ 

       if (renderLink) { 
        setupSubmitOnClick(context, pager, pagerState, controlId + "__lnk__" + i, controlId + "__lnk__" + i); // $NON-NLS-1$ $NON-NLS-2$ 
       } 
      } 

      writer.endElement("li"); // $NON-NLS-1$ 
     } 

     // Encode after the pages 
     if (!pager.isAlwaysCalculateLast()) { 
      if (endCount < pagerState.getLastPage() || pagerState.hasMoreRows()) { 
       writer.startElement("li", null); // $NON-NLS-1$ 
       writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS.getClassName(), 
         Property.DISABLED_CLASS.getClassName())); 

       writer.startElement("a", control); //$NON-NLS-1$ 
       writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName()); 
       writer.writeText(getMayBeMorePages(), null); 
       writer.endElement("a"); // $NON-NLS-1$ 
       writer.endElement("li"); // $NON-NLS-1$ 
      } 
     } 

     // Restore the old page value 
     if (oldPage != null) { 
      requestMap.put(VAR_PAGE, oldPage); 
     } else { 
      requestMap.remove(VAR_PAGE); 
     } 

    } 

    protected void setupSubmitOnClick(FacesContext context, XspPager component, UIPager.PagerState st, String clientId, 
      String sourceId) { 
     boolean immediate = false; 

     UIComponent subTree = ((FacesContextEx) context).getSubTreeComponent(); 

     boolean partialExec = component.isPartialExecute(); 
     String execId = null; 
     if (partialExec) { 
      execId = component.getClientId(context); 
      immediate = true; 
     } else { 
      if (subTree != null) { 
       partialExec = true; 
       execId = subTree.getClientId(context); 
       immediate = true; 
      } 
     } 

     boolean partialRefresh = component.isPartialRefresh(); 
     String refreshId = null; 
     if (partialRefresh) { 
      UIComponent refreshComponent = component.findSharedDataPagerParent(); 
      if (null == refreshComponent) { 
       refreshComponent = (UIComponent) st.getDataIterator(); 
      } 
      refreshId = AjaxUtilEx.getRefreshId(context, refreshComponent); 
     } else { 
      if (subTree != null) { 
       partialRefresh = true; 
       refreshId = subTree.getClientId(context); 
      } 
     } 

     // call some JavaScript in xspClient.js 
     final String event = "onclick"; // $NON-NLS-1$ 
     // Note, the onClick event is also triggered if the user tabs to the 
     // image\link and presses enter (Not just when clicked with a 
     // mouse). 

     // When the source is clicked, put its id in the hidden field and 
     // submit the form. 
     StringBuilder buff = new StringBuilder(); 
     if (partialRefresh) { 
      JavaScriptUtil.appendAttachPartialRefreshEvent(buff, clientId, sourceId, execId, event, 
      /* clientSideScriptName */null, immediate ? JavaScriptUtil.VALIDATION_NONE 
        : JavaScriptUtil.VALIDATION_FULL, 
      /* refreshId */refreshId, 
      /* onstart */getOnStart(component), 
      /* oncomplete */getOnComplete(component), 
      /* onerror */getOnError(component)); 
     } else { 
      JavaScriptUtil.appendAttachEvent(buff, clientId, sourceId, execId, event, 
      /* clientSideScriptName */null, 
      /* submit */true, immediate ? JavaScriptUtil.VALIDATION_NONE : JavaScriptUtil.VALIDATION_FULL); 
     } 
     String script = buff.toString(); 

     // Add the script block we just generated. 
     JavaScriptUtil.addScriptOnLoad(script); 
    } 

    protected String getOnStart(XspPager component) { 
     return (String) component.getAttributes().get("onStart"); // $NON-NLS-1$ 
    } 

    protected String getOnComplete(XspPager component) { 
     return (String) component.getAttributes().get("onComplete"); // $NON-NLS-1$ 
    } 

    protected String getOnError(XspPager component) { 
     return (String) component.getAttributes().get("onError"); // $NON-NLS-1$ 
    } 

    protected void encodeStatus(FacesContext context, ResponseWriter writer, XspPager pager, 
      UIPager.PagerState pagerState, XspPagerControl control, int startCount, int endCount) throws IOException { 
     writer.startElement("li", null); // $NON-NLS-1$ 
     writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS.getClassName(), 
       Property.DISABLED_CLASS.getClassName())); 

     String val = (String) control.getValue(); 

     if (StringUtil.isEmpty(val)) { 
      val = "{0}"; // $NON-NLS-1$ 
     } 

     if (pagerState.getLastPage() > 0) { 
      writer.startElement("a", null); // $NON-NLS-1$ 
      writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName()); 
      writer.writeAttribute("role", "button", null); // $NON-NLS-2$ $NON-NLS-1$ 
      val = StringUtil.format(val, pagerState.getCurrentPage() + 1, pagerState.getLastPage(), startCount, 
        endCount); 
      writer.writeText(val, null); 
      writer.endElement("a"); // $NON-NLS-1$ 
     } 

     writer.endElement("li"); // $NON-NLS-1$ 
    } 

    protected void encodeSeparator(FacesContext context, ResponseWriter writer, XspPagerControl control, String type) 
      throws IOException { 
     String val = (String) control.getValue(); 

     writer.startElement("li", null); // $NON-NLS-1$ 

     if (StringUtil.isEmpty(val)) { 
      String defaultSeparator = "|"; // $NON-NLS-1$ 

      if (type.equalsIgnoreCase(UIPagerControl.TYPE_SEPARATORPAGE)) { 
       // "Page" 
       defaultSeparator = com.ibm.xsp.extsn.ResourceHandler.getString("PagerRenderer.Page"); //$NON-NLS-1$ 
      } 

      val = defaultSeparator; 
     } 

     writeNonNullAttributeOnly(writer, "class", com.irc.util.StringUtil.concat(Property.LIST_ITEM_CLASS.getClassName(), 
       Property.DISABLED_CLASS.getClassName())); 

     // Generate the text link 
     if (StringUtil.isNotEmpty(val)) { 
      writer.startElement("a", null); // $NON-NLS-1$ 
      writeNonNullAttributeOnly(writer, "class", Property.PAGER_LINK_CLASS.getClassName()); 
      writer.writeText(val, null); 
      writer.endElement("a"); // $NON-NLS-1$ 
     } 

     writer.endElement("li"); // $NON-NLS-1$ 
    } 

    protected void encodeGoto() { 
     // Do not exists in core XPages yet.. 
    } 

    protected int getStartCount(UIPager.PagerState st, int pageCount) { 
     int start = (st.getFirst()/st.getRows()) - pageCount/2; 
     start = Math.min(Math.max(0, st.getLastPage() - pageCount), Math.max(0, start)); 
     return start; 
    } 

    protected int getEndCount(UIPager.PagerState st, int pageCount, int start) { 
     int sizeOfPageRange = Math.min(start + pageCount, st.getLastPage()) - start; 
     int end = start + sizeOfPageRange; 
     return end; 
    } 

    protected boolean isFirst(String type) { 
     return (type.equalsIgnoreCase(UIPagerControl.TYPE_FIRST) 
       || type.equalsIgnoreCase(UIPagerControl.TYPE_FIRSTARROW) || type 
       .equalsIgnoreCase(UIPagerControl.TYPE_FIRSTIMAGE)); 
    } 

    protected boolean isNext(String type) { 
     return (type.equalsIgnoreCase(UIPagerControl.TYPE_NEXT) || type.equalsIgnoreCase(UIPagerControl.TYPE_NEXTARROW) || type 
       .equalsIgnoreCase(UIPagerControl.TYPE_NEXTIMAGE)); 
    } 

    protected boolean isLast(String type) { 
     return (type.equalsIgnoreCase(UIPagerControl.TYPE_LAST) || type.equalsIgnoreCase(UIPagerControl.TYPE_LASTARROW) || type 
       .equalsIgnoreCase(UIPagerControl.TYPE_LASTIMAGE)); 
    } 

    protected boolean isPrevious(String type) { 
     return (type.equalsIgnoreCase(UIPagerControl.TYPE_PREVIOUS) 
       || type.equalsIgnoreCase(UIPagerControl.TYPE_PREVIOUSARROW) || type 
       .equalsIgnoreCase(UIPagerControl.TYPE_PREVIOUSIMAGE)); 
    } 

    protected boolean isSeparator(String type) { 
     return (type.equalsIgnoreCase(UIPagerControl.TYPE_SEPARATOR) || type 
       .equalsIgnoreCase(UIPagerControl.TYPE_SEPARATORPAGE)); 
    } 

    protected String getMayBeMorePages() { 
     return "..."; // $NON-NLS-1$ 
    } 

    private void writeNonNullAttributeOnly(ResponseWriter writer, String attributeName, String attributeValue) 
      throws IOException { 
     if (attributeValue != null && !attributeValue.isEmpty()) { 
      writer.writeAttribute(attributeName, attributeValue, null); 
     } 
    } 

    private boolean isAnyAssigned(String... objs) { 
     for (String s : objs) { 
      if (s != null && !s.isEmpty()) 
       return true; 
     } 

     return false; 
    } 

} 

这就是我一直在用我的最后一个项目的类。基本上,它重新实现了页面所做的一切,以便控制组件的外观和感觉 - 毕竟它被称为渲染器。你可以尝试在这里和那里调整它,看看页面上的各种东西是如何工作的。这是一个学习过程。