JavaFX應用問題解答

來源:互聯網
上載者:User
常見問題

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
並不是一種程式語言;它是一種資料描述語言 (Data Description Language)。其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能夠和任何第三方程式碼程式庫互操作,並且不需要任何特殊文法。目前JavaFXTeam Dev進行中開發支援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+" 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 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

轉自:http://www.matrix.org.cn/resource/article/2007-09-24/e50bf5af-6a56-11dc-91f8-0da64dffe568.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.