這裡使用的是jfreechart-1.0.9和struts-2.0.11
首先是JSP頁面
<%@ page language="java" pageEncoding="UTF-8"%><br /><%@ taglib prefix="s" uri="/struts-tags"%><br /><h2>請選擇您喜歡的運動項目</h2><br /><s:form action="viewResult"><br /><s:checkbox name="interest" label="籃球" fieldValue="basketball"/><br /><s:checkbox name="interest" label="氣球" fieldValue="balloon"/><br /><s:checkbox name="interest" label="排球" fieldValue="volleyball"/><br /><s:checkbox name="interest" label="足球" fieldValue="football"/><br /><s:submit value="提交"/><br /></s:form>
然後是用到的struts.xml檔案
<?xml version="1.0" encoding="UTF-8" ?><br /><!DOCTYPE struts PUBLIC<br /> "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"<br /> "http://struts.apache.org/dtds/struts-2.0.dtd"><br /><struts><br /><package name="struts2" extends="struts-default, jfreechart-default"><br /><action name="viewResult" class="com.jadyer.action.ViewResultAction"><br /><result type="chart"><br /><param name="height">600</param><br /><param name="width">800</param><br /></result><br /></action><br /></package><br /></struts><br /><!-- *******************【概述Struts2的外掛程式機制】******************************************* --><br /><!-- Struts2同Eclipse一樣也提供了外掛程式整合機制,它的外掛程式整合機制與Struts1.X的Plugin是有較大區別的 --><br /><!-- 而且它的配置方式非常非常簡單,而且具有通用性。目前為止適合於Struts2的外掛程式大概有40多種 --><br /><!-- 任何外掛程式跟Struts2整合的方式與JFreeChart跟Struts2整合的方式都是非常非常類似的,沒有太大的差異 --><br /><!-- 在Struts2中使用JFreeChart外掛程式時,一般需要以下三個JAR檔案 --><br /><!-- struts2-jfreechart-plugin-2.0.11.jar和jfreechart-1.0.9.jar和jcommon-1.0.12.jar檔案 --><br /><!-- *******************【JFreeChart外掛程式的一個BUG】***************************************** --><br /><!-- 根據Struts2網站上對使用JFreeChart外掛程式的說明中得知,這裡的result的type應該定義成chart --><br /><!-- 但是當前package繼承於struts-default包,而struts-default包中並沒有名為chart的result-type --><br /><!-- 那麼如果我們將result的type定義成chart的話,由於Struts2不認識該類型,所以伺服器啟動時就會報錯 --><br /><!-- 實際上該類型是被定義在struts2-jfreechart-plugin-2.0.11.jar中的struts-plugin.xml裡面了 --><br /><!-- 儘管外掛程式被載入進來了,但Struts2不會把外掛程式裡面的result-type自動與我們定義的result的tpye關聯 --><br /><!-- 有一個辦法可以解決問題,那就是讓我們的包繼承jfreechart-default,而不再繼承struts-default包 --><br /><!-- 這個時候就相當於我們把jfreechart-defaul包中的result-type也繼承過來了,所以就可以使用了 --><br /><!-- 但隨之而來的還有個問題,如果直接繼承jfreechart-defaul包的話,就等於不再繼承struts-default了 --><br /><!-- 那麼struts-default裡面的攔截器和其它的結果類型就都無法使用了,最後就會導致整個應用的癱瘓 --><br /><!-- *******************【修改JFreeChart外掛程式並重新打包】**************************************** --><br /><!-- 唯一辦法就是令jfreechart-default繼承struts-default包,然後我們再繼承jfreechart-default --><br /><!-- 這樣一來,也就相當於我們間接的繼承了struts-default包。這就是Struts2的包繼承所帶來的好處 --><br /><!-- 這也算是struts2-jfreechart-plugin-2.0.11.jar外掛程式的一個很小的BUG。這時就需要我們手工修改它 --><br /><!-- 首先解壓縮外掛程式,在struts-plugin.xml中增添jfreechart-default繼承struts-default包的代碼 --><br /><!-- 注意:在將檔案重新打包的時候,應該在struts2-jfreechart-plugin-2.0.11檔案夾裡面打包 --><br /><!-- 步驟:在命令提示字元中進入到F:/Javalib/Struts2/struts2-jfreechart-plugin-2.0.11>裡面 --><br /><!-- 命令:使用【jar cvf struts2-jfreechart-plugin-2.0.11.jar -C *】命令打包檔案 --><br /><!-- 當我們將result的type指定為chart之後,就沒有必要再去指定視圖了 --><br /><!-- 因為chart本身就是一種輸出,沒有必要再去指定JSP了,它會自動為我們產生出來 --><br /><!-- *******************【繼承多個包】******************************************************** --><br /><!-- Struts2的包支援多個繼承,所以我們也可以不必對其重新打包 --><br /><!-- 也就是說<package name="struts2" extends="struts-default, jfreechart-default">即可 --><br /><!-- ************************************************************************************** -->
最後是核心的Action處理類
package com.jadyer.action;<br />import java.awt.Font;<br />import java.util.List;<br />import java.util.Map;<br />import org.jfree.chart.ChartFactory;<br />import org.jfree.chart.JFreeChart;<br />import org.jfree.chart.axis.CategoryAxis;<br />import org.jfree.chart.axis.CategoryLabelPositions;<br />import org.jfree.chart.axis.NumberAxis;<br />import org.jfree.chart.plot.CategoryPlot;<br />import org.jfree.chart.plot.PlotOrientation;<br />import org.jfree.chart.title.TextTitle;<br />import org.jfree.data.category.CategoryDataset;<br />import org.jfree.data.category.DefaultCategoryDataset;<br />import com.opensymphony.xwork2.ActionContext;<br />import com.opensymphony.xwork2.ActionSupport;<br />/**<br /> * 使用JFreeChart繪製使用者投票結果的柱狀3D圖<br /> */<br />public class ViewResultAction extends ActionSupport {<br />private static final long serialVersionUID = 1935592746823978475L;</p><p>private List<String> interest;</p><p>//如果想要使用JFreeChart外掛程式的話,這裡就必須聲明一個private JFreeChart chart<br />//而且聲明的屬性名稱必須是chart,傳回值也必須是JFreeChart類型,這是暫時被硬性規定的<br />//也就是說,這個chart必須寫入程式碼到我們的程式裡面,即HardCoded。這也是當前不太完善的地方<br />//我們只需產生JFreeChart對象即可,具體輸出到視圖或響應裡面,是由JFreeChart外掛程式來完成的<br />private JFreeChart chart;</p><p>/**<br /> * 將使用者選擇的運動項目的票數加壹<br /> * @see 在真正開發中,絕對絕對不能將這樣的方法放到Action中<br /> * @see 一定要放在相應的Model裡面,因為這是一個業務處理方法<br /> */<br />private void increaseResult(List<String> list) {<br />ActionContext context = ActionContext.getContext();<br />Map map = context.getApplication(); //使用Application類比資料庫。只要不關閉瀏覽器,資料一直存在<br />for (String str : list) {<br />if (null == map.get(str)) { //如果該選項被第一次投票,就將當前選項的票數設為壹<br />map.put(str, 1); //JDK5.0提供的自動裝箱<br />} else { //如果該選項已經被投過票了,就將它的票數加壹<br />map.put(str, (Integer) map.get(str) + 1); //由於沒有用到泛型,故須強制類型轉換成Integer。此即不使用泛型的弊端<br />}<br />}<br />}</p><p>/**<br /> * 建立柱狀圖資料集<br /> * @see 這也是一個業務處理方法,實際開發中同樣也不要放到Action裡面<br /> */<br />private CategoryDataset getDataset() {<br />DefaultCategoryDataset dataset = new DefaultCategoryDataset();</p><p>//將當前的投票結果反映到ServletContext中,表示資料已更新為最新票數了<br />//這一步執行完畢之後,就會將最新的投票結果的資料放到Application中了<br />this.increaseResult(this.getInterest());</p><p>ActionContext context = ActionContext.getContext();<br />Map map = context.getApplication();</p><p>//得到Application之後,將裡面的資料放到資料集中<br />dataset.setValue((Integer) map.get("basketball"), "basketball", "籃球");<br />dataset.setValue((Integer) map.get("balloon"), "balloon", "氣球");<br />dataset.setValue((Integer) map.get("volleyball"), "volleyball", "排球");<br />dataset.setValue((Integer) map.get("football"), "football", "足球");</p><p>return dataset;<br />}</p><p>/**<br /> * JFreeChart外掛程式對象將自動調用該方法<br /> * @return 返回已經產生好的JFreeChart類型的chart對象<br /> * @see 這裡JFreeChart對象的產生依然需要我們手工來完成,這一點實際上是不太好的<br /> * @see 也就是說Struts2對JFreeChart的整合并不是很完善的,並不是很到位,我們還需要自己編代碼來產生JFreeChart對象<br /> */<br />public JFreeChart getChart() {<br />chart = ChartFactory.createBarChart3D("體育興趣投票結果", "運動項目", "投票結果", this.getDataset(), PlotOrientation.VERTICAL, false, false, false);</p><p>//重新設定標題<br />chart.setTitle(new TextTitle("體育興趣投票結果柱狀3D圖", new Font("黑體", Font.BOLD, 28)));</p><p>CategoryPlot plot = (CategoryPlot) chart.getPlot();<br />CategoryAxis categoryAxis = plot.getDomainAxis();</p><p>//設定水平軸字型的顯示樣式<br />categoryAxis.setLabelFont(new Font("宋體", Font.BOLD, 24));</p><p>//設定水平軸字型的傾斜角度<br />categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);</p><p>NumberAxis numberAxis = (NumberAxis) plot.getRangeAxis();</p><p>//設定縱軸字型的顯示樣式<br />numberAxis.setLabelFont(new Font("宋體", Font.BOLD, 22));</p><p>return chart;<br />}</p><p>@Override<br />public String execute() throws Exception {<br />return SUCCESS;<br />}</p><p>public List<String> getInterest() {<br />return interest;<br />}<br />public void setInterest(List<String> interest) {<br />this.interest = interest;<br />}<br />}