天天看點

JavaFX應用問題解答

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的一個示例:

無論何時model.attrib的數值發生改變,a的數值都将自動、透明地更新,更新期間無需調用任何程式。這對于在模式和視圖對象之間綁定依賴關系、控制GUI行為是特别有用的。

“list-comprehensions”是什麼意思?

我們常常把“list-comprehensions”翻譯為“清單推導”。清單推導是在語言級别上支援以多種方式建立、維護清單的方法。

在JavaFX中的一些示例:

什麼是"incremental dependency-based evaluation"?

“incremental dependency-based evaluation”譯為“基于依賴關系的增量式求值”。在JavaFX中,屬性值能夠被聲明為依賴于(綁定到)包含其它屬性的表達式。這樣,當某個被引用的屬性數值發生變化時,所有依賴此屬性的屬性都将直接或者間接地改變它們的數值,此過程無需調用任何的中間程式邏輯。這和在Excel之類的電子表格中使用方程式很類似。

這對于那些需要動态維護模式和視圖屬性,而又時常需要複雜的程式邏輯的GUI開發來說非常有用。

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

函數與操作之間的不同之處是函數可以遞增地反複求值、可以綁定傳回值、綁定參數、綁定變量/屬性,隐性綁定本地變量。

為了進一步說明,請看下面的JavaFX代碼片段:

我們非常清楚地看到:無論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,但目前仍然存在某些值得注意的不相容性。

與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編譯器項目,目前已經開放源代碼。

開發中遇到的問題

JavaFX中有哪些固有的資料類型?

JavaFX中的固有資料類型:String、Boolean、Number、Integer。

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

更多資訊請通路:

<a href="https://openjfx.dev.java.net/JavaFX_Programming_Language.html#basic_types%20">https://openjfx.dev.java.net/JavaFX_Programming_Language.html#basic_types</a>

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

與Java有所不同,JavaFX并沒有重載“+”操作符來使其用于字元串連接配接:

如果嘗試運作上面的代碼,我們将看到以下的控制台輸出:

實作方式之一:修改代碼

Java實作方法:

JavaFX的字元串表達式操作符{}實作連接配接字元串的功能:

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

JavaFX提供了concat()方法來連接配接兩個字元串:

如何将字元串轉換為數字?

目前沒有直接的方式,但可以使用下面的代碼:

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

使用綁定::

也可以使用format進行格式化:

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

JNLP (Java Network Launch Protocol)是一種基于XML的協定,它能夠在網絡上部署Java和JavaFX應用。

這裡提供一個用于部署JavaFXPad的JNLP示例。

“Hello Web Start FX”示例

環境需求

        • Java 5 JDK

        • 從openjfx項目下載下傳後獲得的JavaFX代碼包中提取出來的/lib/javafxrt.jar and lib/swing-layout.jar

“Hello Web Start JFX”程式代碼

檔案名: HelloWebStart.fx

建立 HelloWebStartJFX.jar

建立 HelloWebStartJFX.jnlp

檔案名: HelloWebStartJFX.jnlp

建立簽名密鑰

對jar檔案進行簽名

連接配接到HelloWebStartJFX.jnlp

檔案名: index.html

Web伺服器: 設定用于.jnlp 的MIME類型

Apache伺服器:在http.conf 或者 .htaccess檔案中添加類型:

将檔案複制到Web伺服器

啟動Web Start

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

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

全限定Java類名必須使用法語引号&lt;&lt; &gt;&gt;進行修飾。

如何通路内部類和接口?

在通路内部類和接口時,你隻能使用内部類的編譯名。

例如:

在Java中的import java.util.Map.Entry,在JavaFX中将表示為import java.util.Map$Entry。

在JavaFX中還需要注意的是在引用内部類時,你需要繼續使用Outer$Inner 這種形式的文法。為了友善使用,你也可以相應地将導入語句修改為:

這樣就不必重複地使用Outer$Inner形式了。

我能夠使用Java 5的枚舉(enumerations)嗎?

當然可以。你可以采用下面的方式引用它們:

如何在JavaFX中輕松定制Swing元件?

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

SwingWidget類定義:

檔案名:SwingWidget.fx

用法:

下面提供了一個使用SwingWidget的簡單示例。請注意在樹形清單中提供的資料來自于預設的樹形模型,而不是JavaFX所特有的。

檔案名:WidgetTest.fx

運作界面:

JavaFX應用問題解答

為什麼我的某些.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。

示例

更多資訊

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