如何在JSF表中显示行号?

时间:2012-03-30 18:52:37

标签: java jsf jsf-2

我有这个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。我怎么解决这个问题?

此致

2 个答案:

答案 0 :(得分:15)

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

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

您获得的异常基本上是告诉您正在尝试通过字符串索引(例如List)访问orderList.get("rowIndex")项,这是无效的。访问列表项的唯一有效方法是使用括号表示法#{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属性中使用它的方式也是无效的,因为它不返回布尔值,但是返回长。

答案 1 :(得分:4)

另一种选择是使用List的{​​{1}}方法:

indexOf()