cleverpig 發表于 2007-09-24 12:30:35
作者:cleverpig 來源:OpenJFX&Matrix
評論數:0 點擊數:261 投票總得分:5 投票總人次:1
關鍵字:JavaFX FAQ 解答
常見問題
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語法對于編程語言來講是非??膳碌摹5玈VG的交互性、兼容性是令人滿意的。目前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.031
file:/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 = 10
TextField {
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+"
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 />
<description>Web Start example for JavaFX Scripts</description>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.5+" >
</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 jfx
jarsigner -keystore jfx.keystore -verbose -keypass keyPassword -storepass storePassword javafxrt.jar jfx
jarsigner -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