2016年10月8日 星期六

JavaFX遊戲程式設計 (第三版)

2016年的第一本新書 –「JavaFX遊戲程式設計 (第三版)」,我的第35本繁體專書。

章節包括:

  1. JavaFX.
  2. 事件.
  3. 繪圖.
  4. 特殊效果.
  5. 動畫.
  6. 井字遊戲 (Tic Tac Toe).
  7. 拼圖 (Puzzle).
  8. 曲棍球 (Hockey).
  9. 孔明棋 (Peg Solitaire).
  10. 黑白棋 (Reversi).
  11. 西洋跳棋 (Checker).
  12. 翻翻樂 (Matching Card).
  13. 新接龍 (Free Cell).
  14. 俄羅斯方塊 (Tetris).
  15. 踩地雷 (Mine Sweeper).
  16. 數獨 (Sudoku).
It is my new book, JavaFX Game Programming (3rd edition), in 2016. It covers the following chapters:
  1. Introduction to JavaFX.
  2. JavaFX Event.
  3. 2D Graph.
  4. Effect.
  5. Timeline and Transition.
  6. Tic Tac Toe).
  7. Puzzle.
  8. Hockey.
  9. Peg Solitaire.
  10. Reversi.
  11. Checker.
  12. Matching Card.
  13. Free Cell.
  14. Tetris.
  15. Mine Sweeper.
  16. Sudoku.
© Chia-Hui Huang

2016年4月17日 星期日

JavaFX 3D - Icosidodecahedron

以下是以JavaFX 8的TriangleMesh類別建構之Icosidodecahedron (截半二十面體),屬於Archimedean Solid (阿基米德立體)。

float C0 = length * (float) (1.0 + Math.sqrt(5.0)) / 4.0f;
float C1 = length * (float) (3.0 + Math.sqrt(5.0)) / 4.0f;
float C2 = length * (float) (1.0 + Math.sqrt(5.0)) / 2.0f;
float C3 = length * 0.5f;

// 建立TriangleMesh
TriangleMesh trianglemesh = new TriangleMesh();

// 設定頂點座標
trianglemesh.getPoints().addAll(
  0.0f, 0.0f,   C2,
  0.0f, 0.0f,  -C2,
    C2, 0.0f, 0.0f,
   -C2, 0.0f, 0.0f,
  0.0f,   C2, 0.0f,
  0.0f,  -C2, 0.0f,
    C3,   C0,   C1,
    C3,   C0,  -C1,
    C3,  -C0,   C1,
    C3,  -C0,  -C1,
   -C3,   C0,   C1,
   -C3,   C0,  -C1,
   -C3,  -C0,   C1,
   -C3,  -C0,  -C1,
    C1,   C3,   C0,
    C1,   C3,  -C0,
    C1,  -C3,   C0,
    C1,  -C3,  -C0,
   -C1,   C3,   C0,
   -C1,   C3,  -C0,
   -C1,  -C3,   C0,
   -C1,  -C3,  -C0,
    C0,   C1,   C3,
    C0,   C1,  -C3,
    C0,  -C1,   C3,
    C0,  -C1,  -C3,
   -C0,   C1,   C3,
   -C0,   C1,  -C3,
   -C0,  -C1,   C3,
   -C0,  -C1,  -C3  
);

// 設定貼圖座標
trianglemesh.getTexCoords().addAll(
  0.50f, 1.0f,
  0.75f, (float) (1.0-Math.sqrt(3.0)/4.0f),
  0.25f, (float) (1.0-Math.sqrt(3.0)/4.0f),
  1.00f, 1.0f,
  0.50f, (float) (1.0-Math.sqrt(3.0)/2.0f),
  0.00f, 1.0f
);

// 設定各三角形的面
trianglemesh.getFaces().addAll(
   0, 2,  6, 1, 10, 4,
   0, 2, 12, 1,  8, 4,
   1, 2,  9, 1, 13, 4,
   1, 2, 11, 1,  7, 4,
  14, 2, 16, 1,  2, 4,
  14, 2, 22, 1,  6, 4,
  17, 2, 15, 1,  2, 4,
  17, 2, 25, 1,  9, 4,
  19, 2, 21, 1,  3, 4,
  19, 2, 27, 1, 11, 4,
  20, 2, 18, 1,  3, 4,
  20, 2, 28, 1, 12, 4,
  23, 2,  4, 1, 22, 4,
  23, 2, 15, 1,  7, 4,
  24, 2,  5, 1, 25, 4,
  24, 2, 16, 1,  8, 4,
  26, 2,  4, 1, 27, 4,
  26, 2, 18, 1, 10, 4,
  29, 2,  5, 1, 28, 4,
  29, 2, 21, 1, 13, 4,
   0, 0,  8, 1, 16, 2,
   0, 0, 16, 1, 14, 2,
   0, 0, 14, 1,  6, 2,
   0, 0, 10, 1, 18, 2,
   0, 0, 18, 1, 20, 2,
   0, 0, 20, 1, 12, 2,
   1, 0,  7, 1, 15, 2,
   1, 0, 15, 1, 17, 2,
   1, 0, 17, 1,  9, 2,
   1, 0, 13, 1, 21, 2,
   1, 0, 21, 1, 19, 2,
   1, 0, 19, 1, 11, 2,
   2, 0, 15, 1, 23, 2,
   2, 0, 23, 1, 22, 2,
   2, 0, 22, 1, 14, 2,
   2, 0, 16, 1, 24, 2,
   2, 0, 24, 1, 25, 2,
   2, 0, 25, 1, 17, 2,
   3, 0, 18, 1, 26, 2,
   3, 0, 26, 1, 27, 2,
   3, 0, 27, 1, 19, 2,
   3, 0, 21, 1, 29, 2,
   3, 0, 29, 1, 28, 2,
   3, 0, 28, 1, 20, 2,
   4, 0, 23, 1,  7, 2,
   4, 0,  7, 1, 11, 2,
   4, 0, 11, 1, 27, 2,
   4, 0, 26, 1, 10, 2,
   4, 0, 10, 1,  6, 2,
   4, 0,  6, 1, 22, 2,
   5, 0, 24, 1,  8, 2,
   5, 0,  8, 1, 12, 2,
   5, 0, 12, 1, 28, 2,
   5, 0, 29, 1, 13, 2,
   5, 0, 13, 1,  9, 2,
   5, 0,  9, 1, 25, 2
);

// 設定各面的平滑參數
trianglemesh.getFaceSmoothingGroups().addAll(
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0,
  0, 0, 0, 0
);

// 建立MeshView
MeshView meshview;

meshview = new MeshView(createMesh(100));
...
【參考資料】

[1] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[2] JavaFX:http://www.oracle.com/technetwork/java/javafx
[3] JavaFX 8.0 API Specification.
[4] Java Platform, Standard Edition 8 API Specification.
[5] JDK 8 Certified System Configurations.
[6] H. M. Cundy, A. P. Rollett, Mathematical Models, Tarquin Publications, 1981.
[7] G. Sellers, R. S. Wright, N. Haemel, OpenGL SuperBible: Comprehensive Tutorial and Reference (6th Edition), Addison-Wesley Professional, 2013.
[8] 黃嘉輝, JavaFX 8技術手冊, ISBN: 9789863474050, 碁峰資訊, 2014.

© Chia-Hui Huang

2016年2月27日 星期六

SAP Business Intelligence - Radio Button

選擇鈕或選項按鈕 (Radio Button) 是由數個選擇鈕群組而成,為圓圈狀且僅能單選的選取器。

與選擇鈕類似的選取器是核取方塊 (Check Box),核取方塊可由1至數個核取方塊群組而成,為方格狀且能複選的選取器。

透過選擇鈕或核取方塊可將資料依不同的條件篩選出不同的結果,以建立圖表互動,讓圖表更加多樣化。



【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-選擇鈕 (Radio Button),國立臺北商業大學。

© Chia-Hui Huang

SAP Business Intelligence - Gauge

儀錶圖 (Gauge) 如同汽車儀錶板,以圓形的刻度顯示範圍值。與儀錶圖類似的單一值是刻度盤 (Dial),刻度盤同樣為圓形的刻度顯示器,差別在於刻度盤通常用來選擇值,而儀錶圖則多用來顯示值。此外,儀錶圖常搭配警示屬性,以顏色區分不同的範圍值。


【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-儀錶圖 (Gauge),國立臺北商業大學。

© Chia-Hui Huang

2016年2月26日 星期五

SAP Business Intelligence - Filter Selector

篩選器 (Filter Selector) 是由1至10個下拉式方塊 (Combo Box) 所組成,透過篩選器可將資料依不同的條件組合,篩選出不同的結果,以建立圖表互動,讓圖表更加多樣化。

當選擇其中一個下拉式方塊的選項時,其餘下拉式方塊的選項將隨著所設定的條件關係而變動。



【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-篩選器 (Filter Selector),國立臺北商業大學。

© Chia-Hui Huang

2016年2月24日 星期三

SAP Business Intelligence - List Box

選取器包括:
  • 核取方塊 (Check Box)
  • 圖示 (Icon)
  • 按鈕 (Push Button)
  • 下拉式方塊 (Combo Box)
  • 篩選器 (Filter)
  • 標籤式功能表 (Label Based Menu)
  • 播放選取器 (Play Control)
  • 魚眼式圖片功能表 (Fisheye Picture Menu)
  • 清單方塊 (List Box)
  • 清單檢視 (List View)
  • 清單產生器 (List Builder)
  • 選擇鈕 (Radio Button)
  • 計分卡 (Scorecard)
  • 階層表格 (Spreadsheet Table)
選取器 (Selector) 如下拉式方塊 (Combo Box)、清單方塊 (List Box)、清單檢視 (List View)、選擇鈕 (Radio Buttons)、清單產生器 (List Builder)、計分卡 (Scorecard)、標籤式功能表 (Label Based Menu)、魚眼式圖片功能表 (Fisheye Picture Menu) 等,均以插入類型 (Insertion Type) 設定資料插入的方式。

插入類型分為位置、標籤、值、資料列、資料行、狀態清單、篩選的資料列等七種類型。

清單方塊或檢視清單 (List Box) 包含一個以上的選項項目,項目超過顯示區域大小時,清單方塊會自動顯示捲軸,以便以捲動方式列出項目。

與清單方塊類似的選取器是下拉式方塊 (Combo Box) 與篩選器 (Filter Selector),差別在於下拉式方塊將一組項目顯示於一列(Row) 之內,當點選時,則以下拉式選單的方式列出項目,而清單方塊則是將一組項目顯示於區域內,若超過顯示區域大小時,則以捲軸列出項目。

透過清單方塊可將資料依不同的條件篩選出不同的結果,以建立圖表互動,讓圖表更加多樣化。



【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-清單方塊 (List Box),國立臺北商業大學。

© Chia-Hui Huang

2016年2月22日 星期一

SAP Business Intelligence - Drill-Down Analysis

向下分析 (Drill-Down Analysis) 並不只是圖表,而是將數個圖表建立Master-Detail關聯,當點選主要圖表時,其關聯之明細圖表則顯示對應的詳細資料。

圖表類型並沒有限制,SAP Crystal Presentation Design內建的圖表均可做為主要圖表與明細圖表。



【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-向下分析 (Drill-Down Analysis),國立臺北商業大學。

© Chia-Hui Huang

2016年2月20日 星期六

SAP Business Intelligence - Combination Chart

組合圖 (Combination Chart) 結合折線圖與長條圖於一個圖表中,並以不同的標記類型 (例如欄、折線或區域線) 顯示各項資料序列。


【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-組合圖 (Combination Chart),國立臺北商業大學。

© Chia-Hui Huang

2016年2月18日 星期四

SAP Business Intelligence - OHLC Chart

OHLC圖 (Open-High-Low-Close Chart) 又稱為股票圖、技術分析圖或美國線,是以豎立的線條表現股票價格的變化,並呈現開盤價、最高價、最低價與收盤價,豎線呈現最高價和最低價間的價差間距,左側橫線代表開盤價,右側橫線代表收盤價,繪製上較K線圖簡單。

另外還有最高價-最低價-收盤價、成交量-最高價-最低價-收盤價、成交量-開盤價-最高價-最低價-收盤價等三種呈現方式。

為建立OHLC圖,需輸入股票開盤價、最高價、最低價與收盤價,資料可自臺灣證券交易所 (TWSE)、公開資訊觀測站及櫃檯買賣中心 (OTC) 取得。 以臺灣證券交易所 (TWSE)為例:

http://www.twse.com.tw

接著點選『交易資訊』→『TWSE自行編制指數』→『發行量加權股價指數歷史資料』選單,則可選擇年份與月份,並下載資料。



【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-OHLC圖 (Open-High-Low-Close Chart),國立臺北商業大學。

© Chia-Hui Huang

2016年2月16日 星期二

SAP Business Intelligence - Bullet Chart

重點式圖表或子彈圖 (Bullet Chart) 分為水平與垂直重點式圖表,實際上重點式圖表是長條圖附加額外的選項,包括效能、比較標記、高比例與低比例。

除了長條圖之外,重點式圖表並可顯示目標值 (Target) 及兩個以上的定性範圍 (Qualitative Ranges),這些範圍用以表示資料的性質,例如好壞、滿意程度等。



【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-重點式圖表 (Bullet Chart),國立臺北商業大學。

© Chia-Hui Huang

2016年2月14日 星期日

SAP Business Intelligence - Pie Chart

圓形圖或圓餅圖 (Pie Chart) 將圓形統計圖表劃分成幾個不同比例的扇形區域,藉以描述量、頻率或百分比之間的相對關係。在圓形圖中,每個扇區的面積大小代表所表示數量的比例。圓形圖又可分為分裂式圓形圖、3D圓形圖、極區圖等。

由於圓形圖以面積取代長度表達相對關係,如此反而加大了對各個數據比較的難度。因此若需要進行數據比較,建議使用折線圖或長條圖。



【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-魚眼式圖片功能表 (Fisheye Picture Menu),國立臺北商業大學。

© Chia-Hui Huang

2016年2月12日 星期五

SAP Business Intelligence - Line Chart

折線圖 (Line Chart)用以顯示一段時間內的連續資料,且根據一般的比例進行設定,因此適合顯示相等間隔內資料的趨勢,在折線圖中,類別資料沿著水平軸均勻分散,所有資料沿著垂直軸均勻分散。

長條圖 (Bar Chart)用以顯示一段時間內資料的變更或比較不同項目間的差異,在長條圖中,通常沿著水平軸顯示類別、沿著垂直軸顯示值。長條圖又分為群組長條圖、百分比堆疊長條圖、立體長條圖、圓柱圖、圓錐圖與金字塔圖。

區域圖 (Area Chart)用以區域圖強調一段時間的變動程度,例如可使用區域圖繪製代表一段時間內利潤的資料,強調利潤總和。區域圖也可藉由顯示繪製值的總和,顯示部分與整體的關係。區域圖又分為平面區域圖、立體區域圖、堆疊區域圖、百分比堆疊區域圖。

由於折線圖、長條圖、區域圖、堆疊長條圖與堆疊區域圖在商業智慧中的製作與設定均一致,因此歸類為基本圖表。

進階功能包括啟用執行階段工具與啟用範圍滑動軸,適用於折線圖、OHLC圖、燭臺圖、長條圖、堆疊長條圖、直條圖、堆疊直條圖、組合圖、區域圖、堆疊區域圖、雷達圖、填滿式雷達圖、瀑布圖。若啟用執行階段工具,座標軸之刻度將隨著資料值增加而自動展開或自動調整以配合資料範圍。當處理大量資料時,為避免畫面擁擠,可啟用範圍滑動軸,縮小資料範圍,並以捲動的方式檢視資料。



可點選圖例標籤以隱藏或顯示圖表數列,亦可以範圍滑動軸縮小資料範圍,並以捲動的方式檢視資料。


【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。
[2] 黃嘉輝,商業智慧應用-基本圖表操作,國立臺北商業大學。

© Chia-Hui Huang

2016年2月10日 星期三

SAP Crystal Presentation Design

商業智慧 (Business Intelligence, BI) 一詞最早於1989年由Gartner Group分析師Howard Dresner所提出,為一傘型概念,代表可協助企業決策之技術及工具統稱 (“Business intelligence” as an umbrella term to describe "concepts and methods to improve business decision making by using fact-based support systems.")。

根據Gartner Group (http://www.gartner.com) 的統計,全球商業智慧軟體市場的規模,由1990年的5億美元增加至現在約63億美元,國內外商業智慧代表軟體包括:
  • SAP BusinessObjects.
  • SAS Business Intelligence.
  • Oracle Business Intelligence.
  • IBM Cognos.
  • Microsoft ProClarity.
  • MicroStrategy Business Intelligence. 
  • 睿智資訊Analyzer.
  • 鼎新電腦V-Point BI.
  • 慧盟資訊科技BI@Planning.
  • 捷智商訊科技Spatial Intelligence.
商業智慧軟體包括查詢報表與進階分析工具,前者包括一般查詢、多維度分析、儀表板 (Dashboard) 及報表產生工具等,後者則包括資料探勘及統計分析兩類。透過商業智慧系統的導入,可將各個獨立系統的資料彙整,並透過商業智慧所提供的分析功能,快速地整合資料並加以分析,轉換成可產生收益的智慧資產。

一般而言,商業智慧系統的架構與技術包括以下四類:
  • 應用系統的作業資料。
  • 資料擷取、轉換與載入工具。
  • 資料倉儲管理。
  • 商業智慧分析工具。
其中資料擷取、轉換與載入 (Extraction, Transformation, Load) 是導入資料倉儲過程中最重要的工作,資料擷取需考量各部門不同的型態資料、不同使用者的分析需求、多樣的分析工具,將所有整合方能有效運作。資料倉儲 (Data Warehouse) 則是透過一連串的資料純化、轉換、整合、載入與定期資料更新建構的過程。此外商業智慧分析並包括線上分析處理 (Online Analytical Processing, OLAP) 、資料探勘 (Data Mining) 與報表系統 (Reporting) 等技術。

SAP Crystal Presentation Design (Xcelsius Dashboard) 是一商業智慧軟體,可將Excel試算表轉換成視覺化的動態分析模式。

儀表板 (Dashboard):
  • 儀表板以簡單明瞭的方式與資料建立互動。
  • 使用儀表板將更容易監控重要的商務資訊。
  • 儀表板可將商業智慧轉換成強而有力商務能量。
系統需求:
  • 作業系統:Windows XP SP1+, Windows Server 2003 Enterprise Edition+, Windows Vista+, Windows 7。
  • 瀏覽器:Google Chrome, Apple Safari, Mozilla Firefox 2.0+, Microsoft Internet Explorer 6.0+。
  • Adobe Flash Player:9.0.151.0+。
  • Microsoft Office:XP SP3+, 2003, 2007。
SAP BusinessObjects的系統架構如下圖所示,藉由其核心的三層式架構包括資料來源 (Data Source) 、企業邏輯 (Business Logic) 與視覺化 (Visualization),將視覺化的商業智慧匯出成不同的資料格式,如Microsoft Word, Microsoft Excel, Microsoft PowerPoint, Microsoft Outlook, Adobe PDF, Adobe Shockwave Flash, Adobe Air, HTML等,此外並可與Adobe Flash, Crystal Reports, IBM WebSphere Server, Microsoft SharePoint Server, Portal Info, Web Service, XML Data等資料架構整合。


SAP Crystal Presentation Design支援Microsoft Word、Microsoft Excel、Microsoft PowerPoint、Microsoft Outlook、Microsoft SharePoint、Adobe PDF、Adobe Flash、Adobe Air、HTML等匯出資料格式。

Dashboard Component (元件) 分為:
  • 圖表 (Chart)
  • 容器 (Container)
  • 選取器 (Selector)
  • 單一值 (Single Value)
  • 地圖 (Map)
  • 文字 (Text)
  • 美工和背景 (Art and Background)
  • Web連線 (Web Connectivity)
  • 其他 (Other)
其中圖表SAP圖表元件包括:
  • 折線圖 (Line Chart)
  • 長條圖 (Bar Chart)
  • 區域圖 (Area Chart)
  • 圓形圖 (Pie Chart)
  • 組合圖 (Combination Chart)
  • XY散佈圖 (XY Chart)
  • OHLC圖 (OHLC Chart)
  • 雷達圖 (Radar Chart)
  • 堆疊長條圖 (Stacked Bar Chart)
  • 堆疊區域圖 (Stacked Area Chart)
  • 樹狀地圖 (Tree Map)
  • 瀑布圖 (Waterfall Chart)
容器元件包括:
  • 畫布容器 (Canvas)
  • 面板容器 (Panel)
  • 索引標籤組 (Tab Set)

選取器包括:
  • 核取方塊 (Check Box)
  • 圖示 (Icon)
  • 按鈕 (Push Button)
  • 下拉式方塊 (Combo Box)
  • 篩選器 (Filter)
  • 標籤式功能表 (Label Based Menu)
  • 播放選取器 (Play Control)
  • 魚眼式圖片功能表 (Fisheye Picture Menu)
  • 清單方塊 (List Box)
  • 清單檢視 (List View)
  • 清單產生器 (List Builder)
  • 選擇鈕 (Radio Button)
  • 計分卡 (Scorecard)
  • 階層表格 (Spreadsheet Table)

單一值包括:
  • 值 (Value)
  • 微調鈕 (Spinner)
  • 滑動軸 (Slider)
  • 雙滑動軸 (Dual Slider)
  • 進度列 (Progress Bar)
  • 刻度盤 (Dial)
  • 儀表圖 (Gauge)

Dashboard Workspace 開發環境:


畫布 (Canvas) 是開發環境的主要部份,用以配置元件、設定畫布背景及大小:


內嵌試算表(Embedded Spreadsheet) 是SAP Crystal Presentation Design新增功能,與Microsoft Excel整合,可自行輸入資料或匯入Excel試算表,藉以建立與畫布中元件之資料連結。

屬性面板 (Properties Panel) 依不同元件,大致可分為:
  • 一般:設定圖表標題、資料範圍、標籤等。
  • 插入:啟用資料插入、設定互動選項等。
  • 行為:設定排序、動態可視性、動畫效果等。
  • 外觀:啟用圖例、設定文字字型、顏色、大小等。
  • 警示:啟用警示、警示臨界值、顏色順序等。
SAP BusinessObjects除了支援一般電腦之外,並支援平板電腦如Apple iPad,稱為SAP BusinessObjects Mobile,簡稱SAP BI,可讓使用者隨時從行動裝置取得BI資訊。以Apple iPad為例,透過App Store下載SAP BusinessObjects Mobile與SAP BusinessObjects Explorer,如下所示:


【參考資料】

[1] 黃嘉輝,商業智慧應用-SAP Crystal Presentation Design,國立臺北商業大學。 
[2] 黃嘉輝,商業智慧應用-基本圖表操作,國立臺北商業大學。

© Chia-Hui Huang

2015年7月30日 星期四

深入研究JavaFX 2 (第二版)

2015年的第一本新書,雖然只是改版,但也是我的誠懇之作,第42本書 –「深入研究JavaFX 2 (第二版)」。
© Chia-Hui Huang

JavaFX遊戲程式設計 (第二版)

2015年的第二本新書,雖然只是改版,但也是我的誠懇之作,第41本書 –「JavaFX遊戲程式設計 (第二版)」。
© Chia-Hui Huang

2015年4月18日 星期六

展示jQuery Mobile

網頁以jQuery Mobile完成之後,則可以手機或平板瀏覽,但若是以電腦的瀏覽器瀏覽時,則可能與實際結果有所出入。我們可以試著加入手機或平板的圖片,並以<iframe>網頁標籤將jQuery Mobile網頁置於圖片之中,產生如同以手機或平板的瀏覽效果。

例如以下手機圖片:
其中圖片尺寸分別為380px (Height) 與700px (Width)、白色矩形的右上角分別為27px (Top) 與85px (Left)、長寬分別為320px (Height) 與533px (Width),藉此設定以下CSS:
#preview {
  height: 380px;
  width: 700px;
  background: url(images/phone_landscape.png) 
    center no-repeat;
}

#preview iframe {
  width: 533px;
  height: 320px;
  top: 27px;
  left: 85px;
}
並在HTML網頁中,以下列方式顯示jQuery Mobile網頁 (demo.html):
【執行結果】

同樣的,以相同方式處理平板,以下為平板圖片:
其中圖片尺寸分別為640px (Height) 與1050px (Width)、白色矩形的右上角分別為70px (Top) 與125px (Left)、長寬分別為500px (Height) 與800px (Width),藉此設定以下CSS:
#preview {
  height: 640px;
  width: 1050px;
  background: url(images/smalltablet_landscape.png) 
    center no-repeat;
}

#preview iframe {
  width: 800px;
  height: 500px;
  top: 70px;
  left: 125px;
}
並在HTML網頁中,以下列方式顯示jQuery Mobile網頁 (demo.html):
【執行結果】


© Chia-Hui Huang

JavaFX Spinner

2015年03月03日Oracle推出JavaFX 8 Update 40,新增Spinner物件,Spinner原義為紡紗機,此處是指微調工具,其類別為javafx.scene.control.Spinner,類似於ListView與ComboBox類別,均用以顯示一個以上的項目。

Spinner類別由箭頭與編輯物件 (Editor) 兩部份所組成,下圖為JavaFX之Spinner樣式:

JavaFX的Spinner支援int整數、double浮點數與自定字串清單,與Java Swing的JSpinner相比,Java Swing支援預設 (Default)、日期 (Date)、清單 (List)與數字 (Number)等格式,較JavaFX多了日期格式,下圖為Java Swing之JSpinner的日期樣式:
不過JavaFX的Spinner可設定箭頭位置與方向,分別由以下選項設定,若未指定,則為預設的右側垂直樣式:
  • Spinner.STYLE_CLASS_ARROWS_ON_RIGHT_HORIZONTAL:右側水平。
  • Spinner.STYLE_CLASS_ARROWS_ON_LEFT_VERTICAL:左側垂直。
  • Spinner.STYLE_CLASS_ARROWS_ON_LEFT_HORIZONTAL:左側水平。
  • Spinner.STYLE_CLASS_SPLIT_ARROWS_VERTICAL:分裂垂直。
  • Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL:分裂水平。
以下範例示範Spinner類別的各種箭頭位置與方向之樣式:
String[] styles = {
  "",                                             // 預設右側垂直
  Spinner.STYLE_CLASS_ARROWS_ON_RIGHT_HORIZONTAL, // 右側水平
  Spinner.STYLE_CLASS_ARROWS_ON_LEFT_VERTICAL,    // 左側垂直
  Spinner.STYLE_CLASS_ARROWS_ON_LEFT_HORIZONTAL,  // 左側水平
  Spinner.STYLE_CLASS_SPLIT_ARROWS_VERTICAL,      // 分裂垂直
  Spinner.STYLE_CLASS_SPLIT_ARROWS_HORIZONTAL     // 分裂水平
};

Spinner[] spinner = new Spinner[styles.length];

for (int i = 0; i < styles.length; i++) {
  spinner[i] = new Spinner(0, 100, 10);      // 最小值, 最大值, 預設值
  spinner[i].getStyleClass().add(styles[i]); // 設定箭頭位置與方向
  spinner[i].setPrefWidth(80);
}
...
【執行結果】
除了以上述Spinner的建構函式設定之外,亦可以使用SpinnerValueFactory設定Spinner的Model,分別如下:
  • SpinnerValueFactory.IntegerSpinnerValueFactory:Integer整數。
  • SpinnerValueFactory.DoubleSpinnerValueFactory:Double浮點數。
  • SpinnerValueFactory.ListSpinnerValueFactory:List清單。
以下範例示範以SpinnerValueFactory.DoubleSpinnerValueFactory設定Double浮點數的Spinner Model:
Spinner[] spinner = new Spinner[styles.length];

for (int i = 0; i < styles.length; i++) {
  // 最小值, 最大值, 預設值, 遞增減值
  SpinnerValueFactory svf = new 
    SpinnerValueFactory.DoubleSpinnerValueFactory(0.0, 10.0, 1.2, 0.1); 
  Spinner sp = new Spinner();
  sp.setValueFactory(svf);
  sp.getStyleClass().add(styles[i]);
  sp.setPrefWidth(80);
  spinner[i] = sp;
}
...
【執行結果】
比較特殊的是List清單,一般Spinner物件都用在選擇數字或日期,但JavaFX加入List清單功能,因此可自定字串清單,以下範例示範以SpinnerValueFactory.ListSpinnerValueFactory設定List清單的Spinner Model:
Spinner[] spinner = new Spinner[styles.length];

for (int i = 0; i < styles.length; i++) {
  ObservableList<String> months = 
    FXCollections.observableArrayList(
      "January", "February", "March", "April",
      "May", "June", "July", "August",
      "September", "October", "November", "December"
    );

  SpinnerValueFactory svf = new 
    SpinnerValueFactory.ListSpinnerValueFactory<>(months);
  Spinner sp = new Spinner();
  sp.setValueFactory(svf);
  sp.getStyleClass().add(styles[i]);
  sp.setPrefWidth(100);
  spinner[i] = sp;
}
...
【執行結果】
更進一步,可搭配CurrencyStringConverter設定貨幣格式,並以setStyle()方法設定Spinner的字型樣式:
TextFormatter<Number> formatter = 
  new TextFormatter<>(new CurrencyStringConverter());
formatter.setValue(50000);

Spinner spinner = new Spinner();
spinner.setPrefWidth(150);
spinner.setEditable(true);
spinner.getEditor().setTextFormatter(formatter);
spinner.getEditor().setStyle(
  "-fx-font: 10pt 'verdana'; 
   -fx-text-fill: black; 
   -fx-alignment: CENTER_RIGHT;"
);    
...
【執行結果】
以下範例更進一步以CurrencyStringConverter設定系統預設、美金 (Locale.US)、日幣 (Locale.JAPAN) 等貨幣格式,並以PercentageStringConverter設定百分比格式:
// 系統預設貨幣格式
TextFormatter<Number> formatter1 = 
  new TextFormatter<>(new CurrencyStringConverter());
formatter1.setValue(50000);

Spinner spinner1 = new Spinner();
spinner1.setPrefWidth(150);
spinner1.setEditable(true);
spinner1.getEditor().setTextFormatter(formatter1);
spinner1.getEditor().setStyle(
  "-fx-font: 10pt 'verdana'; 
   -fx-text-fill: black; 
   -fx-alignment: CENTER_RIGHT;"
);  

// 美金貨幣格式
TextFormatter<Number> formatter2 =  
  new TextFormatter<>(new CurrencyStringConverter(Locale.US));
formatter2.setValue(50000);

Spinner spinner2 = new Spinner();
spinner2.setPrefWidth(150);
spinner2.setEditable(true);
spinner2.getEditor().setTextFormatter(formatter2);
spinner2.getEditor().setStyle(
  "-fx-font: 10pt 'verdana'; 
   -fx-text-fill: black; 
   -fx-alignment: CENTER_RIGHT;"
);  

// 日幣貨幣格式
TextFormatter<Number> formatter3 =  
  new TextFormatter<>(new CurrencyStringConverter(Locale.JAPAN));
formatter3.setValue(50000);

Spinner spinner3 = new Spinner();
spinner3.setPrefWidth(150);
spinner3.setEditable(true);
spinner3.getEditor().setTextFormatter(formatter3);
spinner3.getEditor().setStyle(
  "-fx-font: 10pt 'verdana'; 
   -fx-text-fill: black; 
   -fx-alignment: CENTER_RIGHT;"
);  

// 百分比格式
TextFormatter<Number> formatter4 = 
  new TextFormatter<>(new PercentageStringConverter(););
formatter4.setValue(0.12);

Spinner spinner4 = new Spinner();
spinner4.setPrefWidth(150);
spinner4.setEditable(true);
spinner4.getEditor().setTextFormatter(formatter4);
spinner4.getEditor().setStyle(
  "-fx-font: 10pt 'verdana'; 
   -fx-text-fill: black; 
   -fx-alignment: CENTER_RIGHT;"
);  
...
【執行結果】
雖然Spinner物件不直接支援日期格式,但仍可以搭配SimpleDateFormat的方式設定各種日期格式,請參考以下範例:
try {
  Calendar calendar = Calendar.getInstance();

  // yyyy/MM/dd
  SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd");
  // 指定日期
  calendar.setTime(DateFormat.getDateInstance().parse("2015/5/10"));    

  Spinner spinner1 = new Spinner();
  spinner1.setPrefWidth(220);
  spinner1.setEditable(true);
  spinner1.getEditor().setText(sdf1.format(calendar.getTime()));
  spinner1.getEditor().setStyle(
    "-fx-font: 10pt 'verdana'; 
     -fx-text-fill: black; 
     -fx-alignment: CENTER_RIGHT;"
  );      

  // E yyyy/MM/dd
  SimpleDateFormat sdf2 = new SimpleDateFormat("E yyyy/MM/dd");
  // 指定日期
  calendar.setTime(DateFormat.getDateInstance().parse("2015/5/10"));    

  Spinner spinner2 = new Spinner();
  spinner2.setPrefWidth(220);
  spinner2.setEditable(true);
  spinner2.getEditor().setText(sdf2.format(calendar.getTime()));
  spinner2.getEditor().setStyle(
    "-fx-font: 10pt 'verdana'; 
     -fx-text-fill: black; 
     -fx-alignment: CENTER_RIGHT;"
  );        

  // yyyy/MM/dd HH:mm:ss
  SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

  Spinner spinner3 = new Spinner();
  spinner3.setPrefWidth(220);
  spinner3.setEditable(true);
  // 系統目前日期
  spinner3.getEditor().setText(sdf3.format(new Date()));
  spinner3.getEditor().setStyle(
    "-fx-font: 10pt 'verdana'; 
     -fx-text-fill: black; 
     -fx-alignment: CENTER_RIGHT;"
  );      

  // EEE, MMM d, 'yy
  SimpleDateFormat sdf4 = new SimpleDateFormat("EEE, MMM d, ''yy");

  Spinner spinner4 = new Spinner();
  spinner4.setPrefWidth(220);
  spinner4.setEditable(true);
  // 系統目前日期
  spinner4.getEditor().setText(sdf4.format(new Date()));
  spinner4.getEditor().setStyle(
    "-fx-font: 10pt 'verdana'; 
     -fx-text-fill: black; 
     -fx-alignment: CENTER_RIGHT;"
  );         
  
  ...
} 
catch (Exception  e) {
  e.printStackTrace();
}
...
【執行結果】
【參考資料】

[1] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[2] JavaFX:http://www.oracle.com/technetwork/java/javafx
[3] JavaFX 8.0 API Specification.
[4] Java Platform, Standard Edition 8 API Specification.

© Chia-Hui Huang

2015年4月13日 星期一

JavaFX Dialog (3)

除了Alert類別之外,另外尚有ChoiceDialog與TextInputDialog類別,皆繼承自Dialog類別,分別在對話盒中顯示選項方塊 (Choice Box) 與文字欄位 (Text Field),此外亦可以Dialog類別自訂對話盒。

以下範例示範以TextInputDialog建立文字欄位之對話盒,較之前以getDialogPane()的setContent()或setExpandableContent()方法將自訂物件置於對話盒的方式為簡單:
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("Text Input Dialog");
dialog.setHeaderText(null);
dialog.setContentText("Username:");

dialog.showAndWait().ifPresent(result -> {
  System.out.println("Username: " + result);
});     
...
【執行結果】
以下範例並加入setHeaderText()方法設定標題文字:
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("Text Input Dialog");
dialog.setHeaderText("示範以setHeaderText()方法設定標題文字。");
dialog.setContentText("Username:");

dialog.showAndWait().ifPresent(result -> {
  System.out.println("Username: " + result);
});     
...
【執行結果】
以下範例示範以ChoiceDialog建立選項方塊之對話盒,並示範將作業系統的所有字型置於選項方塊之中:
// 取得作業系統的所有字型
List<String> fonts = Font.getFamilies();

// 以字型建立選項方塊對話盒
ChoiceDialog<String> dialog = 
  new ChoiceDialog<>(fonts.get(0), fonts);
dialog.setTitle("Choice Dialog");
dialog.setHeaderText(null);
dialog.setContentText("Fonts:");

dialog.showAndWait().ifPresent(result -> {
  System.out.println("Font: " + result);
});     
...
【執行結果】
除此之外,亦可以Dialog類別自訂對話盒,請參考以下範例,分別加入文字欄位、修改對話盒圖示與按鈕類型組合:
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("Custom Dialog");
dialog.setHeaderText(null);
dialog.setGraphic(new ImageView(
  new Image(getClass().getResourceAsStream("images/info.png"))));

// 自訂按鈕類型組合
ButtonType button1 = new ButtonType("OK", ButtonData.OK_DONE);
ButtonType button2 = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);

dialog.getDialogPane().getButtonTypes().addAll(button1, button2);

Label label1 = new Label("Username:");
Label label2 = new Label("Password:");

final TextField textfield = new TextField();
textfield.setText("");
textfield.setTooltip(new Tooltip("Username"));

final PasswordField passwordfield = new PasswordField();
passwordfield.setText("Athena");
passwordfield.setPrefColumnCount(15);
passwordfield.setPromptText("Please enter your password.");
passwordfield.setTooltip(new Tooltip("Password"));

GridPane gridpane = new GridPane();
gridpane.setAlignment(Pos.CENTER);
gridpane.setHgap(10);
gridpane.setVgap(10);
gridpane.setPadding(new Insets(5, 5, 5, 5));

gridpane.add(label1, 0, 0);
gridpane.add(label2, 0, 1);

gridpane.add(textfield, 1, 0);
gridpane.add(passwordfield, 1, 1);

Button btnOK = (Button) dialog.getDialogPane().lookupButton(button1);
btnOK.setDisable(true);

textfield.textProperty().addListener(
  (observable, oldValue, newValue) -> {
  
  btnOK.setDisable(newValue.trim().isEmpty());
});

// 將自訂物件置於對話盒中
dialog.getDialogPane().setContent(gridpane);

dialog.setResultConverter(buttontype -> {
  if (buttontype == button1) {
    return new Pair<>(textfield.getText(), passwordfield.getText());
  }
  return null;
});

dialog.showAndWait().ifPresent(result -> {
  System.out.println("Username: " + result.getKey());
  System.out.println("Password: " + result.getValue());
});
...
【執行結果】
【參考資料】

[1] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[2] JavaFX:http://www.oracle.com/technetwork/java/javafx
[3] JavaFX 8.0 API Specification.
[4] Java Platform, Standard Edition 8 API Specification.

© Chia-Hui Huang

JavaFX Dialog (2)

除了前述以Alert類別的相關方法設定對話盒之外,亦可自訂訊息對話盒中的物件。首先自訂各類物件配置,接著以Alert類別的getDialogPane()方法取得對話盒的窗格,再以getDialogPane()的setContent()或setExpandableContent()方法將自訂物件置於對話盒中。

以下範例首先以TextArea建立文字區域,並以BorderPane配置文字區域,最後以getDialogPane()的setContent()或setExpandableContent()方法將自訂物件置於對話盒中:
// 自訂物件
String text = "...";

TextArea textArea = new TextArea(text);
textArea.setEditable(false);
textArea.setWrapText(true);

BorderPane borderpane = new BorderPane();
borderpane.setCenter(textArea);

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Dialog");
alert.setHeaderText(null);
alert.setContentText("示範自訂訊息對話盒的內容。");
// 將自訂物件置於對話盒中
alert.getDialogPane().setExpandableContent(borderpane);            
alert.showAndWait();
...
【執行結果】

當剛開啟對話盒時,其自訂物件部份為收合狀態,並在左下角顯示「顯示詳細資訊」:
點選「顯示詳細資訊」,則展開自訂物件部份,並在左下角顯示「隱藏詳細資訊」:
以下範例首先以TextField與PasswordField分別建立文字欄位與密碼欄位,並以GridPane配置物件,最後以getDialogPane()的setContent()或setExpandableContent()方法將自訂物件置於對話盒中:
// 自訂物件
Label label1 = new Label("Username:");
Label label2 = new Label("Password:");

final TextField textfield = new TextField();
textfield.setText("");
textfield.setTooltip(new Tooltip("Username"));

final PasswordField passwordfield = new PasswordField();
passwordfield.setText("Athena");
passwordfield.setPrefColumnCount(15);
passwordfield.setPromptText("Please enter your password.");
passwordfield.setTooltip(new Tooltip("Password"));

GridPane gridpane = new GridPane();
gridpane.setAlignment(Pos.CENTER);
gridpane.setHgap(10);
gridpane.setVgap(10);
gridpane.setPadding(new Insets(5, 5, 5, 5));

gridpane.add(label1, 0, 0);
gridpane.add(label2, 0, 1);

gridpane.add(textfield, 1, 0);
gridpane.add(passwordfield, 1, 1);

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Dialog");
alert.setHeaderText(null);
alert.setContentText("示範自訂訊息對話盒的內容。");
// 將自訂物件置於對話盒中
alert.getDialogPane().setExpandableContent(gridpane);            
alert.showAndWait();
...
【執行結果】
以下範例首先以ComboBox建立複合方塊與setCellFactory()方法設定其Cell Factory,並在Cell Factory中以Rectangle類別設定各選項項目的顏色,並以BorderPane配置複合方塊,最後以getDialogPane()的setContent()或setExpandableContent()方法將自訂物件置於對話盒中:
// 自訂物件
final ComboBox<Color> combobox = new ComboBox<>();

combobox.getItems().addAll(
  Color.RED, Color.GREEN, Color.BLUE, Color.AQUA, 
  Color.BLUEVIOLET, Color.CHOCOLATE, Color.DIMGRAY, 
  Color.FORESTGREEN, Color.GREENYELLOW, Color.INDIGO);

// select the last element
combobox.getSelectionModel().select(3);
combobox.setVisibleRowCount(5);
combobox.setEditable(false);
combobox.setPrefWidth(180);

// Cell Factory
combobox.setCellFactory(new Callback<ListView<Color>, 
  ListCell<Color>>() {
  @Override 
  public ListCell<Color> call(ListView<Color> param) {

    return new ListCell<Color>() 
    {
      {
        super.setPrefWidth(60);
      }    
      private final Rectangle rectangle;
      { 
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 
        rectangle = new Rectangle(150, 15);
      }

      @Override 
      protected void updateItem(Color item, boolean empty) {
        super.updateItem(item, empty);

        if (item == null || empty) {
          setGraphic(null);
        } 
        else {
          rectangle.setFill(item);
          setGraphic(rectangle);
        }
      }
    };
  }
});

BorderPane borderpane = new BorderPane();
borderpane.setCenter(combobox);

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Dialog");
alert.setHeaderText(null);
alert.setContentText("示範自訂訊息對話盒的內容。");
// 將自訂物件置於對話盒中
alert.getDialogPane().setExpandableContent(borderpane);            
alert.showAndWait();
...
【執行結果】
以下範例首先以Pagination建立分頁控制,並以BorderPane配置文字區域,最後以getDialogPane()的setContent()或setExpandableContent()方法將自訂物件置於對話盒中:
// 自訂物件
final Pagination pagination;
pagination = new Pagination();
pagination.setPageCount(14);
pagination.setCurrentPageIndex(0);
pagination.setMaxPageIndicatorCount(10);
pagination.setPageFactory((Integer pageIndex) -> {
  ImageView imageview = new ImageView(scene[pageIndex]);

  VBox vbox = new VBox();
  vbox.setAlignment(Pos.CENTER);
  vbox.getChildren().add(imageview);

  return vbox;
});

BorderPane borderpane = new BorderPane();
borderpane.setCenter(pagination);

Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Dialog");
alert.setHeaderText(null);
alert.setContentText("示範自訂訊息對話盒的內容。");
// 將自訂物件置於對話盒中
alert.getDialogPane().setExpandableContent(borderpane);            
alert.showAndWait();
...
【執行結果】
【參考資料】

[1] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[2] JavaFX:http://www.oracle.com/technetwork/java/javafx
[3] JavaFX 8.0 API Specification.
[4] Java Platform, Standard Edition 8 API Specification.

© Chia-Hui Huang

JavaFX Dialog (1)

2015年03月03日Oracle推出JavaFX 8 Update 40,終於將Dialog (對話盒) 納入JavaFX中,其實由JavaFX 2就蠻好奇為什麼沒有Dialog這項功能,老實說要寫一個對話盒並不難,Java Swing就有。

在圖形化介面環境中,對話盒因功能之不同可分為:
  • 訊息對話盒 (Message Box)。
  • 開啟檔案對話盒 (Open File Dialog)。
  • 儲存檔案對話盒 (Save File Dialog)。
  • 色彩對話盒 (Color Dialog)。
  • 版面設定對話盒 (Page Setup Dialog)。
  • 預覽列印對話盒 (Print Preview Dialog)。
  • 列印對話盒 (Print Dialog)。
  • 字型對話盒 (Font Dialog)。
  • 尋找對話盒 (Find Dialog)。
在Java Swing中,有關對話盒之類別分為:
  • 對話盒:javax.swing.JDialog。
  • 對話框:javax.swing.JOptionPane。
  • 檔案對話盒:javax.swing.JFileChooser。
  • 色彩對話盒:javax.swing.JColorChooser。
以JOptionPane類別為例,可分為以下類型,主要是以JOptionPane類別不同的方法顯示:
  • 確認對話盒 (Confirm Dialog):以showConfirmDialog()方法顯示,預設包括Yes、No與Cancel按鈕。
  • 輸入對話盒 (Input Dialog):用以取得資訊,並以showInputDialog()方法顯示。
  • 訊息對話盒 (Message Dialog):用以顯示資訊,並以showMessageDialog()方法顯示。
  • 選項對話盒 (Option Dialog):可自訂對話盒及按鈕樣式,並以showOptionDialog()方法顯示。
在JavaFX中,有關對話盒的類別分別為:
  • 目錄對話盒:javafx.stage.DirectoryChooser。
  • 檔案對話盒:javafx.stage.FileChooser。
  • 快顯對話盒:javafx.stage.Popup。
  • 顏色選擇器:javafx.scene.control.ColorPicker。
  • 日期選擇器:javafx.scene.control.DatePicker。
其中顏色選擇器與日期選擇器繼承自ComboBoxBaser抽象類別,因此其樣式類似於複合方塊 (Combo Box)。

JavaFX 8 Update 40新增之對話盒沿用自ControlsFX,其類別為javafx.scene.control.Alert,繼承自javafx.scene.control.Dialog類別,因此除了可使用Alert類別的相關方法建立對話盒之外,亦可以Dialog類別自訂對話盒。除了Alert類別之外,另外尚有ChoiceDialog與TextInputDialog類別。

Alert類別的方法包括:
  • getButtonTypes():取得對話盒的按鈕類型。
  • getContentText():取得對話盒的內容文字。
  • setContentText():設定對話盒的內容文字。
  • getDialogPane():取得對話盒的窗格。
  • setDialogPane():設定對話盒的窗格。
  • getGraphic():取得對話盒中的圖示。
  • setGraphic():設定對話盒中的圖示。
  • getHeaderText():取得標題文字,Java Swing並沒有此部份。
  • setHeaderText():設定標題文字,Java Swing並沒有此部份。
  • getTitle():取得對話盒標題。
  • setTitle():設定對話盒標題。
  • show():顯示對話盒。
  • wait():等待使用者回應,則按下對話盒中的任一按鈕。
  • showAndWait():顯示對話盒並等待使用者回應。
此外Alert類別以下列屬性值設定對話盒的類型:
  • AlertType.INFORMATION:訊息對話盒。
  • AlertType.WARNING:警告對話盒。
  • AlertType.ERROR:錯誤對話盒。
  • AlertType.CONFIRMATION:確認對話盒。
  • AlertType.NONE:無任何預設設定。
以下範例以Alert類別的相關方法設定訊息對話盒,請注意setHeaderText()方法:
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Dialog");
alert.setHeaderText(null);
alert.setContentText("訊息對話盒,顯示一般訊息之用。");
alert.showAndWait();
...
【執行結果】
以下範例以Alert類別的相關方法設定訊息對話盒,並加入setHeaderText()方法設定標題文字:
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Information Dialog");
alert.setHeaderText("示範以setHeaderText()方法設定標題文字。");
alert.setContentText("訊息對話盒,顯示一般訊息之用。");
alert.showAndWait();
...
【執行結果】
以下範例以Alert類別的相關方法設定警告對話盒:
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Warning Dialog");
alert.setHeaderText(null);
alert.setContentText("警告對話盒,顯示警告訊息之用。");
alert.showAndWait();
...
【執行結果】
以下範例以Alert類別的相關方法設定警告對話盒,並加入setHeaderText()方法設定標題文字:
Alert alert = new Alert(AlertType.WARNING);
alert.setTitle("Warning Dialog");
alert.setHeaderText("示範以setHeaderText()方法設定標題文字。");
alert.setContentText("警告對話盒,顯示警告訊息之用。");
alert.showAndWait();
...
【執行結果】
以下範例以Alert類別的相關方法設定錯誤對話盒:
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error Dialog");
alert.setHeaderText(null);
alert.setContentText("錯誤對話盒,顯示錯誤訊息之用。");
alert.showAndWait();
...
【執行結果】
以下範例以Alert類別的相關方法設定錯誤對話盒,並加入setHeaderText()方法設定標題文字:
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error Dialog");
alert.setHeaderText("示範以setHeaderText()方法設定標題文字。");
alert.setContentText("錯誤對話盒,顯示錯誤訊息之用。");
alert.showAndWait();
...
【執行結果】
以下範例以Alert類別的相關方法設定確認對話盒,用以確認訊息,並包括確認與取消按鈕:
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");          
alert.setHeaderText(null);
alert.setContentText("確認對話盒,用以確認訊息,並包括確認與取消按鈕。");
alert.showAndWait();
...
【執行結果】
以下範例以Alert類別的相關方法設定確認對話盒,並加入setHeaderText()方法設定標題文字:
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");          
alert.setHeaderText("示範以setHeaderText()方法設定標題文字。");
alert.setContentText("確認對話盒,用以確認訊息,並包括確認與取消按鈕。");
alert.showAndWait();
...
【執行結果】
我們也可以使用setGraphic()方法設定對話盒中的圖示:
Alert alert = new Alert(AlertType.CONFIRMATION);
alert.setTitle("Confirmation Dialog");          
alert.setHeaderText(null);
alert.setContentText("確認對話盒,用以確認訊息,並包括確認與取消按鈕。");
// 設定對話盒中的圖示
alert.setGraphic(new ImageView(
  new Image(getClass().getResourceAsStream("images/Question.png"))));
alert.showAndWait();
...
【執行結果】
由於確認對話盒預設包括確認與取消按鈕,可使用以下方式取得所按下的按鈕:
Optional<buttontype> result = alert.showAndWait();

if (result.get() == ButtonType.OK) {
  System.out.println("Press OK button.");
}
else {
  System.out.println("Press cancel button.");
}
...
可更進一步使用Lambda Expression精簡程式:
alert.showAndWait().ifPresent(result -> {
  if (result == ButtonType.OK) {
    System.out.println("Press OK button.");
  }
  else {
    System.out.println("Press cancel button.");
  }
});
...
除了預設按鈕之外,可使用ButtonType類別自訂按鈕類型組合,並以ButtonData.CANCEL_CLOSE設定自訂按鈕中的預設Cancel按鈕,當按下ESC按鍵時,等同按下Cancel按鈕:
// 自訂按鈕類型
ButtonType button1 = new ButtonType("Yes");
ButtonType button2 = new ButtonType("No");
ButtonType button3 = new ButtonType("Maybe");
// 設定預設Cancel按鈕
ButtonType button4 = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);

alert.getButtonTypes().setAll(button1, button2, button3, button4);

alert.showAndWait().ifPresent(result -> {
  if (result == button1) {
    System.out.println("Press Yes button.");
  }
  else if (result == button2) {
    System.out.println("Press No button.");
  }
  else if (result == button3) {
    System.out.println("Press Maybe button.");
  }
  else {
    System.out.println("Press Cancel button.");
  }
});
...
【執行結果】
【參考資料】

[1] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[2] JavaFX:http://www.oracle.com/technetwork/java/javafx
[3] JavaFX 8.0 API Specification.
[4] Java Platform, Standard Edition 8 API Specification.

© Chia-Hui Huang