JavaFX應(yīng)用問(wèn)題解答
cleverpig 發(fā)表于 2007-09-24 12:30:35作者:cleverpig 來(lái)源:OpenJFX&Matrix
評(píng)論數(shù):0 點(diǎn)擊數(shù):261 投票總得分:5 投票總?cè)舜?1
關(guān)鍵字:JavaFX FAQ 解答
常見(jiàn)問(wèn)題
JavaFX是什么?
“JavaFX腳本是一種聲明式、靜態(tài)類(lèi)型編程語(yǔ)言。它具有一等函數(shù)(first-class functions)、聲明式的語(yǔ)法、列表推導(dǎo)(list-comprehensions)及基于依賴(lài)關(guān)系的增量式求值(incremental dependency-based evaluation)等特征。”JavaFX腳本為多種多樣的操作提供了聲明式、無(wú)中間程序邏輯的語(yǔ)法,這些操作包括創(chuàng)建2D動(dòng)畫(huà)、設(shè)置屬性或者聲明在模式和視圖對(duì)象之間的綁定依賴(lài)關(guān)系。
什么樣的函數(shù)能夠稱(chēng)為“first-class functions”?
在編程語(yǔ)言中,我們常常把那些將函數(shù)作為一等對(duì)象的函數(shù)稱(chēng)為一等函數(shù)(first-class functions)。具體地說(shuō),就是編程語(yǔ)言支持在程序執(zhí)行過(guò)程中構(gòu)造新的函數(shù),并將它們存儲(chǔ)在數(shù)據(jù)結(jié)構(gòu)中作為其它函數(shù)的參數(shù)的傳入?yún)?shù),并在函數(shù)返回時(shí)將它們作為函數(shù)值返回。本概念并不涵蓋任何語(yǔ)言和程序的外部函數(shù)或者程序,例如通過(guò)調(diào)用編譯器或者一個(gè)eval函數(shù)來(lái)創(chuàng)建新函數(shù)。
這里提供一等函數(shù)的一個(gè)簡(jiǎn)單示例:map或者mapcar函數(shù),它使用一個(gè)函數(shù)和一個(gè)列表作為參數(shù),然后將通過(guò)將函數(shù)應(yīng)用到列表中的每個(gè)成員后形成的列表作為返回值。
“declarative syntax”是什么意思?
與大多數(shù)依靠程序和顯式代碼來(lái)更新在變量或者屬性之間關(guān)系的編程語(yǔ)言不同,聲明式語(yǔ)言允許數(shù)值被聲明為另一種方式。
在JavaFX的一個(gè)示例:
var a : Number = bind model.attrib/2;
無(wú)論何時(shí)model.attrib的數(shù)值發(fā)生改變,a的數(shù)值都將自動(dòng)、透明地更新,更新期間無(wú)需調(diào)用任何程序。這對(duì)于在模式和視圖對(duì)象之間綁定依賴(lài)關(guān)系、控制GUI行為是特別有用的。
“list-comprehensions”是什么意思?
我們常常把“list-comprehensions”翻譯為“列表推導(dǎo)”。列表推導(dǎo)是在語(yǔ)言級(jí)別上支持以多種方式創(chuàng)建、維護(hù)列表的方法。
在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”譯為“基于依賴(lài)關(guān)系的增量式求值”。在JavaFX中,屬性值能夠被聲明為依賴(lài)于(綁定到)包含其它屬性的表達(dá)式。這樣,當(dāng)某個(gè)被引用的屬性數(shù)值發(fā)生變化時(shí),所有依賴(lài)此屬性的屬性都將直接或者間接地改變它們的數(shù)值,此過(guò)程無(wú)需調(diào)用任何的中間程序邏輯。這和在Excel之類(lèi)的電子表格中使用方程式很類(lèi)似。
這對(duì)于那些需要?jiǎng)討B(tài)維護(hù)模式和視圖屬性,而又時(shí)常需要復(fù)雜的程序邏輯的GUI開(kāi)發(fā)來(lái)說(shuō)非常有用。
“操作(operation)” vs “函數(shù)(function)”
函數(shù)與操作之間的不同之處是函數(shù)可以遞增地反復(fù)求值、可以綁定返回值、綁定參數(shù)、綁定變量/屬性,隱性綁定本地變量。
為了進(jìn)一步說(shuō)明,請(qǐng)看下面的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);
我們非常清楚地看到:無(wú)論zing和zap如何變化,snap將不會(huì)發(fā)生變化。而dyn則會(huì)隨著zing和zap的變化而改變。因?yàn)樵趜ing和zap的數(shù)值發(fā)生變化時(shí),發(fā)生了一個(gè)增量式的求值過(guò)程:程序?qū)⒆兓臄?shù)值傳遞給依賴(lài)其的所有函數(shù),并重新計(jì)算數(shù)值。
JavaFX的授權(quán)模式是怎么的?
JavaFX的開(kāi)發(fā)者很贊同讓用戶(hù)發(fā)布自己的應(yīng)用,并堅(jiān)信開(kāi)源和社區(qū)的力量。但當(dāng)前的JavaFX版本是在評(píng)估授權(quán)下發(fā)布的,因此并不能夠被重新發(fā)布。你當(dāng)然能夠發(fā)布自己編寫(xiě)的基于JavaFX的應(yīng)用,但不能夠和JavaFX一起捆綁發(fā)布,并需要告之使用者:需要到openjfx項(xiàng)目站點(diǎn)下載JavaFX二進(jìn)制代碼庫(kù)。并且,由于正處于早期的JavaFX代碼還處在評(píng)估授權(quán)下,因此它不能用于商業(yè)用途。當(dāng)Sun完成了JavaFX的商業(yè)化版本開(kāi)發(fā)后,我相信這將會(huì)得到改變。
Sun是否規(guī)定了發(fā)布JavaFX商業(yè)化產(chǎn)品的時(shí)間線?
很抱歉,目前沒(méi)有準(zhǔn)確的時(shí)間約定,不過(guò)馬上就會(huì)制定出來(lái)。
JavaFX Runtime像JavaFX Script那樣開(kāi)源嗎?
是的,JavaFX Runtime即將開(kāi)放源代碼。
在JavaFX和…之間的不同
與F3比較:F3是Form Follows Function的縮寫(xiě),這是JavaFX平臺(tái)從前的名字。
與Java比較:JavaFX 是一種兼容JSR-223的腳本語(yǔ)言。它能夠使用Java類(lèi),并從Java類(lèi)中被調(diào)用。
與Java 6.0提供的Scriting Engine比較:Java 6.0提供的Scriting Engine為兼容JSR-223的腳本語(yǔ)言提供了運(yùn)行平臺(tái),JavaFX可以在Java 6.0提供的Scriting Engine上執(zhí)行。而JavaFX并不依賴(lài)于Java 6.0,它可以在任何兼容JSR-223的腳本引擎(比如javax.script.ScriptEngine)下執(zhí)行。
與SVG比較:SVG并不是一種程序語(yǔ)言;它是一種數(shù)據(jù)描述語(yǔ)言。其XML語(yǔ)法對(duì)于編程語(yǔ)言來(lái)講是非常可怕的。但SVG的交互性、兼容性是令人滿意的。目前JavaFX開(kāi)發(fā)團(tuán)隊(duì)并沒(méi)有計(jì)劃直接使用SVG。由于SVG和JavaFX都源自舊的PostScript和Java2D向量圖形模式,因此在某種程度上,我們已經(jīng)在JavaFX中使用了SVG,但目前仍然存在某些值得注意的不兼容性。
Chris Oliver 已經(jīng)編寫(xiě)了SVG-to-F3 轉(zhuǎn)換程序。
與Swing比較:JavaFX是一種編寫(xiě)Swing應(yīng)用的新方式,它無(wú)需了解swing框架和java語(yǔ)言。
與JavaScript比較:在JavaFX和JavaScript之間唯一相同點(diǎn)就是它們都是兼容JSR-223的腳本語(yǔ)言。
與Ajax比較:Ajax是使用了JavaScript和異步更新的web瀏覽器端技術(shù)。它與JavaFX的關(guān)系:兩者都是UI相關(guān)的技術(shù)。但它們?cè)谡Z(yǔ)言和環(huán)境上完全不同。
與Savaje OS的關(guān)系:Sun正在計(jì)劃使用它們購(gòu)買(mǎi)的Saveje手機(jī)系統(tǒng)和JVM來(lái)發(fā)布JavaFX Mobile,后者能在移動(dòng)設(shè)備上運(yùn)行JavaFX腳本,它將成為Windows Mobile、Flash Lite的有力競(jìng)爭(zhēng)者。
我能夠使用JavaFX編寫(xiě)Java3D應(yīng)用嗎?它兼容VRML或者X3D標(biāo)準(zhǔn)、Xj3D之類(lèi)的代碼庫(kù)嗎?
沒(méi)有原因不能使用。JavaFX能夠和任何第三方代碼庫(kù)互操作,并且不需要任何特殊語(yǔ)法。目前JavaFX開(kāi)發(fā)團(tuán)隊(duì)正在進(jìn)行開(kāi)發(fā)支持Java3D的功能。
JavaFX是一種RCP(Rich Client Platform) 嗎?
是的。JavaFX不僅能夠用于RCP開(kāi)發(fā),也能夠用于RIA(Rich internet Applications)開(kāi)發(fā)。
我能夠在web應(yīng)用中使用JavaFX嗎?
JavaFX能夠用于編寫(xiě)前端應(yīng)用、web應(yīng)用的視圖或者用戶(hù)接口,不過(guò)這都需要JVM的支持。
JavaFX將代替Java EE中的JSF和JSP嗎?
不,JSF和JSP用于編寫(xiě)純粹的web應(yīng)用(對(duì)于支持HTML的HTTP客戶(hù)端來(lái)講是可用的),而JavaFX需要位于客戶(hù)端的JVM。如果你希望編寫(xiě)富客戶(hù)端的話,那么就需要在客戶(hù)端安裝JRE,JavaFX能夠提供與基于Flash的Flex、基于.net的Silverlight相同的功能。常見(jiàn)的應(yīng)用場(chǎng)景是開(kāi)發(fā)運(yùn)行在公司內(nèi)網(wǎng)的應(yīng)用。
JavaFX在運(yùn)行時(shí)需要服務(wù)器嗎?
JavaFX是一種關(guān)注GUI的腳本語(yǔ)言;它主要用于桌面應(yīng)用,因此不需服務(wù)器。如果你計(jì)劃部署JNLP(Java Web Start)的話,那么你需要一臺(tái)web服務(wù)器。
運(yùn)行JavaFX需要什么條件?
兩種條件任選其一:
Java5以上、一個(gè)兼容JSR-223的實(shí)現(xiàn)、JavaFX代碼庫(kù);
Java6以上、JavaFX代碼庫(kù)。
目前有JavaFX可用的編譯器嗎?
OpenFX Compiler是JavaFX編譯器項(xiàng)目,目前已經(jīng)開(kāi)放源代碼。
詳細(xì)情況請(qǐng)?jiān)L問(wèn):https://openjfx-compiler.dev.java.net/
開(kāi)發(fā)中遇到的問(wèn)題
JavaFX中有哪些固有的數(shù)據(jù)類(lèi)型?
JavaFX中的固有數(shù)據(jù)類(lèi)型:String、Boolean、Number、Integer。
JavaFX與Java類(lèi)型之間的對(duì)應(yīng)關(guān)系:

更多信息請(qǐng)?jiān)L問(wèn):
https://openjfx.dev.java.net/JavaFX_Programming_Language.html#basic_types
如何連接兩個(gè)字符串?“+”操作符已經(jīng)不起作用了!?
與Java有所不同,JavaFX并沒(méi)有重載“+”操作符來(lái)使其用于字符串連接:
import javafx.ui.*;
import javafx.ui.canvas.*;
Frame {
content: Label {
text: "Hello " + "World"
}
visible: true
}
如果嘗試運(yùn)行上面的代碼,我們將看到以下的控制臺(tái)輸出:
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"
實(shí)現(xiàn)方式之一:修改代碼
Java實(shí)現(xiàn)方法:
String s = "Your score is " + n + " out of " + total + ".";
JavaFX的字符串表達(dá)式操作符{}實(shí)現(xiàn)連接字符串的功能:
var s:String = "Your score is {n} out of {total}.";
實(shí)現(xiàn)方式之二:調(diào)用concat()方法
JavaFX提供了concat()方法來(lái)連接兩個(gè)字符串:
import javafx.ui.*;
import javafx.ui.canvas.*;
Frame {
content: Label {
text: "Hello ".concat("World")
}
visible: true
}
如何將字符串轉(zhuǎn)換為數(shù)字?
目前沒(méi)有直接的方式,但可以使用下面的代碼:
var value = new DecimalFormat("0").parse(someString);
如何將TextField的數(shù)值綁定到一個(gè)數(shù)字類(lèi)型屬性?
使用綁定::
var total = 10
TextField {
value: bind total
...
}
也可以使用format進(jìn)行格式化:
value: bind "{total format as <<#,##0>>}"
如何設(shè)置用在Java Web Start上的JavaFX?
JNLP (Java Network Launch Protocol)是一種基于XML的協(xié)議,它能夠在網(wǎng)絡(luò)上部署Java和JavaFX應(yīng)用。
這里提供一個(gè)用于部署JavaFXPad的JNLP示例。
詳細(xì)示例請(qǐng)見(jiàn):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”示例
環(huán)境需求
• Java 5 JDK
• 從openjfx項(xiàng)目下載后獲得的JavaFX代碼包中提取出來(lái)的/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
}
創(chuàng)建 HelloWebStartJFX.jar
jar cvf HelloWebStartJFX.jar HelloWebStart.fx
創(chuàng)建 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>
創(chuàng)建簽名密鑰
keytool -genkey -alias jfx -dname "CN=John Doe, O=JFX Inc." -validity 9999 -keystore jfx.keystore -keypass keyPassword -storepass storePassword
對(duì)jar文件進(jìn)行簽名
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服務(wù)器: 設(shè)置用于.jnlp 的MIME類(lèi)型
Apache服務(wù)器:在http.conf 或者 .htaccess文件中添加類(lèi)型:
application/x-java-jnlp-file JNLP
將文件復(fù)制到Web服務(wù)器
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/
啟動(dòng)Web Start
通過(guò)www.example.com/HelloWebStartJFX/啟動(dòng)web Start。
如何使用“全限定名”引用Java類(lèi)?
全限定Java類(lèi)名必須使用法語(yǔ)引號(hào)<< >>進(jìn)行修飾。
如何訪問(wèn)內(nèi)部類(lèi)和接口?
在訪問(wèn)內(nèi)部類(lèi)和接口時(shí),你只能使用內(nèi)部類(lèi)的編譯名。
例如:
在Java中的import java.util.Map.Entry,在JavaFX中將表示為import java.util.Map$Entry。
在JavaFX中還需要注意的是在引用內(nèi)部類(lèi)時(shí),你需要繼續(xù)使用Outer$Inner 這種形式的語(yǔ)法。為了方便使用,你也可以相應(yīng)地將導(dǎo)入語(yǔ)句修改為:
import java.util.Map$Entry as Entry
這樣就不必重復(fù)地使用Outer$Inner形式了。
我能夠使用Java 5的枚舉(enumerations)嗎?
當(dāng)然可以。你可以采用下面的方式引用它們:
import java.util.management.MemoryType; // 導(dǎo)入枚舉
var value = HEAP:MemoryType; // 使用枚舉值
// HEAP是MemoryType中的枚舉值
var allValues = MemoryType.values(); // 創(chuàng)建包含所有枚舉值的JavaFX數(shù)組
如何在JavaFX中輕松定制Swing組件?
這里提供了一些對(duì)Swing組件進(jìn)行快速封裝的代碼,它能用于JavaFX組件層中:
SwingWidget類(lèi)定義:
文件名: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;
}
用法:
下面提供了一個(gè)使用SwingWidget的簡(jiǎn)單示例。請(qǐng)注意在樹(shù)形列表中提供的數(shù)據(jù)來(lái)自于默認(rèn)的樹(shù)形模型,而不是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"
}
運(yùn)行界面:

為什么我的某些.fx文件不能被JavaFX Pad重新裝載?
非常抱歉地告訴你,JavaFXPad目前的功能非常有限。他并不能檢測(cè)到外部文件的改變。為了讓它能夠“看到”你的修改,你需要以手工的方式在JavaFXPad中重新打開(kāi)修改后的文件。
如何引用其它JavaFX文件?
JavaFX能夠從以下三種資源中引用靜態(tài)值、變量和類(lèi):
1.在同一文件內(nèi)
2.在相同的目錄/包路徑下的文件
3.在其它的包路徑下的文件
首先,第一種方式非常簡(jiǎn)單。如果你正在引用處于相同文件中的類(lèi),那么你只需要使用類(lèi)名即可(類(lèi)可以被定義在引用之前或者之后)。而變量則要在它們被聲明之后才能被引用。
對(duì)于第二種方式,顯而易見(jiàn),你無(wú)須對(duì)處于相同包路徑下的每個(gè).fx文件都使用import語(yǔ)句,而只要提供具有它們所在的同一包路徑的import語(yǔ)句即可。
如果你有其它的內(nèi)部類(lèi)或者你需要從不同的包路徑下引入類(lèi),那么就需要使用import語(yǔ)句完成一點(diǎn)額外工作:使用import語(yǔ)句將.fx文件導(dǎo)入,而不是在此文件中的某個(gè)特定的類(lèi)。例如,如果MediaTable.fx包含兩個(gè)類(lèi):MediaTableColumn和MediaTableRow,那么你只需要importing MediaTable這一條語(yǔ)句就可以導(dǎo)入這兩個(gè)類(lèi)。
你也可以像使用Java一樣使用 import *語(yǔ)句。但由于這種方式降低了代碼的可讀性,所以并不推薦給大家。
JavaFX腳本提供類(lèi)似 __LINE__這樣的魔術(shù)常量(magic constants)嗎?
魔術(shù)常量
• __DIR__ -- 返回包含當(dāng)前FX源文件的目錄的URL。如果當(dāng)前文件是從jar文件裝載的,那么返回值可能是jar文件的URL。
• __FILE__ -- 返回當(dāng)前源文件的URL。
• __LINE__ -- 返回當(dāng)前源文件中的當(dāng)前行。
• __ARCHIVE__ -- 返回包含當(dāng)前文件的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編寫(xiě)的"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 (請(qǐng)注意不是throws)
trigger
true
try
typeof
unitinterval
valueof
var
where
while
xor
posted on 2007-09-29 10:57 junky 閱讀(916) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): java