JavaFX 相關知識

JavaFX是什麼?

“JavaFX腳本是一種聲明式、靜態類型編程語言。它具有一等函數(first-class functions)、聲明式的語法、列表推導(list-comprehensions)及基於依賴關係的增量式求值(incremental dependency-based evaluation)等特徵。”JavaFX腳本爲多種多樣的操作提供了聲明式、無中間程序邏輯的語法,這些操作包括創建2D動畫、設置屬性或者聲明在模式和視圖對象之間的綁定依賴關係。

什麼樣的函數能夠稱爲“first-class functions”?

在編程語言中,我們常常把那些將函數作爲一等對象的函數稱爲一等函數(first-class functions)。具體地說,就是編程語言支持在程序執行過程中構造新的函數,並將它們存儲在數據結構中作爲其它函數的參數的傳入參數,並在函數返回時將它們作爲函數值返回。本概念並不涵蓋任何語言和程序的外部函數或者程序,例如通過調用編譯器或者一個eval函數來創建新函數。
這裏提供一等函數的一個簡單示例:map或者mapcar函數,它使用一個函數和一個列表作爲參數,然後將通過將函數應用到列表中的每個成員後形成的列表作爲返回值。

“declarative syntax”是什麼意思?

與大多數依靠程序和顯式代碼來更新在變量或者屬性之間關係的編程語言不同,聲明式語言允許數值被聲明爲另一種方式。
在JavaFX的一個示例:
var a : Number = bind model.attrib/2;
無論何時model.attrib的數值發生改變,a的數值都將自動、透明地更新,更新期間無需調用任何程序。這對於在模式和視圖對象之間綁定依賴關係、控制GUI行爲是特別有用的。

“list-comprehensions”是什麼意思?

我們常常把“list-comprehensions”翻譯爲“列表推導”。列表推導是在語言級別上支持以多種方式創建、維護列表的方法。
在JavaFX中的一些示例:
var nums = [1,2,3,4]; var nums2 = [1..4]; //same as above var numsGreaterThanTwo = nums[. > 2]; var numsLessThanFour = select n from n in nums where n < 4;

什麼是"incremental dependency-based evaluation"?

“incremental dependency-based evaluation”譯爲“基於依賴關係的增量式求值”。在JavaFX中,屬性值能夠被聲明爲依賴於(綁定到)包含其它屬性的表達式。這樣,當某個被引用的屬性數值發生變化時,所有依賴此屬性的屬性都將直接或者間接地改變它們的數值,此過程無需調用任何的中間程序邏輯。這和在Excel之類的電子表格中使用方程式很類似。
這對於那些需要動態維護模式和視圖屬性,而又時常需要複雜的程序邏輯的GUI開發來說非常有用。

“操作(operation)” vs “函數(function)”

函數與操作之間的不同之處是函數可以遞增地反覆求值、可以綁定返回值、綁定參數、綁定變量/屬性,隱性綁定本地變量。
爲了進一步說明,請看下面的JavaFX代碼片段:
Class Foo ( attribute zap; function bar(x) { x + zap }}var afoo = Foo { zap: 14 }var zing = 1;var snap = afoo.bar(zing);bind dyn = afoo.bar(zing);
我們非常清楚地看到:無論zing和zap如何變化,snap將不會發生變化。而dyn則會隨着zing和zap的變化而改變。因爲在zing和zap的數值發生變化時,發生了一個增量式的求值過程:程序將變化的數值傳遞給依賴其的所有函數,並重新計算數值。

JavaFX的授權模式是怎麼的?

JavaFX的開發者很贊同讓用戶發佈自己的應用,並堅信開源和社區的力量。但當前的JavaFX版本是在評估授權下發布的,因此並不能夠被重新發布。你當然能夠發佈自己編寫的基於JavaFX的應用,但不能夠和JavaFX一起捆綁發佈,並需要告之使用者:需要到openjfx項目站點下載JavaFX二進制代碼庫。並且,由於正處於早期的JavaFX代碼還處在評估授權下,因此它不能用於商業用途。當Sun完成了JavaFX的商業化版本開發後,我相信這將會得到改變。

Sun是否規定了發佈JavaFX商業化產品的時間線?

很抱歉,目前沒有準確的時間約定,不過馬上就會制定出來。

JavaFX Runtime像JavaFX Script那樣開源嗎?

是的,JavaFX Runtime即將開放源代碼。

在JavaFX和…之間的不同

與F3比較:F3是Form Follows Function的縮寫,這是JavaFX平臺從前的名字。

與Java比較:JavaFX 是一種兼容JSR-223的腳本語言。它能夠使用Java類,並從Java類中被調用。

與Java 6.0提供的Scriting Engine比較:Java 6.0提供的Scriting Engine爲兼容JSR-223的腳本語言提供了運行平臺,JavaFX可以在Java 6.0提供的Scriting Engine上執行。而JavaFX並不依賴於Java 6.0,它可以在任何兼容JSR-223的腳本引擎(比如javax.script.ScriptEngine)下執行。

與SVG比較:SVG並不是一種程序語言;它是一種數據描述語言。其XML語法對於編程語言來講是非常可怕的。但SVG的交互性、兼容性是令人滿意的。目前JavaFX開發團隊並沒有計劃直接使用SVG。由於SVG和JavaFX都源自舊的PostScript和Java2D向量圖形模式,因此在某種程度上,我們已經在JavaFX中使用了SVG,但目前仍然存在某些值得注意的不兼容性。
Chris Oliver 已經編寫了SVG-to-F3 轉換程序。

與Swing比較:JavaFX是一種編寫Swing應用的新方式,它無需瞭解swing框架和java語言。

與JavaScript比較:在JavaFX和JavaScript之間唯一相同點就是它們都是兼容JSR-223的腳本語言。

與Ajax比較:Ajax是使用了JavaScript和異步更新的web瀏覽器端技術。它與JavaFX的關係:兩者都是UI相關的技術。但它們在語言和環境上完全不同。

與Savaje OS的關係:Sun正在計劃使用它們購買的Saveje手機系統和JVM來發布JavaFX Mobile,後者能在移動設備上運行JavaFX腳本,它將成爲Windows Mobile、Flash Lite的有力競爭者。

我能夠使用JavaFX編寫Java3D應用嗎?它兼容VRML或者X3D標準、Xj3D之類的代碼庫嗎?

沒有原因不能使用。JavaFX能夠和任何第三方代碼庫互操作,並且不需要任何特殊語法。目前JavaFX開發團隊正在進行開發支持Java3D的功能。

JavaFX是一種RCP(Rich Client Platform) 嗎?

是的。JavaFX不僅能夠用於RCP開發,也能夠用於RIA(Rich internet Applications)開發。

我能夠在web應用中使用JavaFX嗎?

JavaFX能夠用於編寫前端應用、web應用的視圖或者用戶接口,不過這都需要JVM的支持。

JavaFX將代替Java EE中的JSF和JSP嗎?

不,JSF和JSP用於編寫純粹的web應用(對於支持HTML的HTTP客戶端來講是可用的),而JavaFX需要位於客戶端的JVM。如果你希望編寫富客戶端的話,那麼就需要在客戶端安裝JRE,JavaFX能夠提供與基於Flash的Flex、基於.net的Silverlight相同的功能。常見的應用場景是開發運行在公司內網的應用。

JavaFX在運行時需要服務器嗎?

JavaFX是一種關注GUI的腳本語言;它主要用於桌面應用,因此不需服務器。如果你計劃部署JNLP(Java Web Start)的話,那麼你需要一臺web服務器。

運行JavaFX需要什麼條件?

兩種條件任選其一:
Java5以上、一個兼容JSR-223的實現、JavaFX代碼庫;
Java6以上、JavaFX代碼庫。

目前有JavaFX可用的編譯器嗎?

OpenFX Compiler是JavaFX編譯器項目,目前已經開放源代碼。
詳細情況請訪問:https://openjfx-compiler.dev.java.net/

開發中遇到的問題

JavaFX中有哪些固有的數據類型?

JavaFX中的固有數據類型:String、Boolean、Number、Integer。

JavaFX與Java類型之間的對應關係:

更多信息請訪問:
https://openjfx.dev.java.net/JavaFX_Programming_Language.html#basic_types

如何連接兩個字符串?“+”操作符已經不起作用了!?

與Java有所不同,JavaFX並沒有重載“+”操作符來使其用於字符串連接:
import javafx.ui.*;import javafx.ui.canvas.*; Frame { content: Label { text: "Hello " + "World" } visible: true}
如果嘗試運行上面的代碼,我們將看到以下的控制檯輸出:
compile thread: Thread[AWT-EventQueue-0,6,main]compile 2.031file:/C:/workspace/F3/HelloWorld.fx:6: incompatible types: expected Number, found String in "Hello "file:/C:/workspace/F3/HelloWorld.fx:6: incompatible types: expected Number, found String in "World"file:/C:/workspace/F3/HelloWorld.fx:6: incompatible types: expected String, found Number in text: "Hello " + "World"

實現方式之一:修改代碼

Java實現方法:
String s = "Your score is " + n + " out of " + total + ".";
JavaFX的字符串表達式操作符{}實現連接字符串的功能:
var s:String = "Your score is {n} out of {total}.";

實現方式之二:調用concat()方法

JavaFX提供了concat()方法來連接兩個字符串:
import javafx.ui.*;import javafx.ui.canvas.*; Frame { content: Label { text: "Hello ".concat("World") } visible: true}

如何將字符串轉換爲數字?

目前沒有直接的方式,但可以使用下面的代碼:
var value = new DecimalFormat("0").parse(someString);

如何將TextField的數值綁定到一個數字類型屬性?

使用綁定::
var total = 10TextField { value: bind total ...}
也可以使用format進行格式化:
value: bind "{total format as <<#,##0>>}"

如何設置用在Java Web Start上的JavaFX?

JNLP (Java Network Launch Protocol)是一種基於XML的協議,它能夠在網絡上部署Java和JavaFX應用。
這裏提供一個用於部署JavaFXPad的JNLP示例。
詳細示例請見:http://download.java.net/general/openjfx/demos/javafxpad.jnlp) 。
<?xml version="1.0" encoding="utf-8"?><jnlp spec="1.5+" codebase="http://download.java.net/general/openjfx/demos" href="javafxpad.jnlp"> <information> <title>JavaFX Demos:JavaFX Pad</title> <vendor>Sun Microsystems</vendor> <offline-allowed /> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.5+" href="http://java.sun.com/products/autodl/j2se" java-vm-args="-Xss1M -Xmx256M" > </j2se> <jar href="javafxrt.jar" main="true"/> <jar href="Filters.jar"/> <jar href="swing-layout.jar"/> <jar href="javafxpad.jar"/> </resources> <application-desc main-class="net.java.javafx.FXShell"> <argument>javafxpad.Main</argument> </application-desc></jnlp>

“Hello Web Start FX”示例

環境需求
• Java 5 JDK
• 從openjfx項目下載後獲得的JavaFX代碼包中提取出來的/lib/javafxrt.jar and lib/swing-layout.jar

“Hello Web Start JFX”程序代碼

文件名: HelloWebStart.fx
import javafx.ui.*;Frame { title : 'Hello Web Start JFX!' width : 600 height : 400 content: Label { text: 'Hello Web Start JFX!' font: Font{size: 32} } visible: true}

創建 HelloWebStartJFX.jar

jar cvf HelloWebStartJFX.jar HelloWebStart.fx

創建 HelloWebStartJFX.jnlp

文件名: HelloWebStartJFX.jnlp
<?xml version="1.0" encoding="utf-8"?><jnlp spec="1.5+" codebase="http://www.example.com/HelloWebStartJFX/" href="HelloWebStartJFX.jnlp"> <information> <title>Hello Web Start JFX</title> <vendor>John Doe</vendor> <homepage href="http://www.example.com/HelloWebStartJFX/"/> <description>Web Start example for JavaFX Scripts</description> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.5+" href="http://java.sun.com/products/autodl/j2se"> </j2se> <jar href="javafxrt.jar" main="true"/> <jar href="swing-layout.jar"/> <jar href="HelloWebStartJFX.jar"/> </resources> <application-desc main-class="net.java.javafx.FXShell"> <argument>HelloWebStart</argument> </application-desc></jnlp>

創建簽名密鑰

keytool -genkey -alias jfx -dname "CN=John Doe, O=JFX Inc." -validity 9999 -keystore jfx.keystore -keypass keyPassword -storepass storePassword

對jar文件進行簽名

jarsigner -keystore jfx.keystore -verbose -keypass keyPassword -storepass storePassword HelloWebStartJFX.jar jfxjarsigner -keystore jfx.keystore -verbose -keypass keyPassword -storepass storePassword javafxrt.jar jfxjarsigner -keystore jfx.keystore -verbose -keypass keyPassword -storepass storePassword swing-layout.jar jfx

連接到HelloWebStartJFX.jnlp

文件名: index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Hello Web Start JFX!</title> </head> <body> <h1>Hello Web Start JFX!</h1> <p><a href="HelloWebStartJFX.jnlp">Java Web Start: Hello Web Start JFX!</a></p> </body></html>

Web服務器: 設置用於.jnlp 的MIME類型

Apache服務器:在http.conf 或者 .htaccess文件中添加類型:
application/x-java-jnlp-file JNLP

將文件複製到Web服務器
mkdir /www/www.example.com/docs/HelloWebStartJFX/cp index.html HelloWebStartJFX.jnlp HelloWebStartJFX.jar javafxrt.jar swing-layout.jar /www/www.example.com/docs/HelloWebStartJFX/

啓動Web Start

通過www.example.com/HelloWebStartJFX/啓動web Start。

如何使用“全限定名”引用Java類?

全限定Java類名必須使用法語引號<< >>進行修飾。

如何訪問內部類和接口?

在訪問內部類和接口時,你只能使用內部類的編譯名。
例如:
在Java中的import java.util.Map.Entry,在JavaFX中將表示爲import java.util.Map$Entry。

在JavaFX中還需要注意的是在引用內部類時,你需要繼續使用Outer$Inner 這種形式的語法。爲了方便使用,你也可以相應地將導入語句修改爲:
import java.util.Map$Entry as Entry
這樣就不必重複地使用Outer$Inner形式了。
我能夠使用Java 5的枚舉(enumerations)嗎?
當然可以。你可以採用下面的方式引用它們:
import java.util.management.MemoryType; // 導入枚舉 var value = HEAP:MemoryType; // 使用枚舉值 // HEAP是MemoryType中的枚舉值 var allValues = MemoryType.values(); // 創建包含所有枚舉值的JavaFX數組

如何在JavaFX中輕鬆定製Swing組件?

這裏提供了一些對Swing組件進行快速封裝的代碼,它能用於JavaFX組件層中:

SwingWidget類定義:

文件名:SwingWidget.fx
package a.b.c;import javafx.ui.*;import javax.swing.JComponent;class SwingWidget extends Widget { attribute swingComponent: JComponent;}operation SwingWidget.createComponent():<<javax.swing.JComponent>> { return swingComponent;}

用法:

下面提供了一個使用SwingWidget的簡單示例。請注意在樹形列表中提供的數據來自於默認的樹形模型,而不是JavaFX所特有的。
文件名:WidgetTest.fx
package a.b.c;import javafx.ui.*;import javafx.ui.canvas.*;import java.lang.System;import javax.swing.JTree;import a.b.c.SwingWidget;Frame { onClose: operation() { System.exit(0); } content: SwingWidget { swingComponent: new JTree() } visible: true title: "WTF, the Widget Test Framework"}
運行界面:


爲什麼我的某些.fx文件不能被JavaFX Pad重新裝載?

非常抱歉地告訴你,JavaFXPad目前的功能非常有限。他並不能檢測到外部文件的改變。爲了讓它能夠“看到”你的修改,你需要以手工的方式在JavaFXPad中重新打開修改後的文件。

如何引用其它JavaFX文件?

JavaFX能夠從以下三種資源中引用靜態值、變量和類:
1.在同一文件內
2.在相同的目錄/包路徑下的文件
3.在其它的包路徑下的文件

首先,第一種方式非常簡單。如果你正在引用處於相同文件中的類,那麼你只需要使用類名即可(類可以被定義在引用之前或者之後)。而變量則要在它們被聲明之後才能被引用。

對於第二種方式,顯而易見,你無須對處於相同包路徑下的每個.fx文件都使用import語句,而只要提供具有它們所在的同一包路徑的import語句即可。

如果你有其它的內部類或者你需要從不同的包路徑下引入類,那麼就需要使用import語句完成一點額外工作:使用import語句將.fx文件導入,而不是在此文件中的某個特定的類。例如,如果MediaTable.fx包含兩個類:MediaTableColumn和MediaTableRow,那麼你只需要importing MediaTable這一條語句就可以導入這兩個類。

你也可以像使用Java一樣使用 import *語句。但由於這種方式降低了代碼的可讀性,所以並不推薦給大家。

JavaFX腳本提供類似 __LINE__這樣的魔術常量(magic constants)嗎?

魔術常量

• __DIR__ -- 返回包含當前FX源文件的目錄的URL。如果當前文件是從jar文件裝載的,那麼返回值可能是jar文件的URL。
• __FILE__ -- 返回當前源文件的URL。
• __LINE__ -- 返回當前源文件中的當前行。
• __ARCHIVE__ -- 返回包含當前文件的jar文件的URL。

示例

import javafx.ui.*; Frame { title : 'Magic Constants' width : 700 height : 400 content: Label {text: "<html><dl> <dt>__DOCBASE__</dt><dd>{__DOCBASE__}</dd> <dt>__DIR__</dt> <dd>{__DIR__}</dd> <dt>__FILE__</dt> <dd>{__FILE__}</dd> <dt>__LINE__</dt> <dd>{__LINE__}</dd> <dt>__ARCHIVE__</dt><dd>{__ARCHIVE__}</dd> </dl></html>"} visible: true}// Frame

更多信息

• Christopher Oliver編寫的"Magic Constants"

JavaFX中的保留字有哪些?

after
and
as
assert
attribute
before
bind
break
by
catch
class
continue
delete
distinct
do
dur
easeboth
easein
easeout
else
endif
extends
false
finally
first
for
foreach
format
fps
from
function
if
import
in
index
indexof
insert
instanceof
into
inverse
last
later
lazy
linear
motion
nodebug
new
not
null
on
operation
or
order
package
private
protected
public
readonly
return
reverse
select
sizeof
super
then
this
throw (請注意不是throws)
trigger
true
try
typeof
unitinterval
valueof
var
where
while
xor

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章