本教程將介紹在 NetBeans IDE 6.0 中如何建立頁面導航。最初在 IDE 中創建的 web 應用程序,僅使用了簡單的兩頁面間的導航。第一張頁面上的按鈕能轉至第二張頁面。而後對應用程序的修改,使其能在運行時根據下拉列表組件的返回值來決定顯示哪個頁面。您還能學到動態頁面導航的一種更高級的替代方法,即在下拉列表中作出選擇的瞬間就進行頁面導航。
學習本教程需要以下技術和資源:
JavaServer Faces 組件/ Java EE 平台 1.2 和 Java EE 5* 1.1 和 J2EE 1.4 Travel 數據庫 非必須* 為了使用 NetBeans IDE 6.0 的 Java EE 5 特性,請使用與 Java EE 5 全兼容的應用程序服務器,比如 Sun Java Application Server 9/GlassFish。
本教程專為使用 GlassFish v2 應用程序服務器做了修訂。如果您使用其他的服務器,請參考發布說明和 FAQs,了解已知的問題及其解決方法。有關受支持的服務器和 Java EE 平台的詳細信息,請參閱發布說明。
創建第一張頁面
在本教程的開始,您將創建一個僅有兩張頁面的 web 應用程序,而且在頁面之間使用按鈕進行導航。稍後,您將添加一個下拉列表組件,以使用戶能在運行時選擇目標頁面。
首先,創建一張帶有靜態文本組件和按鈕組件的頁面。
創建一個新的 web 應用程序項目,並將其命名為 NavigationExample,使用 GlassFish V2 應用程序服務器以及可視化 Web JavaServer Faces 框架。
新項目中的初始頁面會在“可視化設計器”中顯示出來。下圖展示了根據以上步驟創建出的頁面:
圖 1:頁面 1 的設計
從“組件面板”的“基本組件”中,拖動一個靜態文本組件,並將其放置在頁面中。在組件的默認文本上直接按鍵,來將組件的 text 屬性更改為 Page One。
從“組件面板”中拖拽一個按鈕組件,放置在頁面,並將其 text 屬性更改為 Go。
重要注意事項:在 IE7 中有一個已知問題會影響 JSF 1.2 按鈕組件的寬度。解決方法是將按鈕組件放置在一個布局組件中(Grid Panel、Group Panel、或者是 Layout Panel)。縮放布局組件能自動縮放該按鈕組件。
兩張頁面間的導航
接下來,在項目中添加另一張頁面,並通過創建一個鏈接或者頁面連接器來在兩張頁面間指定一個導航。
在“可視化編輯器”中編輯區域的空白處單擊鼠標右鍵,然後在彈出菜單中選擇“頁面導航”。
“頁面流編輯器”會顯示一個圖標表示 Page1.jsp ,代表在前一節中創建的頁面。注意該圖標有 4 個特征:
徽章標明該圖標表示哪一類頁面。綠色箭頭表明該頁面是項目的主頁面。
圖標上標識的文件名用以區別產品中其他頁面。
展開圖標上的加號可以顯示頁面上的組件。
連接器端口用於繪制頁面間的導航線。
按照如下步驟創建一個新的 JSP 頁面:
右鍵單擊空白處,選擇“新建文件”。
在“新建文件”對話框中,在“類別”面板選中“Java Server Faces”,在“文件類型”面板選中“可視化 Web JSF 頁面”,然後點擊“下一步”。
接受默認文件名,“Page2”,點擊“完成”。
Page2.jsp 會在“可視化設計器”中打開。點擊 Faces-config.xml 選項卡再次打開“頁面流編輯器”。圖 2 展示了包含所有頁面的“頁面流編輯器”。
點擊 Page1.jsp 圖標上的加號來將其放大,這樣就能看到 button1 圖標了。
點擊 button1 圖標,並拖拽一條線至 Page2.jsp 圖標。這時會出現一個連接器,錨在第一張頁面,而指向第二張頁面。默認情況下,新創建的連接器被命名為 case1。
雙擊該連接器的名稱,並將該名稱從 case1 改為 Page 2。
下圖展示了“頁面流編輯器”以及兩張頁面之間的連接器。
圖 2:頁面流編輯器
點擊編輯工具欄中的“XML”,查看一下在前面兩步中所生成的代碼。下面粗體顯示的“navigation-rule”被添加在省略號(...)所表示的受管 bean 代碼下面。
代碼示例 1:生成的代碼
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
...
<navigation-rule>
<from-view-id>/Page1.jsp</from-view-id>
<navigation-case>
<from-outcome>Page 2</from-outcome>
<to-view-id>/Page2.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
在 faces-config 標簽中所添加的代碼指定了用於此 web 應用程序的單向導航規則。每個導航規則指定了一張原始頁面,以及一張或者多張目標頁面。
在第二張頁面中添加組件
現在向第二張頁面中添加一個標簽,以便在視覺上和第一張頁面區別開來,然後運行應用程序。
點擊編輯工具欄中的“頁面流”。
雙擊 Page2.jsp 圖標。
頁面會在“可視化設計器”中打開。
在頁面中放置一個靜態文本組件,然後將其 text 屬性更改為 Page Two,如下圖所示。
圖 3:頁面 2 的布局
按下“F6”鍵部署應用程序。
Web 應用程序部署後,“Page One”會在浏覽器中打開,如下圖所示:
圖 4:使用簡單導航 Web 應用程序
點擊“Go”按鈕,將帶您從第一張頁面導航至第二張頁面。
在本節中,您創建了兩張頁面,並建立了從一張頁面到另一張頁面的簡單導航。在下一節中,您將基於下拉列表組件中的選擇來建立導航。
添加用於動態導航的下拉列表
現在您將學習有關動態導航的內容。在應用程序中的第一張頁面中添加一個下拉列表組件。下拉列表允許用戶在運行時選擇目標頁面。之後,在應用程序中加入第三張頁面,這樣下拉列表就包含了兩個目標選項。
下圖展示了上述步驟對頁面 1 所做的改動:
圖 5:修改後第一張頁面的布局
在“可視化設計器”中打開 Page1.jsp。
在靜態文本組件下方放置一個下拉列表組件。
右鍵點擊該下拉列表,選擇“配置默認選項”。
在標為“選項定制器 - dropDown1”的對話框中,將每項默認條目的值更改為下圖中所給出的值。點擊每個表項來編輯其值,編輯每個域後按下“Enter”鍵接受改動。
圖 6:“選項定制器”對話框
點擊“確定”保存所有改動。
添加第三張頁面
接下來創建第三張頁面,第一張頁面可以導航至該頁面。
在“項目”窗口中,右鍵點擊“NavigationExample”>“Web 頁面”節點,選擇“新建”>“可視化 Web JSF 頁面”。在“新建可視化 Web JSF 頁面”向導中,點擊“完成”。IDE 會創建並顯示 Page3.jsp。
從“組件面板”中拖拽一個靜態文本組件,並放置在頁面中。設置組件的文本為 Page Three。
實現動態頁面導航
在本節中,將啟動動態頁面導航功能。通過動態導航,應用程序可在運行時決定當用戶點擊第一張頁面中的“Go”按鈕時該顯示哪個頁面。
打開“頁面流編輯器”。
點擊 Page1.jsp 圖標顯示其內容,然後從按鈕的連接器端口拖拽一條連接器線至 Page3.jsp 圖標。
將連接器的名稱 case1 更改為 Page 3。
雙擊 Page1.jsp 圖標,並在編輯工具欄中點擊“設計”來顯示頁面 1 的布局。
雙擊“Go”按鈕組件,在“Java 編輯器”中顯示其動作處理方法的源代碼。
將方法中的 return 語句替換成下面粗體顯示的代碼:
重要注意事項:NetBeans IDE 6.1 加入了按需幫定的特性。故如果您正在使用 NetBeans IDE 6.1,您必須手動向“Page 1”的下拉列表組件添加一條幫定屬性。要
完成該動作,右鍵點擊組件,然後選擇“添加幫定屬性”。
代碼示例 2:return 語句
public String button1_action() {
return (String) dropDown1.getValue();
}
部署應用程序
測試頁面間的導航。
按下“F6”鍵部署應用程序。
在第一張頁面中,從下拉列表中選擇“Page 2”,然後點擊“Go”轉至第二張頁面。
點擊浏覽器中的“後退”按鈕,從第二張頁面返回至第一張頁面。
現在從下拉列表中選擇“Page 3”,然後點擊“Go”將轉至第三張頁面。
實現高級動態頁面導航
在前一節中,動態導航是以一種直接的方式被處理的。用戶在下拉列表中選擇想要浏覽的頁面,然後點擊“Go”按鈕。如果您想要在下拉列表中選擇改動的同時進行頁面切換,那請您按照如下步驟來修改您在前面章節中所創建的項目。
選擇“Page1”選項卡,點擊編輯工具欄中的“設計”切換至“可視化設計器”。
右鍵點擊“Go”按鈕,選擇“刪除”。
雙擊下拉列表組件,打開“Java 編輯器”來查看 Page1 的類代碼。
將下面粗體顯示的代碼添加到 dropDown1_processValueChange() 處理方法。代碼的前兩行會獲取一個應用程序的對象引用。然後通過該對象獲取一個“導航處理器”(NavigationHandler)的實例。調用該實例的 handleNavigation() 方法時指定的值就是從下拉列表組件返回的值,該值指示要浏覽的頁面。
代碼示例 3:“導航處理器”(Navigation Handler)方法
public void dropDown1_processValueChange(ValueChangeEvent event) {
Application application = getApplication();
NavigationHandler navigator = application.getNavigationHandler();
FacesContext facesContext = getFacesContext();
navigator.handleNavigation(facesContext,
null,(String) dropDown1.getValue());
}
注意,紅色的波浪線說明找不到類 Application、NavigationHandler 和 FacesContext 。您將在下一步中導入這些類。
在“源代碼編輯器”中任意地方單擊鼠標右鍵,選擇“修復導入”來自動添加下列導入語句到源文件的頂部:
代碼示例 4:用於“導航處理器”(Navigation Handler)方法的導入語句
import javax.faces.application.Application;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
在編輯工具欄中點擊“設計”打開“可視化設計器”查看“Page1”。
右鍵點擊下拉列表組件,選擇“自動提交改動”來指明被選中的條目將在選中時被自動提交。
部署並運行應用程序。
在下拉列表中選擇“Page 2”條目,從第一張頁面導航至第二張頁面。點擊“後退”按鈕返回到第一張頁面。
在下拉列表中選擇“Page 3”條目,從第一張頁面導航至第三張頁面。
更進一步:處理大量頁面
本教程中介紹的場景只能處理較少的頁面,而大多數現實世界中的應用程序則要求導航大量頁面。要建立這種導航:
在“頁面導航”編輯器中,點擊編輯工具欄中的“XML”按鈕。
添加如下列 XML 中的第一項所示的導航規則。設置 <from-view-id> 為 /*,設置 <from-outcome> 為方便於其他頁面區分的字符串,並將 <to-view-id> 設置為目標頁面。
代碼示例 5:用於大量頁面應用程序的頁面導航 XML 代碼
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<navigation-rule>
<from-view-id>/*</from-view-id>
<navigation-case>
<from-outcome>login</from-outcome>
<to-view-id>/Page3.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/Page1.jsp</from-view-id>
<navigation-case>
<from-outcome>case1</from-outcome>
<to-view-id>/Page2.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
當返回到“頁面導航”編輯器時,編輯器可能顯示一些錯誤,不過這些錯誤可被忽略。
在要向頁面發送消息的動作組件的動作處理方法中,要返回 from-outcome(本例中是 "login"),如下所示:public String button1_action() {
return "login";
}
小結
實現頁面導航的典型工作流一般如下所示:
創建頁面。
在頁面上放置支持導航的組件,比如按鈕和下拉列表。
使用“頁面流編輯器”,在組件和頁面之間繪制連接器。
使用 dropDown1_processValueChange() 處理方法實現更高級的導航。