Hello JavaFX! Part 3 by Michael | CodeData
top

Hello JavaFX! Part 3

分享:

Hello JavaFX! Part 2 << 前情

開發Java桌面應用程式,繪圖和動畫效果好像都跟它沒有關係,開發人員的重點通常會在應用程式後端的技術,畫面只不過是讓使用者輸入一些資料後按個按鈕,讓應用程式後端的元件正確而且有效率的儲存或查詢資料。如果大家對桌面應用程式的想法都是這樣的話,那繪圖和動畫效果還真的是浪費時間而且完全沒必要的東西。

不過現在的使用者好像不會這麼想了,他們要求的應用程式功能,當然一個都不能少,執行的效率也要好,正確性更是必要的。除了這些,他們還會提出更過份的要求,就是希望畫面可以好看一些,操作應用程式的時候,如果可以有一些特殊效果,就更好了。

在應用程式執行刪除資料的時候,讓這個資料在畫面上飛到垃圾桶…這個想法可能會讓很多人覺得非常詭異。就算不覺得應該在應用程式中加入這些垃圾效果,一些像是相簿或音樂播放程式,尤其是遊戲,繪圖與動畫效果就一定要了。開發人員想要設計這類應用程式,通常不會想到Java技術,這也是應該的,它真的不太合適。

現在已經包含在Java SE中的JavaFX 2,應該可以改變大家對Java桌面應用程式的想法,開發人員可以用它建立功能強大的商業應用程式,它在2D與3D繪圖和動畫效果支援,不論是實作的方式或執行的效率,都讓人非常滿意,在認識JavaFX的最後一個部份,就來看看它在繪圖和動畫效的基本作法。在瞭解JavaFX應用程式的基本設計以後,最後再說明如何將應用程式發佈給使用者。

My Circles

這個JavaFX應用程式會帶著你認識基本的繪圖與動畫效果,最後完成的應用程式在執行後會像這樣:

NetBeans中建立一個JavaFX應用程式,名稱可以取為「MyCircles」,把主程式「MyCircles.java」的「start」方法改成下面的樣子:

Group root = new Group();
Scene scene = new Scene(root, 600, 480, Color.BLACK);
primaryStage.setScene(scene);

Rectangle colors = new Rectangle(scene.getWidth(), scene.getHeight(), null);
root.getChildren().add(colors);
primaryStage.show();

執行這個程式以後,會出現一個600X480的視窗,視窗裡面雖然放了一個矩形的Retangle物件,不過現在的畫面會是一片漆黑。JavaFx內建許多繪圖效果的API,在繪製圖形的時候可以指定它們基本的顏色和繪圖效果。在建立Retangle物件之前先建立好一個線性漸層效果的LinearGradient物件,再把它指定給Retangle建構子的最後一個參數:

LinearGradient linearGradient = new LinearGradient(
0f, 1f, 1f, 0f, true, CycleMethod.NO_CYCLE, new Stop[]{
new Stop(0, Color.web("#f8bd55")),
new Stop(0.14, Color.web("#c0fe56")),
new Stop(0.28, Color.web("#5dfbc1")),
new Stop(0.43, Color.web("#64c2f8")),
new Stop(0.57, Color.web("#be4af7")),
new Stop(0.71, Color.web("#ed5fc2")),
new Stop(0.85, Color.web("#ef504c")),
new Stop(1, Color.web("#f2660f")),});

Rectangle colors = new Rectangle(scene.getWidth(), scene.getHeight(), linearGradient);

再執行應用程式,就可以在視窗中看到線性漸層效果。不過現在加入視窗中的矩形有一個很大的問題,雖然在建立的時候,指定它的大小為視窗的寬與高,如果使用者調整視窗大小的話,就會變成這樣了:

hello-javafx-part-3-1  hello-javafx-part-3-2

如果希望視窗中的矩形,可以隨著使用調整視窗的大小自動設定的話,一般的作法都會是使用視窗事件來控制。不過JavaFX技術中有一個很重要而且很方便的作法,採用Peoperty和Binding的設定,讓矩形的寬與高自動連結到視窗的寬與高,這樣就方便多了。在建立好Rectangle物件後,加入連結寬與高的程式碼:

colors.widthProperty().bind(scene.widthProperty());
colors.heightProperty().bind(scene.heightProperty());

執行應用程式並調整視窗的大小,矩形已經可以跟著視窗自動調整寬與高了。

Circles

接下來在畫面中加入一些圓環的圖形,而且一次要加入很多個。在JavaFX需要把多個圖形組合起來管理,可以使用「Group」物件,建立好群組務件後,加入30個使用「Circle」類別繪製的圓形。需要設定圖形模糊的效果也很容易在「javafx.scene.effect」套件下有許多用來設定圖形效果的API,這裡使用的是「BoxBlur」它會讓圖形的邊緣產生模糊的效果。在「primaryStage.show();」敘述前加入下面的程式:

Group circles = new Group();

for (int i = 0; i < 30; i++) {
    Circle circle = new Circle(50, Color.web("white", 0.05));
    circle.setStrokeType(StrokeType.OUTSIDE);
    circle.setStroke(Color.web("white", 0.16));
    circle.setStrokeWidth(16);
    circles.getChildren().add(circle);
}

circles.setEffect(new BoxBlur(10, 10, 3));
root.getChildren().add(circles);

執行程式以後,在視窗的左上角會出現一個四分之一的白色圓環,目前沒有設定這些圓環的位置,所以它們全部都重疊在一起。畫面會像這樣:

hello-javafx-part-3-3

這個範例主要的元件都已經加入了,所以可以看看現在視窗中的元件架構:

hello-javafx-part-3-4

Blend Mode

目前顯示在視窗中的樣子,跟一開始讓你看到的結果還是很不一樣,還差一個混合模式的繪圖效果。加入視窗中的矩形使用線性漸層的繪圖效果,希望可以把它隱藏起來,把它當成底層的顏色,只有在圓環出現的地方,才會顯示線性漸層的顏色。要完成這樣的需求,可以把這兩個群組結合成一個群組,並且把矩形的結合效果設定為圖層。原來的作法是分別加入矩形和圓環群組到畫面中,所以要先找到這兩行敘述並刪除它們:

root.getChildren().add(colors);
root.getChildren().add(circles);

接下來在「primaryStage.show();」敘述前加入下面的程式:

// 把圓環群組跟一個黑色的矩形包裝為一個群組
Group circlesGroup = new Group(
    new Rectangle(scene.getWidth(), scene.getHeight(), Color.BLACK),
    circles);
// 再把上面的群組跟原來使用線性漸層效果的矩形包裝為一個群組
Group blendModeGroup = new Group(circlesGroup, colors);
// 設定使用線性漸層效果的矩形為圖層混合模式
colors.setBlendMode(BlendMode.OVERLAY);
root.getChildren().add(blendModeGroup);

執行程式,比較處理前跟處理後的樣子:

hello-javafx-part-3-5  hello-javafx-part-3-6

Time Line

最後要讓這些圓環可以在畫面上動起來,你一定想到執行緒了。執行緒是Java技術中大家最喜歡挑戰的主題了,它很簡單,只有Runnable和Thread兩個;也非常的麻煩,因為真的用了它們以後,一些很奇怪的事情都會出現了。JavaFX API對開發人員還是不錯的,簡化執行緒的作法對動畫效果的製作會有很大的幫助。TimeLine是JavaFX用來代替執行緒的其中一個API,它是一個應用程式中獨立執行的工作。建立好需要的TimeLine物件,為它加入需要的KeyFrame,每一個KeyFrame都可以指定一個執行動畫效果的工作,最後再播放它就可以了。

先看看使用TimeLine讓一個圓環動起來的作法,在「primaryStage.show();」敘述前加入下面的程式:

Timeline timeline = new Timeline();
Node circle = circles.getChildren().get(0);
timeline.getKeyFrames().addAll(
    new KeyFrame(new Duration(5000),
        new KeyValue(circle.translateXProperty(), 600),
        new KeyValue(circle.translateYProperty(), 0)),
        new KeyFrame(new Duration(10000),
        new KeyValue(circle.translateXProperty(), 0),
        new KeyValue(circle.translateYProperty(), 480)
    )
);
timeline.play();

這段程式碼加入兩個KeyFrame,讓第一個圓環在畫面上移動,執行後的結果會像這樣:

http://youtu.be/YuEqS0NM4aU

瞭解這段程式碼的效果以後,把它們移除掉。接下來讓所有的圓環使用亂數的設定,讓它們在畫面中一起移動。在「primaryStage.show();」敘述前加入下面的程式:

Timeline timeline = new Timeline();

for (Node circle : circles.getChildren()) {
    timeline.getKeyFrames().addAll(
        new KeyFrame(Duration.ZERO,
            new KeyValue(circle.translateXProperty(), Math.random() * 600),
            new KeyValue(circle.translateYProperty(), Math.random() * 480)),
            new KeyFrame(new Duration(20000),
            new KeyValue(circle.translateXProperty(), Math.random() * 600),
            new KeyValue(circle.translateYProperty(), Math.random() * 480)
        )
    );
}

timeline.play();

發佈JavaFX應用程式

想要把寫好的JavaFX應用程式發佈給使用者,目前在NetBeans開發工具中是比較方便的。在NetBeans中建置好一個JavaFX專案後,在「Files」標籤下專案的「dist」目錄中,就包裝好一個可以單獨執行的JAR檔;另外也有一個JNLP檔案,它是一個在網路環境中執行的設定檔,可以讓JavaFX應用程式在Java Web Start或瀏覽器中執行。還有一個HTML檔案,用來啟動Java Web Start和在瀏覽器中執行JavaFx應用程式的樣版,你可以參考它使用在自己的網頁中。

在NetBeans開發環境中,如果沒有特別設定的話,執行JavaFX應用程式都是獨立應用程式的方式。你可以在專案目錄上按滑鼠右鍵,選擇「Properties」,選擇「Run」目錄,在這個設定視窗中,你可以選擇執行JavaFX應用程式的方式。如果選擇在瀏覽器或Java Web Start中執行,也可以設定應用程式的寬度與高度。設定完成候,最好在專案目錄上按滑鼠右鍵後選擇「Clear and Build」,就可以使用新的設定執行JavaFX應用程式了。

資料來源與參考資訊

後續 >> JavaFX Layout Part 1

分享:
按讚!加入 CodeData Facebook 粉絲群

相關文章

留言

留言請先。還沒帳號註冊也可以使用FacebookGoogle+登錄留言

牧野洛05/11

請問 在"這段程式碼加入兩個KeyFrame,讓第一個圓環在畫面上移動,執行後的結果會像這樣:"之後是不是忘記附圖了?

關於作者

張益裕。目前的工作是講師與作者,專長是教育訓練課程規劃、教材編製與課程推廣,技術書籍與專欄寫作。涵蓋的領域有OOAD、Java程式設計、JavaFX、Java Embedded、Android與SQL。已出版電子書Google Play圖書Pubu

熱門論壇文章

熱門技術文章