Dynamic DataTable, Fixed Header, Fixed NumColumn, Sortable Header
自己寫了段小代碼, 希望可以供大家學習和參考。 代碼里沒有太多注釋, 有時間的話我會補充上去。
自己在寫動態生成DataTable的時候也查閱了很多相關文章, 以及實現固定表頭等等。
在解決固定表頭問題上我是用的兩張表(加行標是3張表)實現的, 因為我發現如果用JSF1.1的化實現固定表頭幾乎不可能(如果有人有好的想法, 比如用JS比較在行的朋友請告訴我解決方法, 謝謝)
實現給每個Header加上一個CommandLink的時候我遇到了很大的問題, 就是無論如何我動態生成的這些CommandLink都沒有辦法觸發事件(并不報錯), 這個問題足足折磨了我3天。。。
最后終于發現問題的所在, 是因為我在生成CommandLink的時候沒有給每個CommandLink SetID。。。 就加上這句話,問題立馬解決。
我原來的代碼是鏈接數據庫的, 但是這樣的化大家也沒有辦法參考, 所以我對代碼少繳修改, 就算是個小例子吧, 可重用。
希望大家對我的代碼提出寶貴意見,一起進步,謝謝。
備注(2007/8/9): 做這個DataTable的目的其實不是在電腦上顯示,而是在PDA上使用, 這個是最大的問題, 按照我的測試, 這段代碼在FireFox上沒有辦法正常顯示,在IE Mobile 5,6 都沒有辦法正常顯示, 說的直白點, 就是這段代碼只能在PC的IE瀏覽器上顯示。。。
PDA上使用JSF顯示動態的東西確實沒有辦法實現, 在進行很久的調研之后發現,凡是一切可以動的效果在IE Mobile 上都沒有辦法正常顯示。。。
不過聽說目前的iPhone里面的瀏覽器很牛, 可以正常顯示所有動態的效果(Mac就是牛!!!)
我真心希望如果有人閱讀我這個文章后可以給我點意見和建議, 我喜歡可以把自己的這段代碼優化的完美些。。。
截圖:

Dynamic.jsp
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<Script language="JavaScript">
var tdW;
//Scroll
function f_scroll(Col_T,Row_T,DivNm){
if(Col_T!=''){
document.getElementById(Col_T).scrollLeft = document.getElementById(DivNm).scrollLeft;
}
if(Row_T!=''){
document.getElementById(Row_T).scrollTop = document.getElementById(DivNm).scrollTop;
}
}
</Script>
<html>
<f:view>
<head>
<title>TABLE</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h:form>
<font size="2" color="black"
style="position:absolute; left: 35; top: 5; width:200; height:20">
<h:outputText value="Please Enter:" /> </font>
<h:inputText value="" size="20"
style="position:absolute; left: 110; top: 5; width:150; height:20" />
<h:commandButton value="Search" action=""
style="position:absolute; left: 270; top: 5; width:50; height:20" />
<table BORDER=0
STYLE="POSITION: ABSOLUTE; LEFT: 0px; TOP: 30px; right: 0px; bottom: 0px;">
<tr>
<td STYLE="text-align: right;">
<!--Table1 start-->
<!--Table1 end-->
</td>
<td>
<!--Table2 start-->
<Div ID="Table2"
STYLE="position: relative; top: 0; border-left: 0.5pt solid black; border-right: 0.5pt solid black; height: 17.75px; width: 285px; overflow-x: hidden;">
<h:dataTable value="#{myBean.myHeader}" var="myHeader"
binding="#{myBean.headerDataTable}" bgcolor="white" border="1"
cellspacing="1" rendered="true" styleClass="orders"
headerClass="ordersHeader" rowClasses="evenColumn,oddColumn"
style="position:absolute; left: 0; top: 0; width: 100; height: 10; border-collapse:collapse;"
id="ree">
</h:dataTable>
</Div>
<!--Table2 end-->
</td>
</tr>
<tr>
<td STYLE="vertical-align: top;">
<!--Table3 start-->
<Div ID="Table3"
STYLE="border-bottom: 0.5pt solid black; border-top: 0.5pt solid black; width: 25.5px; height: 265px; overflow-y: hidden; position: relative; left: 0;">
<h:dataTable value="#{myBean.myNum}" var="myNum"
binding="#{myBean.numDataTable}" bgcolor="white" border="1"
cellspacing="1" rendered="true" styleClass="orders"
headerClass="ordersHeader" rowClasses="evenColumn,oddColumn"
style="position:absolute; left: 0; top: 0; width: 32; height: 5; border-collapse:collapse;"
id="dee">
</h:dataTable>
</Div>
<!--Table3 end-->
</td>
<td STYLE="vertical-align: top;">
<!--Table4 start-->
<Div ID="Table4" onScroll="f_scroll('Table2','Table3','Table4');"
STYLE="height: 281px; width: 300px; overflow-y: scroll; overflow-x: scroll;">
<h:dataTable value="#{myBean.myList}" var="myItem"
binding="#{myBean.dynamicDataTable}" bgcolor="white" border="1"
cellspacing="1" rendered="true" styleClass="orders"
headerClass="ordersHeader" rowClasses="evenColumn,oddColumn"
style="position:absolute; left: 0; top: 0; width: 100; height: 5; border-collapse:collapse;">
</h:dataTable>
</Div>
<!--Table4 end-->
</td>
</tr>
</table>
</h:form>
</body>
</f:view>
</html>
MyBean.java
package mypackage;
import java.util.ArrayList;
import java.util.List;
import javax.faces.application.Application;
import javax.faces.component.UIColumn;
import javax.faces.component.UIOutput;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.component.html.HtmlDataTable;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.ActionEvent;
public class MyBean {
private List<List<String>> myList;
private List<List<String>> myHeader;
private List<List<Integer>> myNum;
private HtmlDataTable dynamicDataTable;
private HtmlDataTable headerDataTable;
private HtmlDataTable numDataTable;
private static int tempWidth = 30;
// Load Data from DataBase to Every DataTable --------------------------------
public void loadMyList() throws Exception {
myList = new ArrayList<List<String>>();
int row = 25;
while(row > 0) {
int column = 25;
String str = "o";
List <String> tmpvector = new ArrayList <String> ();
while(column > 0) {
tmpvector.add(str);
column--;
}
row--;
myList.add(tmpvector);
}
}
public void loadMyHeader() throws Exception {
myHeader = new ArrayList<List<String>>();
String str = "*****";
int column = 25;
List <String> tmpvector = new ArrayList <String> ();
while(column > 0) {
tmpvector.add(str);
column--;
}
myHeader.add(tmpvector);
}
public void loadMyNum() throws Exception {
myNum = new ArrayList<List<Integer>>();
int row = 0;
while(row < 25) {
List <Integer> tmpvector = new ArrayList <Integer> ();
tmpvector.add(row);
myNum.add(tmpvector);
row++;
}
}
//initialize Every DataTable to the Front-------------------------------------
public void populateDynamicDataTable() {
if (myList != null && myList.size() > 0) {
dynamicDataTable = new HtmlDataTable();
int columns = ((List) myList.get(0)).size();
System.out.println("DisplayCloumn: " + columns);//
for (int i = 0; i < columns; i++) {
ValueBinding myItem = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{myItem[" + i + "]}");
UIColumn column = new UIColumn();
HtmlOutputText outputText = new HtmlOutputText();
outputText.setValueBinding("value", myItem);
outputText.setStyle("width: " + tempWidth + "");
column.getChildren().add(outputText);
column.setId("col_" + i); //You should set ID of every component which you create in the Backing-Bean .
dynamicDataTable.getChildren().add(column);
}
}
}
public void populateHeaderDataTable() {
if (myHeader != null && myHeader.size() > 0) {
headerDataTable = new HtmlDataTable();
int columns = ((List) myHeader.get(0)).size();
FacesContext facesContext = FacesContext.getCurrentInstance();
Application application = facesContext.getApplication();
for (int i = 0; i < columns; i++) {
HtmlCommandLink commandLink = (HtmlCommandLink) application.createComponent(HtmlCommandLink.COMPONENT_TYPE);
String valueBindingExpression = "#{myHeader[" + i + "]}";
ValueBinding valueBinding = application.createValueBinding(valueBindingExpression);
commandLink.setValueBinding("value", valueBinding);
commandLink.setId("head_comankLink_" + i); //The most important!!! If you dont put it nothing is gonna happen.
commandLink.setStyle("color: blue");
commandLink.setStyle("width: " + tempWidth + "");
commandLink.getAttributes();
Class[] params = { ActionEvent.class };
MethodBinding actionListener = application.createMethodBinding("#{myBean.setSelectedDocumentId}", params);
commandLink.setActionListener(actionListener);
commandLink.setImmediate(true);
UIColumn column = new UIColumn();
column.getChildren().add(commandLink);
column.setId("head_" + i);
headerDataTable.getChildren().add(column);
}
}
}
public void populateNumDataTable() {
if (myNum != null && myNum.size() > 0) {
numDataTable = new HtmlDataTable();
UIOutput output = new UIOutput();
ValueBinding myItem = FacesContext.getCurrentInstance().getApplication().createValueBinding("#{myNum[0]}");
output.setValueBinding("value", myItem);
// Set column.
UIColumn column = new UIColumn();
column.getChildren().add(output);
column.setId("num");
numDataTable.getChildren().add(column);
}
}
//Test Actions and ActionListeners--------------------------------------------
public void setSelectedDocumentId(ActionEvent event) throws Exception
{
}
// Getters -------------------------------------------------------------------
public HtmlDataTable getDynamicDataTable() throws Exception {
if (dynamicDataTable == null) {
loadMyList(); // Reload to get most recent data.
populateDynamicDataTable();
}
return dynamicDataTable;
}
public HtmlDataTable getHeaderDataTable() throws Exception {
if (headerDataTable == null) {
loadMyHeader(); // Reload to get most recent data.
populateHeaderDataTable();
}
return headerDataTable;
}
public HtmlDataTable getNumDataTable() throws Exception {
if (numDataTable == null) {
loadMyNum(); // Reload to get most recent data.
populateNumDataTable();
}
return numDataTable;
}
public List<List<Integer>> getMyNum() {
return myNum;
}
public List<List<String>> getMyHeader() {
return myHeader;
}
public List<List<String>> getMyList() {
return myList;
}
// Setters -------------------------------------------------------------------
public void setDynamicDataTable(HtmlDataTable dynamicDataTable) {
this.dynamicDataTable = dynamicDataTable;
}
public void setHeaderDataTable(HtmlDataTable headerDataTable) {
this.headerDataTable = headerDataTable;
}
public void setMyHeader(List<List<String>> myHeader) {
this.myHeader = myHeader;
}
public void setNumDataTable(HtmlDataTable numDataTable) {
this.numDataTable = numDataTable;
}
public void setMyNum(List<List<Integer>> myNum) {
this.myNum = myNum;
}
public void setMyList(List<List<String>> myList) {
this.myList = myList;
}
}
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<managed-bean>
<managed-bean-name>myBean</managed-bean-name>
<managed-bean-class>mypackage.MyBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>
styles.css
.orders {
border: thin solid black;
}
.ordersHeader {
text-align: center;
font-style: ;
color: Snow;
font-size: 12px;
background: Teal;
}
.evenColumn {
text-align: center;
font-size: 12px;
background: #F0FFFF;
}
.oddColumn {
text-align: center;
font-size: 12px;
background: white;
}
第一次發貼, 我沒有加入行標, 不知道大家可不可以直接復制,如果不可以的話可以留言給我, 我會把代碼方到文件里面。