轉(zhuǎn)帖|其它|編輯:郝浩|2008-09-01 10:38:02.000|閱讀 2004 次
概述:JavaFX 是 Sun 推出的一套基于 Java 技術的產(chǎn)品家族。 JavaFX Script 可以用來高效的創(chuàng)建富媒體和交互性很強的應用。 JavaFX 是 Adobe Flex 和 Microsoft Silverlight 的有力競爭者。本文通過具體的實例介紹了 JavaFX Script 語言本身的一些高級特性并討論了 JavaFX Script 中的一些高級話題,包括創(chuàng)建復雜的用戶界面、實現(xiàn)動畫效果、JavaFX Script 應用的部署和在一個獨立的 Java 應用程序中嵌入 JavaFX Script 等。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
JavaFX Script 語言簡介
JavaFX 是 Sun 推出的一套基于 Java 技術的產(chǎn)品家族,其目的是為從桌面機、移動設備、機頂盒到藍光光盤等提供一致的用戶體驗。 JavaFX 目前包含 JavaFX Script 和 JavaFX Mobile 。 JavaFX Script 可以用來高效的創(chuàng)建富媒體和交互性很強的應用。 JavaFX 是 Adobe Flex 和 Microsoft Silverlight 的有力競爭者。本文通過具體的例子介紹了 JavaFX Script 語言本身的一些高級特性。這些特性包括塊表達式、范圍(Range)表達式、序列的修改、觸發(fā)器(Trigger)和數(shù)據(jù)綁定。另外還結合具體的應用,討論了 JavaFX Script 中的一些高級話題,包括創(chuàng)建復雜的用戶界面、實現(xiàn)動畫效果、JavaFX Script 應用的部署和在一個獨立的 Java 應用程序中嵌入 JavaFX Script 等。
目前 JavaFX Script 語言本身在不斷的變化之中,本文中對 JavaFX Script 語法的說明和實例,均基于 JavaFX Script 在 2008 年 7 月 21 號的版本。開發(fā)環(huán)境采用 NetBeans 6.1,并安裝 JavaFX Script 插件。請從 參考資源 中下載相關的工具。
JavaFX Script 高級特性
下面具體介紹 JavaFX Script 語言的一些高級特性。
塊表達式
JavaFX Script 中的塊表達式是包含在 {} 中的一系列用分號分隔的語句。如果塊表達式中的最后一個語句是表達式的話,那么這個塊表達式的值就是最后這個表達式的值;否則該塊表達式的值是 Void 類型。塊表達式適合于那些在代碼中只出現(xiàn)一次的計算邏輯。因為只出現(xiàn)一次,可以不用把這樣的邏輯封裝在一個 function 中。而塊表達式又可以把這部分邏輯的代碼與其它部分區(qū)別開來。在 代碼清單 1 中,對于薪水的計算邏輯被封裝在一個塊表達式中。
清單 1. 塊表達式示例
var baseSalary = 10000;
var salary = {
12 * (baseSalary + 1000) + 2 * baseSalary
};
System.out.println(salary);
范圍表達式
熟悉其他動態(tài)語言,如 Python、Ruby 和 Groovy 的人對于范圍(Range)表達式可能并不陌生。 JavaFX Script 也引入了同樣的范圍表達式,可以用來定義一個序列。不過在使用方式與其他語言有些不同。
在 JavaFX Script 中可以通過 [number1..number2] 來定義一個序列。這里需要注意的是兩個邊界數(shù)字 number1 和 number2 都是包含在序列里面的。如 [0..5] 包含 0,1,2,3,4,5 這六個數(shù)字。這點和 Ruby 里面的 number1...number2 和 Groovy 里面的 number1..number2 是一樣的。默認情況下,范圍中的數(shù)字之間的間隔是 1,可以通過在 number2 后面加上顯式的 step 來聲明間隔。比如 [0..9 step 3] 包含的數(shù)字是 0,3,6,9 。
當 number1 大于 number2 的時候,可以通過指定值為負數(shù)的 step 來生成降序排列的序列。如 [5..0 step -1] 包含的數(shù)字是 5,4,3,2,1,0 ;如果不指定 step,或是 step 的值為正數(shù)的話,生成的序列實際上是空的。如 [5..0] 是個空的序列。
序列的修改
JavaFX Script 提供了兩個強大的操作符 insert 和 delete 來對序列進行操作。
insert 語句的語法如 代碼清單 2 中所示。
清單 2. insert 語句的語法
insert x into seq
insert x before seq[idx]
insert x after seq[idx]
從代碼清單 2 列出的語法中可以看到,insert 語句可以往序列中的指定位置插入新元素。使用 insert x into seq 會把 x 添加到序列末尾。而 insert x before seq[idx] 和 insert x after seq[idx] 則分別可以把新元素插入到 seq[idx] 所對應的元素的前面和后面。
delete 的語法如 代碼清單 3 中所示。
清單 3. delete 語句的語法
delete seq
delete x from seq
delete seq[idx]
delete seq[a..b]
在 代碼清單 3 列出的四種用法中,第一種會刪除整個序列;第二種和第三種都會刪除指定元素,不同的是第二種需要指定元素的值,而第三種需要指定其序號;第四種是用來刪除序列中給定范圍之內(nèi)的全部元素的。
觸發(fā)器
JavaFX Script 提供類似 SQL 中觸發(fā)器的機制來處理數(shù)據(jù)的變化。如果在某個屬性上聲明了觸發(fā)器,那么當它的值發(fā)生變化的時候,觸發(fā)器就會被觸發(fā),預先定義的邏輯就會被執(zhí)行。代碼清單 4 中給出了觸發(fā)器的一個實例。
清單 4. 觸發(fā)器示例
class Person {
attribute address : String
on replace oldAddress = newAddress {
System.out.println(" 地址已經(jīng)從 {oldAddress} 改為 {newAddress} 。 ");
};
}
var person = Person {
address : " 北京市朝陽區(qū) "
};
person.address = " 北京市海淀區(qū) "; [SPAN]
從代碼清單 4 中可以看到,當屬性 address 的值發(fā)生改變時,會輸出相應的提示信息。該屬性的舊值和新值都可以得到,并在相應的處理邏輯代碼中使用。觸發(fā)器不僅可以用于單值屬性,也可以用于序列上。代碼清單 5 和 代碼清單 6 中給出的兩個例子分別演示了如何在序列中插入和刪除元素之后得到通知。
清單 5. 序列中插入新元素的觸發(fā)器
class Company {
attribute employees : String[]
on replace oldEmployees = newEmployees {
if (sizeof employees - sizeof oldEmployees == sizeof newEmployees) {
System.out.println(" 歡迎新員工 {newEmployees} 加入! ");
}
};
}
var company = new Company();
insert " 張三 " into company.employees;
insert " 李四 " into company.employees;
清單 6. 序列中刪除元素的觸發(fā)器
class Student {
attribute courses : String[]
on replace oldCourses = newCourses {
if (sizeof newCourses == 0) {
System.out.println(" 你已經(jīng)成功退選了課程 {oldCourses} 。 ");
}
}
}
var student = new Student();
insert " 網(wǎng)絡信息體系結構 " into student.courses;
insert " 編譯原理 " into student.courses;
delete student.courses[0];
數(shù)據(jù)綁定
JavaFX Script 中,屬性初始化的時候,可以通過 bind 將屬性的值和某個表達式綁定起來,當該表達式所引用的對象發(fā)生變化時,該屬性的值也會自動更新。方法也可以通過 bound 來設成綁定的。以 代碼清單 7 為例,方法 getPercent 在其內(nèi)部的變量的值發(fā)生改變的時候,會自動重新求值。屬性 currentValue 的值的改變首先使得方法 getPercent 的值發(fā)生改變,然后再使得 percent 的值發(fā)生變化。這一切都是自動的。
清單 7. 數(shù)據(jù)綁定示例
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
}
let percent = bind stock.getPercent();
System.out.println(percent);
stock.currentValue = 101;
System.out.println(percent);
上面介紹了 JavaFX Script 語言本身的一些高級特性,下面將以實例的方式討論 JavaFX Script 開發(fā)中的幾個重要的主題。
創(chuàng)建復雜用戶界面
用過 Swing 的人可能都有個感覺,那就是用 Swing 創(chuàng)建用戶界面的時候,不僅編寫起來麻煩,代碼也比較冗長。使用 JavaFX Script,可以幫助你更快更簡單的創(chuàng)建用戶界面。 JavaFX Script 簡化用戶界面的創(chuàng)建的能力主要體現(xiàn)在三個方面:
在 JavaFX Script 中使用 Swing 的 GUI 組件是很容易的。 JavaFX Script 在 javafx.ext.swing 包中提供了很多常用的 Swing 組件的封裝。這些組件可以在 JavaFX Script 代碼中直接以聲明式的方式使用。另外一些復雜的組件,如 JTable 和 JTree,目前在 JavaFX Script 中還不可以直接使用。在這種情況下,需要繼承 javafx.ext.swing.Component 類并實現(xiàn)該類的抽象方法 createJComponent()。該方法返回一個 JComponent 對象。[SPAN]
下面以一個具體的實例來說明如何創(chuàng)建復雜用戶界面。該應用是一個 RSS 訂閱源(Feed)的閱讀器,它可以解析 OPML 文件并在左側以一個樹形結構來顯示所有的訂閱源。當點擊某個訂閱源時,可以在右側看到該訂閱源的內(nèi)容。顯示所有訂閱源的是左側的 OmplViewer,顯示訂閱源內(nèi)容的是右側的 FeedViewer。該應用的截圖見 圖 1。
圖 1. RSS 訂閱源閱讀器
由于 RSS 訂閱源閱讀器的代碼比較多,在本文中將只介紹其中的重點,完整的代碼請下載。
繼承javafx.ext.swing.Component
在上面提到,一些復雜的 Swing 組件,目前需要通過繼承 javafx.ext.swing.Component 的方式來使用。在 RSS 訂閱源閱讀器中,左側顯示所有訂閱源的組件是 JTree。類 OpmlViewer 繼承自 javafx.ext.swing.Component,并實現(xiàn)其createJComponent()方法,該方法創(chuàng)建了一個JTree 對象,并包裝在一個 JScrollPane 中。該類中的其它代碼都與 JTree 對象交互。具體見 代碼清單 8。
清單 8. 繼承 javafx.ext.swing.Component 示例
public class OpmlViewer extends Component {
private attribute tree : JTree;
protected function createJComponent(): JComponent {
tree = new JTree();
return new JScrollPane(tree);
}
} [SPAN]
觸發(fā)器的使用
類 OpmlViewer 有一個屬性 opmlFilePath 用來表示 OPML 文件的路徑。當該屬性的值發(fā)生改變的時候,OpmlViewer 就需要顯示該 OPML 文件中的所有訂閱源。這是通過在屬性 opmlFilePath 上創(chuàng)建一個觸發(fā)器來實現(xiàn)的。具體見 代碼清單 9。
清單 9. OpmlViewer 中的觸發(fā)器使用
public attribute opmlFilePath : String on replace
oldPath = newPath {
if (newPath != null and not "".equals(newPath.trim())) {
setOpmlFilePath(newPath);
}
}
數(shù)據(jù)綁定的使用
數(shù)據(jù)綁定在這個應用中主要用來協(xié)調(diào)左側的 OmplViewer 和右側的 FeedViewer。FeedViewer 的屬性 feedUrl 綁定到 OmplViewer 的屬性 selectedFeedUrl。這樣當用戶選擇了某個訂閱源的時候,OmplViewer 的屬性 selectedFeedUrl 的值會發(fā)生變化,F(xiàn)eedViewer 的屬性 feedUrl 的值也會隨之變化。FeedViewer 就會去加載新的訂閱源內(nèi)容了。具體見 代碼清單 10。
清單 10. OpmlView 和 FeedViewer 之間的數(shù)據(jù)綁定
var opmlViewer = OpmlViewer {
opmlFilePath : "c:\\google-reader-subscriptions.xml",
hmax : 200
hmin : 100
};
var feedViewer = FeedViewer {
feedUrl : bind opmlViewer.selectedFeedUrl
};
上面介紹了如何在 JavaFX Script 中創(chuàng)建復雜的用戶界面,下面將涉及 JavaFX Script 中一個有趣的話題,那就是實現(xiàn)動畫效果。
創(chuàng)建動畫
使用 JavaFX Script 來創(chuàng)建動畫是一件非常容易的事情。 JavaFX Script 所采用的動畫方式叫“關鍵幀動畫(key frame animation)”。這種動畫是通過一系列的場景的轉(zhuǎn)換來完成的,而場景則是由特定時間點上的關鍵幀來表示的。程序員只需要以聲明式的方式定義這些關鍵幀,系統(tǒng)會自動的完成剩下的工作。“關鍵幀動畫”又分成兩種,離散型和插值型。兩者的區(qū)別在于:對于后者,系統(tǒng)會用特定的插值函數(shù)來計算每個關鍵幀之間的中間狀態(tài)。 JavaFX Script 中的動畫主要是依靠 javafx.animation.Timeline、javafx.animation.KeyFrame、javafx.animation.KeyValue 這三個類來完成的。
這三個類的基本說明如下:
KeyValue 的用法
下面用一個例子來具體說明 KeyValue 的用法,見 代碼清單 11。
清單 11. KeyValue 的用法
var simpleVar = 0;
function output() : Void {
System.out.println("The value of simpleVar is {simpleVar}.");
}
Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time : 1s
action: output
},
KeyFrame {
time : 1.5s
action : output
},
KeyFrame {
time : 2s
values : [
simpleVar => 200 tween Interpolator.LINEAR
]
action: output
}
]
}.start()
代碼清單 11 中創(chuàng)建了一個無限運行的 Timeline,該 Timeline 包含 3 個關鍵幀,所關聯(lián)的時間點分別是 1 秒、1.5 秒和 2 秒。在這 3 個關鍵幀所關聯(lián)的時間點到達的時候,都會執(zhí)行 output 方法,該方法會打印出 simpleVar 的值。需要說明的是在第三個關鍵幀上,通過 values 聲明了 simpleVar 在該關鍵幀中的值是 200,并且是通過線性插值(Interpolator.LINEAR)的方式來計算中間值。因此,在 1 秒和 1.5 秒的關鍵幀中,simpleVar 的值就是根據(jù)線性插值的方式計算出來的。[SPAN]
動畫實例
下面通過一個實例來說明如何使用 JavaFX Script 來編寫動畫。在這個動畫實例中,將演示地球自轉(zhuǎn)和月球圍繞地球的轉(zhuǎn)動。動畫的演示效果見 圖 2 所示。需要說明的是 圖 2 中的地球和月球的大小以及月球的運行軌道均為示意。
圖 2. 地球自轉(zhuǎn)和月球圍繞地球運轉(zhuǎn)的動畫
該動畫的源代碼如代碼清單 12所示。
清單 12. 地球和月球運行示意動畫的源代碼
var earthImages = for (i in [1..7]) {
Image {url : "file:images/earth{i}.png"}
}
var moonImage = Image {url : "file:images/moon.gif"};
var currentEarthImage = earthImages[0];
var earthTimeline = Timeline {
keyFrames: for (image in earthImages) {
KeyFrame {
time: 300ms* indexof image
action: function(){currentEarthImage=image;}
}
},
repeatCount : Timeline.INDEFINITE
}
var moonX = 525;
var moonY = 260;
var moonTimeline = Timeline {
var top_right = at (300ms) {
moonX => 425 tween Interpolator.LINEAR;
moonY => 425 tween Interpolator.LINEAR;
}
var right = at (600ms) {
moonX => 260 tween Interpolator.LINEAR;
moonY => 515 tween Interpolator.LINEAR;
}
var right_bottom = at (900ms) {
moonX => 110 tween Interpolator.LINEAR;
moonY => 425 tween Interpolator.LINEAR;
}
var bottom = at (1.2s) {
moonX => 5 tween Interpolator.LINEAR;
moonY => 260 tween Interpolator.LINEAR;
}
var bottom_left = at (1.5s) {
moonX => 110 tween Interpolator.LINEAR;
moonY => 110 tween Interpolator.LINEAR;
}
var left = at (1.8s) {
moonX => 260 tween Interpolator.LINEAR;
moonY => 5 tween Interpolator.LINEAR;
}
var left_top = at (2.1s) {
moonX => 425 tween Interpolator.LINEAR;
moonY => 110 tween Interpolator.LINEAR;
}
var top = at (2.4s) {
moonX => 515 tween Interpolator.LINEAR;
moonY => 260 tween Interpolator.LINEAR;
}
keyFrames:
[top_right, right, right_bottom, bottom, bottom_left, left, left_top, top],
repeatCount : Timeline.INDEFINITE
}
Frame {
title: "Earth and Moon"
width: 560
height: 580
closeAction: function() {
earthTimeline.stop();
moonTimeline.stop();
java.lang.System.exit( 0 );
}
visible: true
stage: Stage {
fill : Color.BLACK
content: [
ImageView {
image: bind currentEarthImage,
transform : Transform.translate(110, 110);
},
ImageView {
image : moonImage
transform : bind Transform.translate(moonX, moonY)
}
]
}
}
earthTimeline.start();
moonTimeline.start();
代碼中創(chuàng)建了兩個 Timeline,一個用來表示地球的自轉(zhuǎn),另外一個用來表示月球圍繞地球的轉(zhuǎn)動。表示地球自轉(zhuǎn)的動畫使用的是離散型“關鍵幀動畫”。該 Timeline earthTimeline 包含 7 個關鍵幀,每個幀的間隔是 300 毫秒。當每個幀所關聯(lián)的時間點到達的時候,所執(zhí)行的動作是將 currentEarthImage 的值設成該幀對應的地球的一張圖片。當 currentEarthImage 的值發(fā)生改變的時候,ImageView 就會顯示那張圖片。[SPAN]
表示月球圍繞地球轉(zhuǎn)動的動畫使用的是插值型“關鍵幀動畫”。該 Timeline moonTimeline 的效果是使得代表月球的圖片按照一個圓形來變換位置。該 Timeline 包含 8 個關鍵幀,分別表示圓周上的 8 個位置。當每個幀所關聯(lián)的時間點到達的時候,所執(zhí)行的動作是 moonX 和 moonY 的值設成計算出來的月球的圖片在窗口中的位置。通過 Transform.translate(moonX, moonY) 這樣的一個變換來改變圖片的位置。插值型“關鍵幀動畫”指的是,程序中聲明了 8 個關鍵幀,系統(tǒng)會自動按照指定的函數(shù)來計算圖片在中間狀態(tài)的位置。這里使用的插值函數(shù)是線性插值。
值得注意的是,如果使用 代碼清單 12 中的方式,運行起來之后,月球的圖片的運動并不是一個圓形,而是一個正八邊形。這是由于以線性插值的方式計算出來的中間狀態(tài)的位置與實際需要的弧形有較大的偏差。而目前 JavaFX Script 并沒有提供弧形的插值函數(shù)。所以一個更好的選擇是使用離散型“關鍵幀動畫”,并且提供更多的關鍵幀,這樣使得月球圖片的運行軌跡更加平滑。代碼清單 13 中給出了新的關鍵幀的生成方法。
清單 13. 更平滑的關鍵幀生成方法
function getKeyFrames() : KeyFrame[] {
var frames = [] as KeyFrame[];
for (i in [1..36]) {
var y = 260 - 260 * Math.sin((360 - i * 10) * Math.PI / 180);
var x = 260 + 260 * Math.cos((360 - i * 10) * Math.PI / 180);
var frame = KeyFrame {
time : 200ms * i
action : function() {
moonX = x.intValue();
moonY = y.intValue();
}
};
insert frame into frames;
}
return frames;
}
從代碼清單 13 中可以看到,一共定義了 36 個關鍵幀,每個幀對應的 moonX 和 moonY 的值都是通過計算得出來的。使用了上面的 36 個關鍵幀之后,運行起來可以看到月球圖片的更好的動畫效果。
在討論完 JavaFX Script 中的動畫之后,下面將討論如何部署 JavaFX Script 應用。
部署 JavaFX Script 應用
在完成 JavaFX Script 應用的編寫和調(diào)試之后,就可以部署該應用了。 JavaFX Script 的應用的部署方式主要有兩種,分別是使用 Java Web Start 和使用 Open JavaFX 編譯器。下面具體介紹這兩種部署方式。
使用 Java Web Start
Java Web Start 是從 JRE 5.0 開始被引入到 Java 運行環(huán)境(JRE)中來的。它使得可以從 Web 下載和運行 Java 程序。當本機安裝了 5.0 及以上版本的 JRE 后,如果通過瀏覽器訪問內(nèi)容類型(Content type)是 application/x-java-jnlp-file 的 URL 時,Java Web Start 會自動運行,并下載相應的 JNLP 文件,來啟動 Java 應用。
JNLP 的文件內(nèi)容可以參考 代碼清單 14。該 JNLP 文件可以用來啟動前面提到的 JavaFX Script 應用“ RSS 訂閱源閱讀器”。
清單 14. “ RSS 訂閱源閱讀器”的 JNLP 文件
<?xml version="1.0" encoding="utf-8"?>
<jnlp
spec="1.5+"
codebase="//localhost:8080/javafx"
href="feedReader.jnlp">
<information>
<title>RSS Feed Reader</title>
<vendor>Fu CHENG</vendor>
<offline-allowed />
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.5+" href="//java.sun.com/products/autodl/j2se"
java-vm-args="-Xss1M -Xmx256M"
>
</j2se>
<jar href="javafxrt.jar"/>
<jar href="javafxgui.jar"/>
<jar href="javafx-swing.jar"/>
<jar href="Scenario.jar"/>
<jar href="rome-0.8.jar"/>
<jar href="jdom.jar"/>
<jar href="FeedReader.jar" main="true"/>
</resources>
<application-desc main-class="feedreader.Main">
</application-desc>
</jnlp>
需要說明的是,在使用 Java Web Start 時,所有的 jar 包都必須經(jīng)過數(shù)字簽名。可以使用 JDK 中自帶的 jarsigner 這個工具。
使用 OpenJFX 編譯器
OpenJFX 是 JavaFX 開源社區(qū)中的一個孵化項目,它的作用是將 JavaFX Script 編譯成 JVM 上可以直接運行的 class 文件(字節(jié)碼)。從 參考資源 中下載了 OpenJFX 的編譯器之后,通過運行 javafxc 命令就可以將一個 JavaFX Script 文件編譯成一系列 Java class 文件。再使用 javafx 命令就可以運行該應用。
在獨立的 Java 應用中嵌入 JavaFX Script
JDK 6.0 中引入了 JSR 223(Scripting 框架),使得可以在 JVM 上執(zhí)行 JavaScript、Python、Ruby 和 JavaFX Script 等動態(tài)語言。如果你的 JavaFX Script 是作為一個獨立的 Java 應用的一部分的話,使用 JSR 223 可以很容易將 JavaFX Script 嵌入其中。
下面以一個簡單計算器的例子來說明如何使用 JSR 223 來將 JavaFX Script 嵌入 Java 應用中。該簡單計算器可以接受用戶輸入的算術表達式并將計算結果告訴用戶。算術表達式可以包含加、減、乘、除和括號等。如果使用 Java 來計算算術表達式的值話,需要對表達式進行分析,拆分成可以識別的符號,再進行運算。而如果使用 JavaFX Script 的話,只需要將整條表達式交給 JavaFX 引擎去求值即可。因此,整個程序由 Java 來處理用戶的輸入和輸出結果,使用 JavaFX Script 來求值。具體見 代碼清單 15。
清單 15. Java 應用中嵌入 JavaFX Script 的示例
import static java.lang.System.out;
class CalculationException extends Exception {
public CalculationException(String message) {
super(message);
}
}
public class Main {
private static ScriptEngine engine = getScriptEngine();
public static void main(String[] args) {
out.println("Enter the expression after the >, " +
"enter 'q' to exit. Spaces are not allowed.");
out.print(">");
Scanner sc = new Scanner(System.in);
try {
while (sc.hasNext()) {
String input = sc.next();
if ("q".equals(input.trim())) {
out.println("Exit!");
break;
}
try {
out.println(calculate(input));
} catch (CalculationException ce) {
out.println(ce.getMessage());
}
out.print(">");
}
} finally {
sc.close();
}
}
private static ScriptEngine getScriptEngine() {
ClassLoader loader = Thread.currentThread().getContextClassLoader();
ScriptEngineManager manager = new ScriptEngineManager(loader);
ScriptEngine engine = manager.getEngineByExtension("fx");
return engine;
}
private static String calculate(String expression)
throws CalculationException {
if (engine == null) {
throw new CalculationException(
"Can not find the JavaFX script engine!");
}
try {
Object result = engine.;
return result == null ? "" : result.toString();
} catch (ScriptException e) {
throw new CalculationException("Wrong expression!");
}
}
}
需要說明的是,必須將 OpenJFX 編譯器中的 javafxc.jar 這個包添加進來,否則會出現(xiàn)找不到ScriptEngine的錯誤。這是由于 JavaFX Script 的引擎是由 javafxc.jar 包中的 com.sun.tools.javafx.script.JavaFXScriptEngineFactory 類來實現(xiàn)的。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務必注明出處、不得修改原文相關鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:IBM