用動(dòng)態(tài)選擇的元素輕松創(chuàng)建復(fù)選框
Danilo Gurovich , 首席工程師, Earthlink Inc.
2005 年 11 月 28 日
Struts Recipes 的合著者 Danilo Gurovich 從 George Franciscus 停止的地方開(kāi)始,介紹了易于使用的創(chuàng)建動(dòng)態(tài)選擇復(fù)選框的 Struts 訣竅。
在用戶(hù)界面設(shè)計(jì)中,復(fù)選框組不如它的同類(lèi) —— 多行選擇框那樣流行。它們基本上做的是同一件事,即選擇映射到單一 name 屬性的一組選項(xiàng)。當(dāng)在組中使用時(shí),復(fù)選框執(zhí)行的功能實(shí)際與多行選擇框一樣,但是它們占據(jù)的屏幕空間更多。當(dāng)希望用戶(hù)在選擇一個(gè)或多個(gè)選項(xiàng)之前能夠看到所有選項(xiàng)的時(shí)候,這會(huì)很有好處。
雖然在選項(xiàng)不多的時(shí)候,多行選擇框通常提供更好的觀感,但是當(dāng)選擇框必須動(dòng)態(tài)呈現(xiàn)而且包含預(yù)選功能時(shí),對(duì)企業(yè)應(yīng)用程序來(lái)說(shuō)復(fù)選框組會(huì)是更好的選擇。幸運(yùn)的是,使用 Struts 框架可以很容易地創(chuàng)建動(dòng)態(tài)復(fù)選框組。
在這篇文章中,我將介紹一個(gè)簡(jiǎn)單的訣竅:用 Struts 的 <html:multibox/> 和 <logic:iterate/> 標(biāo)記在應(yīng)用程序的視圖層呈現(xiàn)大量條目,在本例中是 Java? Server Page(JSP)。
我先從使用復(fù)選框元素顯示簡(jiǎn)單的 String[] 數(shù)組開(kāi)始,數(shù)組中包含喜瑪拉雅山的頂峰高度。然后,我將創(chuàng)建另外一個(gè) String[] 數(shù)組,包含 selectedMountains ,代表已經(jīng)選中的復(fù)選框。復(fù)選框的預(yù)選情況會(huì)在兩個(gè)數(shù)組的交叉中產(chǎn)生。如果 selectedMountains 的初始數(shù)組為空,那么所有復(fù)選框最初都會(huì)顯示為未選中。
請(qǐng)參閱 下載 獲得完整的示例源代碼。應(yīng)當(dāng)擁有跟隨本文所需要的每樣?xùn)|西。如果需要下載 Struts 框架,請(qǐng)參閱 參考資料。
創(chuàng)建動(dòng)態(tài)復(fù)選框
創(chuàng)建動(dòng)態(tài)復(fù)選框的訣竅包含三個(gè)主要部分:
一個(gè)表單 bean,容納復(fù)選框的 String[] 數(shù)組和表示選中復(fù)選框的 String[] 數(shù)組。
一個(gè) JSP,帶有一個(gè)表單,在需要的時(shí)候顯示復(fù)選框。
一個(gè)簡(jiǎn)單的 Action 類(lèi),從表單頁(yè)面轉(zhuǎn)到顯示頁(yè)面。
請(qǐng)注意 “Himalayas” 示例非常簡(jiǎn)單。用來(lái)填充復(fù)選框的字段應(yīng)當(dāng)來(lái)自更復(fù)雜的模型,比如這樣的模型,它能夠標(biāo)識(shí)用戶(hù),并選擇要顯示的字段,然后把業(yè)務(wù)對(duì)象認(rèn)為需要的選項(xiàng)預(yù)先選中。我采用簡(jiǎn)單的模型是為了更好地演示 Struts 的用戶(hù)界面功能。代碼示例使用 JSP 腳本語(yǔ)言是為了表示清楚。
第 1 步. 創(chuàng)建表單 bean
我先從創(chuàng)建 Struts 表單 bean 開(kāi)始,它包含填充復(fù)選框所需要的信息。請(qǐng)注意清單 1 中的 TestForm.java 包含了兩個(gè)示例 String[] 數(shù)組變量的 getter 和 setter。數(shù)組 mountains 代表示例復(fù)選框的 全部選項(xiàng),數(shù)組 selectedMountains 代表預(yù)選的在瀏覽器中顯示為選中的元素。
除了代表初始選中的復(fù)選框,selectedMountains 還代表處理表單時(shí),由用戶(hù)選中的復(fù)選框。(它只代表最終選中的元素。)當(dāng)請(qǐng)求頁(yè)面時(shí),會(huì)顯示復(fù)選框。當(dāng)我在它們之間迭代時(shí),與 selectedMountains 匹配的復(fù)選框元素就是選中的元素。
清單 1 顯示了 TestForm.java 的完整代碼:
清單 1. TestForm.java
package com.strutsrecipes;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
public final class CheckboxTestForm
extends ActionForm {
// Instance Variables
/*Mountains "pre-selected"*/
private String[]
selectedMountains
=
{"Everest","K2","Lhotse"};
/*the ten tallest Mountains to iterate through*/
private String[]
mountains
=
{"Everest","K2","Kangchenjunga","Lhotse",
"Makalu","Kangchenjunga South",
"Lhotse Middle","Kangchenjunga West",
"Lhotse Shar","Cho Oyu"};
/*Getter for selectedMountains*/
public String[] getSelectedMountains() {
return this.selectedMountains;
}
/*Setter for selectedMountains*/
public void setSelectedMountains(String[] selectedMountains) {
this.selectedMountains = selectedMountains;
}
/*Getter for the mountains*/
public String[] getMountains() {
return this.mountains;
}
/*Setter for the mountains*/
public void setMountains(String[] mountains) {
this.mountains = mountains;
}
}
第 2 步. 編寫(xiě) JSP 代碼
接下來(lái),我要編寫(xiě)頁(yè)面的 JSP 代碼,把 TestForm.java 的信息傳遞給視圖層。在編寫(xiě)這個(gè)代碼時(shí),關(guān)鍵是要把對(duì)應(yīng)的 Struts 標(biāo)記庫(kù)導(dǎo)入 JSP。清單 2 的 JSP 代碼表示的是一個(gè)簡(jiǎn)單的表單,顯示復(fù)選框中相應(yīng)的框已經(jīng)選中:
清單 2. 帶有表單的 JSP
<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%>
<%-- html code, etc -->
<html:form
action="/FormAction"
name="testForm"
type="com.strutsrecipes.CheckboxTestForm">
<h4><bean:message key="testForm.instruction"/></h4>
<logic:iterate name="testForm"
property="mountains"
id="mountain">
<%-- create the checkbox and selected attribute -->
<html:multibox property="selectedMountains">
<bean:write name="mountain"/>
</html:multibox>
<%-- create the label, note that "br" tag will format it vertically -->
<bean:write name="mountain"/><br/>
</logic:iterate>
<br/>
<html:submit/><html:reset/>
</html:form>
<%-- some more html code, etc -->
注意,我用 Struts <bean:message/> 標(biāo)記表示文本,用 <html:multibox/> 表示 HTML 復(fù)選框,用 <logic:iterate/> 標(biāo)記在數(shù)組中迭代并創(chuàng)建相應(yīng)內(nèi)容。我的表單在 JSP 中通過(guò) <html:form/> 標(biāo)記被實(shí)例化。
下一步是對(duì) <logic:iterate/> 標(biāo)記中的 mountains 字段進(jìn)行迭代。在這么做的時(shí)候,我創(chuàng)建了一個(gè)變量(mountain),用它來(lái)填充復(fù)選框,并用 <bean:write/> 標(biāo)記給它一個(gè)標(biāo)簽。要在復(fù)選框中創(chuàng)建 selected 屬性,我要再次使用 <logic:iterate/> 和 <html:multibox/> 標(biāo)記。<html:multibox/> 標(biāo)記中的 property 屬性由 selectedMountains 字段填充。當(dāng) selectedMountains 等于 mountain 時(shí),selectBox 就是選中的。
第 3 步. 編寫(xiě) Action 類(lèi)
最后一步是編寫(xiě) Action 類(lèi)。清單 3 比起其他清單,做的事并不多。我做的只是得到 selectedMountains 的 String[] 數(shù)組,并使它可以用于頁(yè)面:
清單 3. 表單的 Action
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* A simple Action for Checkbox test.
*
* @author Danilo Gurovich
*/
public final class CheckboxTestAction
extends Action {
// -------------------------- OTHER METHODS --------------------------
/**
* The execute method
*
* @param mapping ActionMapping
* @param form CheckboxTestForm
* @param request HttpServletRequest
* @param response HttpServletRespons
* @return success to the confirmation page
* @throws ServletException not thrown, but could be!
* @throws Exception ditto.
*/
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, Exception {
// Extract attributes needed
String[] selectedMountains =
((CheckboxTestForm) form).getSelectedMountains()
;
System.out.println("htmlString RETURNED*\n" +
selectedMountains.toString());
//Save the htmlString in the session for later
HttpSession session = request.getSession();
session.setAttribute(CheckboxConstants.MOUNTAINS, selectedMountains);
return (mapping.findForward("success"));
}
}
擴(kuò)充 Himalayas
有了這個(gè)代碼,工作就完成了,差不多可以展示成果了!用戶(hù)現(xiàn)在可以提交 JSP 表單并在 Action 類(lèi)引用的對(duì)應(yīng)頁(yè)面中查看結(jié)果。清單 4 中的代碼段顯示了用戶(hù)在簡(jiǎn)單 JSP 頁(yè)面的表單中選中的復(fù)選框列表:
清單 4. 復(fù)選框選擇的結(jié)果
<%@taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean"%>
<%@taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic"%>
<%-- html code, etc -->
<logic:iterate id="mountain" property="mountains" name="testForm">
<bean:write name="mountain"/><br/>
</logic:iterate>
<hr size=5 color="black"/>
<%-- some more html code, etc -->
這個(gè)訣竅的工作方式
這個(gè)訣竅的關(guān)鍵是表單 bean 中的字段被傳遞到頁(yè)面。查看相關(guān) JSP 代碼有助于澄清這點(diǎn)。一旦表單 bean 被實(shí)例化:
<html:form action="/FormAction"
name="testForm"
type=" com.strutsrecipes.CheckboxTestForm">
下一步為 Java 類(lèi)的 mountains 變量中的每個(gè) mountain 創(chuàng)建一個(gè)復(fù)選框。要做到這一點(diǎn),我必須像下面這樣在 String[] 數(shù)組中迭代:
<logic:iterate id="mountain"
property="mountains"
name="testForm">
使用 <logic:iterate> 標(biāo)記,我調(diào)用了 testForm bean 中的 getMountains() 方法。它在這個(gè)數(shù)組中迭代,并把每個(gè)值作為已經(jīng)命名的 pageContext() 級(jí)的 String mountain[] 數(shù)組變量返回(即 id="mountain")。
在這里可以看到 <html:multibox/> 標(biāo)記的效果以及如何顯示它:
<html:multibox property="selectedMountains">
<bean:write name="mountain"/>
</html:multibox>
<bean:write name="mountain"/><br/>
注意 property 屬性被 selectedMountains 填充,這是我選中的變量。當(dāng)這個(gè)變量與 <html:multibox/> 值(即 multibox 標(biāo)記中的 <bean:write/>)對(duì)應(yīng)時(shí),在呈現(xiàn)表單的時(shí)候它就表現(xiàn)為選中。如果用戶(hù)選中表單或取消選中,那么新的 selectedMountains 值就被發(fā)送給 Action 類(lèi)進(jìn)行處理。這個(gè)迭代中的第二個(gè) <bean:write/> 標(biāo)記創(chuàng)建該標(biāo)記使用的標(biāo)簽,后面跟著 <br/> 標(biāo)記,讓視圖在一長(zhǎng)列中顯示這些標(biāo)記。
擴(kuò)展這個(gè)訣竅
通過(guò)使用 Struts LabelValueBean 類(lèi)代替簡(jiǎn)單的 String[] 數(shù)組,可以對(duì)動(dòng)態(tài)復(fù)選框這個(gè)訣竅進(jìn)行擴(kuò)展,從而為復(fù)選框創(chuàng)建不同的標(biāo)簽。先從添加 LabelValueBeans 到 java.util.List 開(kāi)始。然后對(duì)列表進(jìn)行迭代,把 LabelValueBeans 標(biāo)簽和值釋放到適當(dāng)?shù)奈恢谩_@個(gè)略微復(fù)雜的訣竅與動(dòng)態(tài)復(fù)選框訣竅的效果相同,但是它的結(jié)果更適合實(shí)際的用戶(hù)界面設(shè)計(jì)。清單 5 顯示了擴(kuò)展的動(dòng)態(tài)復(fù)選框訣竅:
清單 5. 添加標(biāo)簽到動(dòng)態(tài)復(fù)選框
<logic:iterate id="mountainlb"
property="mountainslb"
name="testForm">
<bean:define id="mountainbean"
name="mountainlb
"type="org.apache.struts.util.LabelValueBean"/>
<html:multibox property="selectedMountains">
<bean:write name="mountainbean"
property="value"/>
</html:multibox>
<bean:write name="mountainbean"
property="label"/><br/>
</logic:iterate>
注意,這里大的變化是用 <bean:define/> 在迭代的時(shí)候創(chuàng)建 LabelValueBean。然后用 <bean:write/> 輸出每個(gè) mountainbean 的屬性(即 org.apache.struts.util.LabelValueBean 類(lèi)的 getLabel() 和 getValue() 方法)。
結(jié)束語(yǔ)
Struts 對(duì)于復(fù)選框的動(dòng)態(tài)呈現(xiàn)和預(yù)選提供了優(yōu)秀的支持。這個(gè)訣竅是我合著 Struts Recipes 的原因 —— 那時(shí)我已經(jīng)發(fā)現(xiàn)許多與 Struts 框架相關(guān)的理論和服務(wù)器端信息,但是用戶(hù)界面編程多數(shù)被忽略了,或者被掩蓋了。在上上下下找了一圈使用 Struts 創(chuàng)建復(fù)選框的訣竅之后,我放棄了,并自己寫(xiě)了一個(gè)。通過(guò)把不同的部分組合起來(lái),我可以創(chuàng)建適合我的動(dòng)態(tài)復(fù)選框系統(tǒng)。
您會(huì)注意到,代碼示例被設(shè)置為適合用作不同用戶(hù)界面小控件和布局想法的測(cè)試溫床。實(shí)際上,我在書(shū)中的大多數(shù)用戶(hù)界面示例中都使用了它,只需要調(diào)整 Action 類(lèi)和我的模型去適合訣竅的需求而已。我還把它用在測(cè)試不同的想法上,這樣就不用在我正在處理的應(yīng)用程序內(nèi)部花太多時(shí)間為某些東西編碼了。
轉(zhuǎn)自:http://www-128.ibm.com/developerworks/cn/java/j-sr3.html
代碼下載:ftp://www6.software.ibm.com/software/developer/library/j-sr3-source.zip
posted on 2005-12-20 13:14
老妖 閱讀(590)
評(píng)論(0) 編輯 收藏