2012-03-30 116 views
6

我有這個JSF表。我想添加行號。如何在JSF表中顯示行號?

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:ui="http://java.sun.com/jsf/facelets" 
     > 
    <h:head> 
     <h:outputStylesheet library="css" name="table-style.css" /> 
    </h:head> 
    <h:body> 

     <h1>JSF 2 dataTable example</h1> 
     <h:form> 
      <h:dataTable value="#{order.orderList}" var="o" 
       styleClass="order-table" 
       headerClass="order-table-header" 
       rowClasses="order-table-odd-row,order-table-even-row" 
      > 
         <h:column> 

        <f:facet name="header">No</f:facet> 

        <h:inputText value="#{order.orderList.rowIndex + 1}" size="10" rendered="false" /> 

        <h:outputText value="#{order.orderList.rowIndex + 1}" rendered="#{not order.orderList.rowIndex + 1}" /> 

       </h:column> 
       <h:column> 

        <f:facet name="header">Order No</f:facet> 

        <h:inputText value="#{o.orderNo}" size="10" rendered="#{o.editable}" /> 

        <h:outputText value="#{o.orderNo}" rendered="#{not o.editable}" /> 

       </h:column> 

       <h:column> 

        <f:facet name="header">Product Name</f:facet> 

        <h:inputText value="#{o.productName}" size="20" rendered="#{o.editable}" /> 

        <h:outputText value="#{o.productName}" rendered="#{not o.editable}" /> 

       </h:column> 

       <h:column> 

        <f:facet name="header">Price</f:facet> 

        <h:inputText value="#{o.price}" size="10" rendered="#{o.editable}" /> 

        <h:outputText value="#{o.price}" rendered="#{not o.editable}" /> 

       </h:column> 

       <h:column> 

        <f:facet name="header">Quantity</f:facet> 

        <h:inputText value="#{o.qty}" size="5" rendered="#{o.editable}" /> 

        <h:outputText value="#{o.qty}" rendered="#{not o.editable}" /> 

       </h:column> 

       <h:column> 

        <f:facet name="header">Action</f:facet> 

        <h:commandLink value="Edit" action="#{order.editAction(o)}" rendered="#{not o.editable}" /> 

       </h:column> 

      </h:dataTable> 

      <h:commandButton value="Save Changes" action="#{order.saveAction}" /> 

     </h:form> 
    </h:body> 

</html> 


package com.mkyong; 

import java.io.Serializable; 
import java.math.BigDecimal; 
import java.util.ArrayList; 
import java.util.Arrays; 

import javax.faces.bean.ManagedBean; 
import javax.faces.bean.SessionScoped; 

@ManagedBean(name="order") 
@SessionScoped 
public class OrderBean implements Serializable{ 

    private static final long serialVersionUID = 1L; 

    private static final ArrayList<Order> orderList = 
     new ArrayList<Order>(Arrays.asList(

     new Order("A0001", "Intel CPU", 
       new BigDecimal("700.00"), 1), 
     new Order("A0002", "Harddisk 10TB", 
       new BigDecimal("500.00"), 2), 
     new Order("A0003", "Dell Laptop", 
       new BigDecimal("11600.00"), 8), 
     new Order("A0004", "Samsung LCD", 
       new BigDecimal("5200.00"), 3), 
     new Order("A0005", "A4Tech Mouse", 
       new BigDecimal("100.00"), 10) 
    )); 

    public ArrayList<Order> getOrderList() { 

     return orderList; 

    } 

    public String saveAction() { 

     //get all existing value but set "editable" to false 
     for (Order order : orderList){ 
      order.setEditable(false); 
     } 

     //return to current page 
     return null; 

    } 

    public String editAction(Order order) { 

     order.setEditable(true); 
     return null; 
    } 

    public static class Order{ 

     String orderNo; 
     String productName; 
     BigDecimal price; 
     int qty; 
     boolean editable; 

     public Order(String orderNo, String productName, BigDecimal price, int qty) { 
      this.orderNo = orderNo; 
      this.productName = productName; 
      this.price = price; 
      this.qty = qty; 
     } 

     public boolean isEditable() { 
      return editable; 
     } 
     public void setEditable(boolean editable) { 
      this.editable = editable; 
     } 
     public String getOrderNo() { 
      return orderNo; 
     } 
     public void setOrderNo(String orderNo) { 
      this.orderNo = orderNo; 
     } 
     public String getProductName() { 
      return productName; 
     } 
     public void setProductName(String productName) { 
      this.productName = productName; 
     } 
     public BigDecimal getPrice() { 
      return price; 
     } 
     public void setPrice(BigDecimal price) { 
      this.price = price; 
     } 
     public int getQty() { 
      return qty; 
     } 
     public void setQty(int qty) { 
      this.qty = qty; 
     } 
    } 
} 

我加了#{order.orderList.rowIndex + 1}爲了統計行數並顯示數字。但是,當我運行JSF頁面我得到這個錯誤:

java.lang.NumberFormatException: For input string: "rowIndex" 
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) 
    at java.lang.Integer.parseInt(Integer.java:481) 
    at java.lang.Integer.parseInt(Integer.java:514) 
    at javax.el.ListELResolver.toInteger(ListELResolver.java:409) 
    at javax.el.ListELResolver.getValue(ListELResolver.java:202) 
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) 
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) 
    at com.sun.el.parser.AstValue.getValue(AstValue.java:138) 
    at com.sun.el.parser.AstValue.getValue(AstValue.java:183) 
    at com.sun.el.parser.AstNot.getValue(AstNot.java:63) 
    at com.sun.el.parser.AstPlus.getValue(AstPlus.java:59) 
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224) 
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) 
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) 
    at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:413) 
    at javax.faces.component.UIData.iterate(UIData.java:1993) 
    at javax.faces.component.UIData.processDecodes(UIData.java:1161) 
    at javax.faces.component.UIForm.processDecodes(UIForm.java:225) 
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176) 
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176) 
    at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:933) 
    at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849) 
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746) 
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045) 
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228) 
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
    at java.lang.Thread.run(Thread.java:679) 

我認爲rowIndex沒有找到。我如何解決這個問題?

問候

回答

14

rowIndex<h:dataTable>組件本身的性質,而不是它的java.util.List值。

<h:dataTable binding="#{table}" ...> 
    <h:column>#{table.rowIndex + 1}</h:column> 
    ... 
</h:dataTable> 

,你得到的是基本上是告訴你正在試圖通過一個字符串索引像這樣orderList.get("rowIndex")訪問List項目的例外,這是無效的。訪問列表項的唯一有效方法是使用大括號表示法,如#{order.orderList[0]},它解析爲orderList.get(0),但這畢竟不是你所需要的。

另一種方法是將orderList包裝在DataModel屬性中,並將其作爲值提供,例如,

<h:dataTable value="#{order.orderModel}" ...> 
    <h:column>#{order.orderModel.rowIndex + 1}</h:column> 
    ... 
</h:dataTable> 

private transient DataModel orderModel; 

public DataModel getOrderModel() { 
    if (orderModel == null) { 
     orderModel = new ListDataModel(orderList); 
    } 
    return orderModel; 
} 

應該顯示僅輸出。將它顯示在輸入組件中是沒有意義的,因爲不能將設置爲單個值表達式。同樣在rendered屬性中使用它的方式與您所做的一樣無效,因爲它不會返回布爾值,而是返回一個長整型。

+0

你知道的數據表中最好的例子。我有一個不是很好,我發現這個:http://balusc.blogspot.com/2006/06/using-datatables.html這正是我需要的,但它是爲JSF 1.2。有現代版嗎? – 2012-03-30 21:10:57

+1

閱讀頂部的「通知」部分。 – BalusC 2012-03-30 21:36:07

+0

是的,我打開了JSF 2.0的例子,但當我將代碼導入Netbeans中時,出現錯誤:private item item = new Item();這個例子有完整的源代碼嗎? – 2012-03-30 21:47:49

4

另一種選擇是使用ListindexOf()方法:

<h:outputText value="#{order.orderList.indexOf(o) + 1}"/> 
+1

請注意,這需要EL 2.2。此外,每次在父列表中查找項目自己的索引時,如果列表和複雜對象較多,則會降低渲染性能。 – BalusC 2012-03-30 20:52:42