JavaFX Script 是 Sun 推出的基於 Java 技術的腳本語言,旨在高效構建富媒體互動應用,直指 Adobe Flex 與 Microsoft Silverlight。本文基於 2008 年 7 月版本(NetBeans 6.1 + JavaFX Plugin 環境),深度解析其進階語法特性與實戰應用。
以 {} 包裹、分號分隔的語句序列。最後一句若為表達式,其值為整個區塊值;否則為 Void。適合一次性計算邏輯,無需封裝為函數,又能隔離代碼結構:
var baseSalary = 10000;
var salary = {
12 * (baseSalary + 1000) + 2 * baseSalary
};
System.out.println(salary);
[n1..n2] 定義序列,雙邊界包含(如 [0..5] 含 0,1,2,3,4,5)。預設步長 1,可指定 step:[0..9 step 3] 產生 0,3,6,9。降序需負步長:[5..0 step -1] 產生 5,4,3,2,1,0;若 n1 > n2 且無負步長則為空序列。
insert:insert x into seq(尾部)、insert x before seq[i]、insert x after seq[i]。
delete:delete seq(整個)、delete x from seq(指定值)、delete seq[i](指定索引)、delete seq[a..b](範圍)。
屬性值變更時自動執行邏輯,可獲取新舊值。適用單值屬性與序列:
class Person {
attribute address: String
on replace oldAddress = newAddress {
System.out.println("地址從 {oldAddress} 改為 {newAddress}。");
}
}
var person = Person { address: "北京市朝陽區" };
person.address = "北京市海澱區"; // 觸發列印
序列觸發器範例(偵測插入/刪除):
class Company {
attribute employees: String[]
on replace oldEmployees = newEmployees {
if (sizeof employees - sizeof oldEmployees == sizeof newEmployees) {
System.out.println("歡迎新員工 {newEmployees} 加入!");
}
}
}
bind 將屬性與表達式綁定,依賴對象變更自動更新;bound function 定義綁定方法:
class Stock {
attribute currentValue: Number on replace oldValue = newValue {
lastValue = oldValue
}
attribute lastValue: Number
bound function getPercent(): Number {
return (currentValue - lastValue) / lastValue
}
}
var stock = Stock { currentValue: 100, lastValue: 98.6 }
var percent = bind stock.getPercent()
stock.currentValue = 101 // percent 自動更新
JavaFX Script 三大優勢簡化 UI 開發:
text 綁定 Employee 的 name)。PropertyChangeListener 模式。Swing 組件整合:javafx.ext.swing 封裝常用 Swing 組件;複雜組件(JTable、JTree)需繼承 Component 並實作 createJComponent()。

OpmlViewer 繼承 Component 封裝 JTree 顯示 OPML 訂閱樹。opmlFilePath 掛載觸發器:路徑變更自動解析載入。FeedViewer 的 feedUrl 綁定 OpmlViewer.selectedFeedUrl,選擇訂閱自動載入內容。JavaFX 採用關鍵幀動畫:聲明式定義關鍵幀,系統自動插值。核心三類:
Timeline:動畫時間軸,可嵌套、無限循環。KeyFrame:時間點關鍵幀,含 KeyValue、子時間軸、動作(action)。KeyValue:屬性目標值與插值函數(Interpolator.LINEAR 等)。
// 地球自轉:離散型,7 幀,間隔 300ms
var earthTimeline = Timeline {
keyFrames: for (img in earthImages) KeyFrame {
time: 300ms * indexof img
action: function() { currentEarthImage = img; }
}
repeatCount: Timeline.INDEFINITE
}
// 月球公轉:插值型,8 關鍵幀定義圓周位置
var moonTimeline = Timeline {
var top_right = at (300ms) { moonX => 425 tween Interpolator.LINEAR; ... }
keyFrames: [top_right, right, ...]
repeatCount: Timeline.INDEFINITE
}
// UI 綁定
Frame {
stage: Stage {
content: [
ImageView { image: bind currentEarthImage, transform: Transform.translate(110,110) }
ImageView { image: moonImage, transform: bind Transform.translate(moonX, moonY) }
]
}
}
優化建議:線性插值產生多邊形軌跡,若需平滑圓弧,改用離散型並增加關鍵幀密度(如 36 幀對應 10° 間隔),透過三角函數計算精確座標。
需所有 JAR 數位簽名(jarsigner)。範例 JNLP:
<jnlp spec="1.5+" codebase="https://localhost:8080/javafx" href="feedReader.jnlp">
<resources>
<j2se version="1.5+" java-vm-args="-Xss1M -Xmx256M"/>
<jar href="javafxrt.jar"/> <jar href="javafxgui.jar"/> ...
<jar href="FeedReader.jar" main="true"/>
</resources>
<application-desc main-class="feedreader.Main"/>
</jnlp>
開源孵化專案,將 .fx 編譯為 JVM 位元碼(.class)。javafxc 編譯,javafx 執行。
JDK 6 JSR 223 Scripting API 支援嵌入動態語言。範例:簡易計算器,Java 處理 I/O,JavaFX Script 求值算術表達式:
ScriptEngine engine = new ScriptEngineManager(loader).getEngineByExtension("fx");
Object result = engine.eval("(3+5)*2"); // 直接求值
注意:需將 javafxc.jar 加入類路徑,否則找不到 JavaFXScriptEngineFactory。
JavaFX Script 以聲明式語法、強大綁定、觸發器、關鍵幀動畫、靈活部署與嵌入能力,為富客戶端開發提供極具生產力的工具箱。掌握其進階特性,能讓開發者以更少代碼實現更豐富的互動體驗。