中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java 2D 繪圖的開放源代碼備用方案 (轉)

發布時間:2020-08-09 11:37:07 來源:ITPUB博客 閱讀:171 作者:worldblog 欄目:編程語言
Java 2D 繪圖的開放源代碼備用方案 (轉)[@more@]
Java 2D 可能是在 Java 程序中編寫 2D 圖形程序的最顯著的解決方案,但它不是唯一的一個。在本文中,Java 開發者 John Carr 提出了一種優秀的備用方案 — “Java 科學對象”(Java objects for Science(JSci)),一個開放源代碼的包,它使您能夠在 swing 中創建 2D 條形圖、餅形圖和折線圖。請在Javascript:void%20forumWindow()">討論論壇與本文作者和其他讀者分享您對本文的心得。

對于大多數 Java 開發者,任何類型的圖形開發在本質上都與 Java 2D 和 3D api 以及 java.awt.Graphics 有緊密聯系。雖然 Java 2D 和 3D API 為在 Swing 中創建圖形提供優秀的工具,但您并非只可以任意使用它們,當然它們也不是最容易學的。對于那些沒有時間、需要或有興趣熬夜深刻了解 java.awt.Graphics 的人,我向您推薦一個開放源代碼的備用方案:JSci。

Java 科學對象(JSci)開放源代碼項目是 Durham(英國 Durham)大學粒子理論中心的三年級研究生 Mark Hale 創立的。JSci 是一個包集合,包含數學和科學類。 在撰寫本文時,JSci 的版本是 .87,運行在 Java 1.1.8、1.2.x 或 1.3.x 上,但將來可能為 Java 1.4 寫更新版本的 JSci。這個項目的目的是以可能有助于基于科學的軟件開發的最自然方式封裝科學方法和原則。支持 JSci 的設計哲學是基于這樣一種思想 — “直接從黑板到代碼”。也就是,數學概念和構造應該以某種方式封裝在代碼中。在某種程度上,JSci 作為對象設計實驗與作為數學庫差不多。

使用 JSci,您既可以在 AWT 中也可以在 Swing 中創建簡單的條形圖、折線圖和餅形圖。JSci.swing.JBarGraph JSci.swing.JPieChartJSci.swing.JLineGraph API 組件設計得也很好,這些組件和 AWT 繪圖類都遵守 Mvc 體系結構。

在本文中,我將介紹 JSci.swing 包并向您展示如何使用它的類和方法創建條形圖、餅形圖和折線圖。我們將首先看一下組成包的核心的類。

JSci.swing 包
用于在 Swing 中創建圖形的類位于 JSci.swing 包中。圖 1 顯示了 JSci.swing 的類圖表。JSci.swing 中的類,除 JImageCanvas 之外,都從 JDoubleBufferedComponent 繼承。注意:JDoubleBufferedComponentJImageCanvas 都是從 javax.swing.JComponent 繼承的。

我們將在下面部分詳細討論每個類的功能。

JDoubleBufferedComponent
JSci.swing 的超類是一個抽象類,被稱為 JDoubleBufferedComponent。這個類相對來說比較簡單,它為自己將要建立于其上的圖形提供雙緩沖功能。 雙緩沖指出接收組件是否應該使用緩沖區來繪畫。如果雙緩沖被設置為 true,那么來自這個組件的所有圖畫都將在屏外(offscreen)繪畫緩沖區完成。屏外繪畫緩沖區稍后將被復制到屏幕上。根據 javadocs,Swing 繪畫系統總是使用最大的雙緩沖區。如果一個組件有緩沖,而且它的其中一個父組件也有緩沖,那么就使用它的父組件的緩沖區。

JDoubleBufferedComponent 依靠自己而不是 Swing 的雙緩沖實現 JComponent 處理雙緩沖。這為使用 JSci.swing 包的開發者提供了比只使用 Swing 更細粒度的對雙緩沖的控制。

JImageCanvas
JImageCanvas 是另一個簡單的(straightforward)類。它的目的是允許圖像被直接添加到容器。 JImageCanvas 創建一個 java.awt.MediaTracker 實例來裝入和跟蹤圖像。

JContourPlot
contour plot 是 3 個數字變量之間關系的二維圖解表示。兩個變量用于 x 軸和 y 軸,第 3 個變量 z 用于等高位。等高位被繪制成曲線;曲線之間區域的顏色編碼表示內插值。

JGraph3D
JGraph3D 超類提供 2D 圖形的抽象封裝。JScatterGraphJLineGraph 都繼承了 JGraph3D散點圖是一種統計圖,被繪制用來比較兩個數據集。可用它來發現兩個數據集之間的相關性。 折線圖顯示兩段信息之間的關系,以及它們是如何依賴另一方發生變化的。 沿著折線圖一條邊的數字被稱為刻度。在后面我將更詳細地討論折線圖以及如何構造一個折線圖。

JCategoryGraph3D
JCategoryGraph3D 超類提供 2D 圖形分類的抽象封裝。JBarGraphJPieChart 都繼承了 JCategoryGraph3D。一個條形圖由一個坐標軸和一系列帶標簽的水平或垂直條組成,它們顯示每個條的不同值。 餅形圖是一個被分成若干部分的圓形圖,每部分顯示一些相關信息片段的大小。餅形圖被用于顯示組成整體的各部分的大小。我們將在后面討論關于構造餅形圖和條形圖的更多內容。

JLineGraph4D 和 JL.NETrace
如果您覺得自己需要挑戰,那么請嘗試 JLineGraph4D。如名稱所暗示的那樣,JLineGraph4D 允許您向折線圖中添加第三維。JLineGraph4D 不單是讓您按照 x(水平)和 y(垂直)來考慮,而是讓您把 z(深度)也考慮在內。JLineTrace 允許您使用鼠標偵聽器跟蹤 2D 折線圖。

構造一個 JPieChart
要構造任何形狀的圖形,您都必須理解如何用一種有意義的方式來組織數據。不管是構造條形圖還是構造餅形圖,當涉及到數據建模時,其過程都是相同的。圖 2 提供一個數據示例,它可用于創建條形圖或餅形圖。

圖 2. 用于創建條形圖或餅形圖的示例數據
2003-10-241628580.gif" width=165>

一個 series 表示一個數字數組。對于 JPieChart,series 可以是 float 類型或 double 類型。一個 category 表示一個 series 內的數據列標識符。對于 JPieChart,category 用 String 形式表示。當然,您希望有一個對您的觀眾來說有些意義的 category,這就是為什么一個城市名看起來好象適合 PieGraph.java 中餅形圖示例中的每個 category 的原因所在。為簡單起見,餅形圖將只用一個數據 series。清單 1 分別包含 category 和 series 類變量。

清單 1. 為餅形圖定義 x 軸和數據 series

// ... public class PieGraph extends JFrame implements ItemListener { // ... private static final String CATEGORY_NAMES[] = { "London", "Paris", "New York" }; private static final float CONSUMERS_SERIES[] = { 45.3f, 27.1f, 55.5f }; // ... }



現在,已經定義了 CONSUMERS_NAMESSALES_SERIES 數組,我們就可以開始構造餅形圖。這個示例中使用的模型是 DefaultCategoryGraph3DModel。在下一部分,我將更深入地討論該模型的工作機制。清單 2 顯示如何創建一個 DefaultCategoryGraph3DModel 實例。

清單 2. 創建一個 DefaultCategoryGraph3DModel 實例

// ... private JPieChart getPieGraph() { // ... DefaultCategoryGraph3DModel model = new DefaultCategoryGraph3DModel(); model.setCategories(CATEGORY_NAMES); model.addSeries(CONSUMERS_SERIES); // ... } // ...



在實例化 DefaultCategoryGraph3DModel 之后,category 和 series 一定包含在這個模型中。通過 setCategories(String categoryNames[]) 方法設置一個 category。因為這個模型允許多個 series,所以方法 addSeries(float series[])addSeries(double series[]) 可用于這個目的。DefaultCategoryGraph3DModel 將每個增加的 series 存儲在 Vector 中。

這個 model 實例現在可用作 JPieChart 的構造器的一個輸入參數。 在創建了 JPieChart 實例后,可用 setColor(int category, java.awt.Color c) 方法定義每個 category 的顏色。 清單 3 顯示了如何創建 JPieChart 實例和設置 category 顏色。

清單 3. 設置餅形圖扇形塊顏色

// ... public class PieGraph extends JFrame implements ItemListener { // ... private static final int LONDON = 0; private static final int PARIS = 1; private static final int NEW_YORK = 2; // ... private JPieChart getPieGraph() { // ... JPieChart pieChart = new JPieChart(model); pieChart.setColor(LONDON,Color.blue); pieChart.setColor(PARIS,Color.yellow); pieChart.setColor(NEW_YORK,Color.orange); // ... } // ...



圖 3 用圖解形式說明了使用 PieGraph.java 創建的餅形圖。當用戶請求更改 category 的顏色(通過應用程序右邊的列表框)時,方法 JPieChart.setColor(int category, java.awt.Color c) 被調用來實現這種更改。要使這種更改可見,在設置了新的扇形塊顏色后調用 JPieChart.redraw() 方法。

圖 3. PieGraph.java 生成的餅形圖的輸出示例
PieGraph.java 生成的餅形圖的輸出示例

我們只討論了 DefaultCategoryGraph3DModel 用途的一些皮毛。其它還有許多有用的方法,包括允許您隱藏 series 的方法(setSeriesVisible(int series, boolean visible))或更改 series 數據的方法(changeSeries(int series, float newSeries[]))。 我鼓勵您在有空的時候更深入地研究這些類(請參閱sources">參考資料)。

構造一個 JBarGraph
構造一個條形圖首先必須象在構造餅形圖中那樣為數據建模。條形圖,和餅形圖一樣,有一個數據 series 數組(或多個)和一個 category 數組。我不使用 DefaultCategoryGraph3DModel 作為條形圖的模型,而是將說明如何為您的數據創建一個定制模型,以及 JBarGraph 怎樣在運行時期間使用這個模型生成條形圖。為使這個練習更加有趣,我將向您展示如何動態地更改 series 元素的值和重畫條形圖。

如圖 4 所示,一個定制 category 圖模型必須繼承 AbstractGraphModel 并實現 CategoryGraph3DModel(參見 SalesGraphModel.java)。注意:這部分涉及的方法繼承自 CategoryGraph3DModel 接口。

圖 4. 創建一個定制 category 圖模型
創建一個定制 category 圖模型

表 1 展示了 CategoryGraph3DModel 接口的方法以及 JBarGraph 如何在運行時利用模型。

表 1. CategoryGraph3DModel 接口

方法描述 public abstract void addGraphDataListener(GraphDataListener) 添加一個偵聽器 public abstract void firstSeries() 選擇第 1 個數據 series public abstract String getCategory(int i) 返回第 i 個 category public abstract float getValue(int i) 返回第 i 個 category 的值 public abstract boolean nextSeries() 選擇下一個數據 series public abstract void removeGraphDataListener(GraphDataListener) 除去一個偵聽器 public abstract int seriesLength() 返回當前 series 的長度

讓我們看一下這些方法的較為詳細一點的信息。

在運行時,JBarGraph 調用 public void firstSeries(),它選擇第 1 個數據 series。如果您正在處理多個數據 series,將它們存儲在 Vector 中是有意義的。調用的下一個方法是 public int seriesLength();這個方法返回當前 series 的長度。seriesLength() 方法返回的整型值被用于形成一個循環構造來獲取每個 category 以及那個 series 的相應整型值。在這個 series 循環中,調用 public String getCategory(int i) 獲取第 i 個 category 的名稱,并調用 public float getValue(int i) 獲取第 i 個 category 的值。(術語第 i 個是指 category 的順序,比如第 1、第 2、第 3 等等。)為當前 series 收集了全部數據元素后,調用 public boolean nextSeries() 方法選擇下一個數據 series。如果 nextSeries() 方法返回 true,那么為新數據 series 收集數據元素的過程將重新開始 — 從 seriesLength() 方法開始。當 nextSeries() 返回 false 時,模型中不再有數據 series。

BarGraph.javaSalesGraphModel 繼承 AbstractGraphModel 并實現 CategoryGraph3DModel。為簡單起見,將 SalesGraphModel 配置為只處理一個數據 series。如果您查看 SalesGraphModel 中的 nextSeries() 方法,您會注意到它只返回 false;這表明這個模型內只包含一個數據 series。傳給 SalesGraphModel 構造器的輸入參數包括 category 的名稱和一個數據 series。創建 SalesGraphModelJBarGraph 實例的代碼可在清單 4 的 getBarGraph() 方法中找到。

清單 4. 創建一個 JBarGraph

// ... public class BarGraph extends JFrame implements ActionListener { // ... private static final String CATEGORY_NAMES[] = { "London", "Paris", "New York" }; // ... private static final float SALES_SERIES[] = { 24.1f, 14.4f, 36.8f }; // ... private JBarGraph getBarGraph() { SalesGraphModel model = new SalesGraphModel(CATEGORY_NAMES, SALES_SERIES); barGraph = new JBarGraph(model); return barGraph; } // ...


圖 5 顯示 BarGraph.javaSalesGraphModel.java 產生的輸出。您或許已注意到,所有的 category 條顏色都一樣,這與餅形圖示例相反,在餅形圖示例中,每個 category 的顏色都不同。這是因為 JBarGraph 只允許您改變數據 series 的顏色表示,而不是 series 內的 category。

圖 5. BarGraph.java 生成的條形圖的輸出示例
BarGraph.java 生成的條形圖的輸出示例

SalesGraphModel 具有允許在數據 series 內增加 category 值的功能。當用戶從 BarGraph 示例選擇了一個 category(通過單選按鈕)并按下“Add 1 to total”按鈕時,public void incrementCategoryTotal(int i) 方法被調用。這個方法把選中要增加的 category 作為方法參數傳遞,傳遞后會有一個通知被發送到 JBarGraph 實例(通過 public void dataChanged(GraphDataEvent) 方法):模型中的數據已經發生改變,必須重畫此條形圖。清單 5 顯示了增加 category 總數的過程。

清單 5. 增加 category 總數

// ... public class BarGraph extends JFrame implements ActionListener { private void addToCategoryTotal(int category) { SalesGraphModel model = (SalesGraphModel)barGraph.getModel(); model.incrementCategoryTotal(category); } // ... } // ... public class SalesGraphModel extends AbstractGraphModel implements CategoryGraph3DModel { // ... private float seriesTotals[]; // ... public void incrementCategoryTotal(int i) { seriesTotals[i]++; } // ... }



構造一個 JLineGraph
JLineGraph 的模型與 JPieChartJBarGraph 的模型相似;這兩個模型都有多個數據 series 和一個標識 series 內數據的 category。但 JLineGraph 的模型引入了 x 軸和 y 軸坐標系的復雜性,在這一部分,我將研究如何創建一個定制的模型,并展示 JLineGraph 是如何在運行時期間使用這個模型生成一個折線圖的。注意:這一部分涉及的方法繼承自 Graph3DModel 接口。

一個定制的折線圖模型必須要從 AbstractGraphModel 繼承并實現 Graph3DModel 接口,如表 2 中所示。

表 2. Graph3DModel 接口

方法描述 public abstract void addGraphDataListener(GraphDataListener) 添加一個偵聽器 public abstract void firstSeries() 選擇第 1 個數據 series public abstract float getXCoord(int i) 返回第 i 個 category public abstract float getYCoord(int i) 返回第 i 個 category 的值 public abstract boolean nextSeries() 選擇下一個數據 series public abstract void removeGraphDataListener(GraphDataListener) 除去一個偵聽器 public abstract int seriesLength() 返回當前 series 的長度

這些方法的執行與表 1 中所示的相似。

在運行時期間,JLineGraph 調用 public void firstSeries() 方法;這選擇第 1 個數據 series。調用的下一個方法是 public int seriesLength();它返回當前 series 的長度。seriesLength() 方法返回的整型值被用于形成一個循環構造以獲取那個 series 的 x 軸和 y 軸坐標值。在這個 series 循環中,調用 public float getXCoord(int i) 獲取第 i 個 category,并調用 public float getYCoord(int i) 獲取第 i 個 category 的值。為當前 series 收集了全部數據元素后,調用 public boolean nextSeries() 方法選擇下一個數據 series。如果 nextSeries() 方法返回 true,那么為新數據 series 收集數據元素的過程將重新開始 — 從 seriesLength() 方法開始。如果 nextSeries() 返回 false,那是因為模型中不再有數據 series。

缺省情況下,JLineGraph 只接受 x 軸和 y 軸的浮點值。在我的折線圖中,x 軸應該包含代表一年中前六月(一月到六月)的 String。要完成這個任務,必須發生兩件事:第一,必須繼承 Graph3DModel 接口以包含 public String getXLabel(float i) 方法。這樣您就能夠獲得 x 軸的 String 表示。第二,必須繼承 JLineGraph,并覆蓋 drawLabeledAxes(Graphics g) 方法。這一步將允許您使用新的接口訪問 getXLabel(float f) 方法。圖 6 是一個類圖表, 顯示創建一個帶標簽的折線圖涉及的類。

圖 6. 帶標簽折線圖的類圖表

創建 DemandGraphModelJLineGraph 類的實例代碼可在 getLineGraph() 方法中找到,清單 6 中顯示了這些代碼。

清單 6. 創建一個 JLineGraph 實例

// ... public class LineGraph extends JFrame { private JLineGraph lineGraph; private static final String MONTH_NAMES[] = { "Jan", "Feb", //... }; private static final int MONTH_NUMBERING[] = {0, 1, 2, 3, 4, 5 }; private static final int LONDON_SERIES = 0; private static final int PARIS_SERIES = 1; private static final int NEW_YORK_SERIES= 2; private static final float LONDON_DEMAND[] = { 1.2f, 3.7f, 6.7f, // ... }; private static final float PARIS_DEMAND[] = { 12.6f, 15.0f, 13.7f, // ... }; private static final float NEW_YORK_DEMAND[] = { 15.0f, 13.9f, 10.1f, // ... }; // ... private JLineGraph getLineGraph() { DemandGraphModel model = new DemandGraphModel(); model.addSeries(LONDON_DEMAND); model.addSeries(PARIS_DEMAND); model.addSeries(NEW_YORK_DEMAND); model.setXAxisLabel(MONTH_NAMES); model.setXAxis(MONTH_NUMBERING); lineGraph = new LabeledLineGraph(model); lineGraph.setColor(LONDON_SERIES, Color.red); lineGraph.setColor(PARIS_SERIES, Color.yellow); lineGraph.setColor(NEW_YORK_SERIES, Color.blue); lineGraph.setXIncrement(1); return lineGraph; } // ... }



清單 6 的最后一行顯示了對 LabeledLineGraph setXIncrement(int i) 方法的一次調用。完成這次調用是為了確保 x 軸是按照嚴格的增量畫的。換句話說,JLabeledLineGraph 將用最大化應用程序窗口或浮動窗口的相同坐標來標記 x 軸上的每一“格”。圖 7 顯示了 LineGraph.java 產生的輸出示例。調整應用程序窗口的大小,看看折線圖是如何被重畫以適合窗口新尺寸的。

圖 7. LineGraph.java 生成的折線圖的輸出示例
LineGraph.java 生成的折線圖的輸出

結論
JSci 是一個開放源代碼成果,主要用于科學應用。在本文中,我已經介紹了作為創建 2D 圖形工具的 JSci 的一些可能用途。JSci 是專業繪圖包的備用的免費軟件。雖然 JSci 并不提供專業畫圖包所帶的內建類型支持,您卻的確可以訪問源代碼,并且可以自由修改代碼,然后將它們提交回 JSci 社區。JSci 是一個不斷發展的成果,我認為它是一個很好的備用方案,您在用 Java 創建 2D 圖形時可以考慮使用它。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沐川县| 德令哈市| 肃宁县| 万盛区| 天镇县| 马山县| 榕江县| 阿瓦提县| 蓬溪县| 安丘市| 行唐县| 文安县| 汤阴县| 宁武县| 珲春市| 西乡县| 镇赉县| 德州市| 沐川县| 阳东县| 密云县| 延安市| 怀仁县| 阜新| 鄂托克旗| 宁晋县| 横山县| 南木林县| 曲麻莱县| 永兴县| 青州市| 东乡族自治县| 榕江县| 九龙县| 南昌县| 鄂托克前旗| 辽源市| 通河县| 屏山县| 吉林市| 三亚市|