JavaFX 程式架構
|
JavaFX Scene Builder 與 FXML << 前情 JavaFX 1.X是以JavaFX Script的形式撰寫程式,其副檔名為fx: import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
Stage {
title: "First JavaFX"
width: 250
height: 80
scene: Scene {
content: Text {
font: Font {
size: 16
}
x: 10,
y: 30
content: "Hello World - JavaFX"
}
}
}
接著以JavaFX編譯器 (javafxc.exe) 編譯JavaFX Script,由於JavaFX 1.X同時支援桌上型應用程式 (Desktop Profile) 與手機應用程式 (Mobile Profile),因此其編譯方式可分為:
執行JavaFX類別,則以JavaFX直譯器 (javafx.exe) 執行類別檔案,執行方式亦可分為:
但由於JavaFX Script與傳統Java差異甚多,開發人員需花費較多的時間學習,也因此JavaFX Script並未受到很大的重視。 至JavaFX 2.0,Oracle將JavaFX重新改寫,以Java語法取代原JavaFX Script語法與移除支援手機的Mobile版本,並正式併入Java SE 7 Update 6中,將原有的JavaFX編譯器 (javafxc.exe) 與直譯器 (javafx.exe),以Java編譯器 (javac.exe) 與直譯器 (java.exe) 取代,因此可使用同一個編譯器編譯Java與JavaFX程式。 開發JavaFX應用程式需繼承javafx.application.Application抽象類別,Application抽象類別類似於Java Swing的JApplet類別,同樣有其「生命週期」,分別為:
其程式架構如下: import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
...
// 繼承javafx.application.Application抽象類別
public class JavaFXHelloWorld extends Application {
@Override
public void start(Stage primaryStage) {
...
}
public static void main(String[] args) {
launch(args);
}
}
JavaFX同樣以main()方法為進入點,但由於JavaFX可同時以視窗程式、Java Applet或以Java Web Start啟動等形式執行,因此其程式架構類似於Java Applet,但較Java Applet精簡。由於視窗程式是以main()方法為進入點,因此在main()中執行Application抽象類別的launch()方法,啟動獨立的JavaFX應用程式,則以視窗的形式執行;若是以Java Applet形式執行,則將不會執行main(),而是由Application抽象類別的start()方法開始,因此上述的程式架構可同時滿足視窗程式、Java Applet與以Java Web Start啟動等形式,一舉數得。 請參考以下範例: import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.text.Text;
import javafx.scene.Group;
// 繼承javafx.application.Application抽象類別
public class JavaFXHelloWorld extends Application {
@Override
public void start(Stage primaryStage) {
Text text = new Text("("JavaFX Hello World");
text.setX(50);
text.setY(50);
Group group = new Group();
group.getChildren().add(text);
// 設定Scene的Layout Pane
Scene scene = new Scene(group);
// 設定Stage的標題
primaryStage.setTitle("JavaFX Hello World");
// 設定Stage的寬度
primaryStage.setWidth(250);
// 設定Stage的高度
primaryStage.setHeight(200);
primaryStage.setScene(scene);
// 顯示Stage
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
JavaFX以樹狀架構的方式組合物件,如同分層堆疊一般,各樹狀節點稱為Node,分為以下三類:
其中javafx.stage.Stage為JavaFX最上層的容器 (Container),類似於Java Swing的JRootPane類別,用以置放Scene物件。javafx.scene.Scene則是JavaFX Scene Graph,可藉以繪圖或配置各類GUI物件。 程式完成之後,同樣以Java編譯器 (javac.exe) 與直譯器 (java.exe) 編譯JavaFX程式與執行類別檔案。 以下為以視窗的形式執行的結果,與Java Swing不同的是,JavaFX會自動處理部份的視窗事件如關閉視窗: 由於JavaFX所開發的應用程式,可同時以Java Applet、Java Web Start與視窗應用程式的形式執行,因此其建立Java Archive的方式與一般的Java程式不同,並非以jar.exe建立,而是以javafxpackager.exe建立JAR檔案,稱為JavaFX Packager。 JavaFX Packager除了將類別、圖像等檔案建立JAR檔案之外,並分別產生執行Java Applet與Java Web Start所需的HTML網頁與JNLP檔案,可省去開發人員自行建立的步驟,此一概念稱為「Write Once, Deploy Anywhere」。 以JavaFX Packager建立JAR的方式可分為:
例如以下指令將同時建立JAR檔案、HTML與JNLP檔案,並設定輸出目錄為dist、Java Applet於網頁中的高度與寬度均為200: javafxpackager -deploy -appclass JavaFXHelloWorld -srcdir . -outdir dist -outfile JavaFXHelloWorld -width 200 -height 200 -name JavaFXHelloWorld -v 以下為JavaFX Packager所產生的HTML網頁內容,與一般以標籤定義Java Applet不同,此外並包含執行JNLP的超連結: <html>
<head>
<script src="https://java.com/js/dtjava.js"></script>
<script>
function launchApplication(jnlpfile) {
dtjava.launch
(
{
url : 'JavaFXHelloWorld.jnlp'
},
{
javafx : '2.2+'
},
{}
);
return false;
}
</script>
<script>
function javafxEmbed() {
dtjava.embed
(
{
url : 'JavaFXHelloWorld.jnlp',
placeholder : 'javafx-app-placeholder',
width : 200,
height : 200
},
{
javafx : '2.2+'
},
{}
);
}
<!-- Embed FX application into web page once page is loaded -->
dtjava.addOnloadCallback(javafxEmbed);
</script>
</head>
<body>
<h2>Test page for <b>JavaFXHelloWorld</b></h2>
<b>Webstart:</b>
<a href='JavaFXHelloWorld.jnlp'
onclick="return launchApplication('JavaFXHelloWorld.jnlp');">
click to launch this app as webstart
</a>
<br><hr><br>
<!-- Applet will be inserted here -->
<div id='javafx-app-placeholder'></div>
</body>
</html>
以下為JavaFX Packager所產生的JNLP內容,除了原有的JNLP標籤之外,並新增<jfx:javafx-runtime>與<jfx:javafx-desc>之XML標籤,分別定義JavaFX執行Runtime Environment的版本與JavaFX類別名稱及長寬: <?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" xmlns:jfx=https://javafx.com href="JavaFXHelloWorld.jnlp">
<information>
<title>Sample JavaFX Application</title>
<vendor>Unknown vendor</vendor>
<description>Sample JavaFX 2.0 application.</description>
<offline-allowed/>
</information>
<resources>
<jfx:javafx-runtime version="2.2+"
href="https://javadl.sun.com/webapps/download/
GetFile/javafx-latest/windows-i586/javafx2.jnlp"/>
</resources>
<resources>
<j2se version="1.6+" href="https://java.sun.com/products/autodl/j2se"/>
</resources>
<applet-desc width="200" height="200"
main-class="com.javafx.main.NoJavaFXFallback"
name="JavaFXHelloWorld" >
<param name="requiredFXVersion" value="2.2+"/>
</applet-desc>
<jfx:javafx-desc width="200" height="200"
main-class="JavaFXHelloWorld" name="JavaFXHelloWorld" />
<update check="background"/>
</jnlp>
除了以標準的Java格式撰寫JavaFX程式之外,JavaFX並提供Builder類別,透過Builder類別可精簡程式長度,但程式的撰寫方式與以往的Java程式不同。請參考以下範例以Builder的方式改寫上述範例: import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.stage.Stage;
import javafx.scene.text.TextBuilder;
import javafx.scene.GroupBuilder;
// 繼承javafx.application.Application抽象類別
public class JavaFXHelloWorld extends Application {
@Override
public void start(Stage primaryStage) {
Scene scene = SceneBuilder.create()
.width(250)
.height(200)
.root(
GroupBuilder.create()
.children(
TextBuilder.create()
.x(50)
.y(50)
.text("JavaFX Hello World")
.build()
)
.build()
)
.build();
// 設定Stage的標題
primaryStage.setTitle("JavaFX Hello World");
primaryStage.setScene(scene);
// 顯示Stage
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
除了上述兩種格式之外,另外尚有GroovyFX、ScalaFX與Visage,同樣可開發JavaFX應用程式,其程式長度更為精簡。請分別參考以下網站之介紹:
以下為以GroovyFX改寫上述範例: start {
stage(title: 'JavaFX Hello World', visible: true) {
scene(width: 250, height: 200) {
group() {
text(x: 50, y: 50, text: "JavaFX Hello World")
}
}
}
}
以下為以ScalaFX改寫上述範例: object HelloJavaOne extends JFXApp {
stage = new Stage {
title = "JavaFX Hello World"
width = 250
height = 200
scene = new Scene {
Text {
x = 50
y = 50
text = "JavaFX Hello World"
}
}
}
}
以下為以Visage改寫上述範例: Stage {
title: "JavaFX Hello World"
width: 250
height: 200
scene: Scene {
content: Text {
x: 50
y: 50
text: "JavaFX Hello World"
}
}
}
【參考資料】 [1] Java Official Web Site |

Java 學習之路

