本文來自我在javaeye的翻譯文章http://somefuture.iteye.com/blog/1190880
如果想用 JavaFX快速開發富用戶體驗的應用,就好好讀本文吧。我們將創建一個簡單應用並從中瞭解到用少量代碼實現複雜圖形效果是多麼容易。當然了,JavaFX不僅僅只是異常漂亮生動的形狀而已。讀完本文後去看看樣例將大有好處。
如果你很熟悉JavaFX場景圖形編程模型,那就很容易理解程序的代碼。 舞臺( stage)是應用的最高層容器,場景( scene)是應用中內容的繪圖表面。內容都被組織爲場景圖形,是一顆節點的層次樹。
Figure 2 爲應用ColorfulCircles展示了場景圖形。
分支節點是
Group
類的實例化。非分支節點,即葉子節點,是 Rectangle
和Circle
類的實例化。
建立應用
你可以使用任何爲開發Java設計的工具來構建javaFX應用。我們推薦使用NetBeans IDE。 開始之前,請確保你的NB版本已經支持了javaFX2.0。詳見System Requirements。
安裝如下步驟用NB做開發:
-
從 File菜單 , 選擇New Project.
-
從JavaFX application 分類中, 選擇JavaFX Application , 點擊Next.
-
輸入工程名
ColorfulCircles
後點 Finish. -
打開 ColorfulCircles.java 文件,複製 import 聲明粘貼進你的工程覆蓋NB自動生成的語句。
-
或者你可以使用NB的代碼完成功能或Fix Imports 命令導入Import語句,不過記得確保包都以javafx開頭。
創建應用基礎
刪除 NetBeans IDE生成的ColorfulCircles 類並用 Example 1中的代碼代替。以下是運行javaFX應用所需的最少代碼:
Example 1 Basic Application
public class ColorfulCircles extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.show(); } }
ColorfulCircles類繼承了 Application
類,包含兩個方法。第一個方法是 main()
方法, 用來調用launch()
方法。作爲JavaFX最佳實踐,launch()
方法是被
main()
方法調用的唯一方法。
然後, ColorfulCircles
類重寫了抽象的 start()
方法。start()
方法的參數是應用的初始舞臺。最後一行使得舞臺可見。
現在你可以編譯運行ColorfulCircles了,每一步都記得查看下中間結果。如果出問題了,查看下 ColorfulCircles.java文件。
添加場景
現在爲舞臺添加場景:增加三行代碼,參見Example 2。這有兩個最佳實踐: 代碼中爲場景創建了一個Group節點做根節點,並設置了場景的寬和高(這裏是800和600)。
在 primaryStage.show()
這一行之前添加場景及其所有內容。這是另一個最佳實踐。
Example 2 Scene
@Override public void start(Stage primarystage) { Group root = new Group(); Scene scene = new Scene(root, 800, 600, Color.BLACK); primaryStage.setScene(scene); primaryStage.show()
Figure 3 展示了到目前爲止的結果。
添加圖形
接下來在 primaryStage.show()行之前添加
Example 3中的代碼來創建30個圓。
Example 3 30 Circles
Group circles = new Group(); for (int i = 0; i < 30; i++) { Circle circle = new Circle(150, Color.web("white", 0.05)); circle.setStrokeType(StrokeType.OUTSIDE); circle.setStroke(Color.web("white", 0.16)); circle.setStrokeWidth(4); circles.getChildren().add(circle); } root.getChildren().add(circles);
這些代碼創建了稱爲 circles
的Group,然後使用一個ofr循環向其中添加30個圓。每個圓半徑到是150,並用white顏色填充,此外不透明度是5%,所以基本是透明的。
然後爲這些圓創建邊框,代碼中包含了 StrokeType
類。 描邊類型的 OUTSIDE 標明圓的邊界向外擴展
StrokeWidth
的值,也就是4。描邊的顏色是
white
,不透明度是16%,使得它比圓的顏色淺。
最後一行把 circles
加到根節點上。這只是臨時結構,稍候將修改場景圖形使得它匹配
Figure 2展示那樣。
Figure 4展示了當前應用。由於代碼沒有爲每個圓指定特定位置,它們都疊加在一起,並且窗口的左上角是圓心。層疊的圓的不透明度和黑色北京作用使得圓看起來是灰色的。
增加視覺效果
繼續爲圓應用盒子模糊效果使得它們看起來柔和。代碼是
Example 4 。 在primaryStage.show()
之前添加這些代碼。
代碼設置了模糊半徑,寬和高都是10並且迭代3次,使它接近高斯模糊。
這樣便在圓的邊緣出現了平滑效果,看Figure 5.
創建背景漸變
現在創建一個矩形並用線性漸變填充,代碼見 Example 5.
在 root.getChildren().add(circles)
之前添加這些代碼,這樣矩形才能在圓下面。
Example 5 Linear Gradient
Rectangle colors = new Rectangle(scene.getWidth(), scene.getHeight(), 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")),})); root.getChildren().add(colors);
代碼創建了稱爲colors的矩形。
矩形和場景同寬高,並從左下角的(0,0)點開始到右上角的(1,1)點應用線性漸變。
true
表示漸變在矩形中是成比例的,NO_CYCLE
表示顏色循環不會重複, Stop[]
序列表明瞭漸變顏色序列。最後一行把colors
添加到根節點。
現在邊緣模糊的灰色圓出現在了彩虹色的上面,見 Figure 6.
Figure 7 展示了中間的場景圖。現在circles
組和colors
矩形都是根節點的孩子。
應用混合模式
現在通過增加混合覆蓋效果給圓增加顏色並使場景變暗。這個任務需要一點家務活,你需要從場景中移除 circles組和漸變的矩形,並把它們添加到新的混合覆蓋組中。
-
刪除下面兩行代碼:
root.getChildren().add(colors);
root.getChildren().add(circles);
- 添加 Example 6 中的代碼到上面刪除代碼的位置。
Example 6 Blend Mode
Group blendModeGroup = new Group(new Group(new Rectangle(scene.getWidth(), scene.getHeight(), Color.BLACK), circles), colors); colors.setBlendMode(BlendMode.OVERLAY); root.getChildren().add(blendModeGroup);
blendModeGroup
組爲混合覆蓋組建立了結構。組中包含了兩個孩子。第一個是一個新建匿名Group
,包含一個新建的匿名黑色矩形和以前創建的circles
組。第二個孩子是以前創建的colors
矩形。 -
setBlendMode()
方法把混合覆蓋應用到了colors 矩形。最後一行代碼把blendModeGroup
添加到場景作爲根節點的孩子,如Figure 2.
混合覆蓋效果是圖形設計程序中的常規效果。它可以暗化圖像或高亮它們,這取決於混合組中的顏色。這裏,我們把線性漸變矩形用作覆蓋,黑色矩形用來保持背景黑暗,而接近透明的圓從矩形中取了色不過依然變暗了。
Figure 8 展示了結果。下一步活化了圓之後將能看到完整的混合覆蓋效果。
添加動畫
最後一步是使用javaFX動畫來移動圓:
-
如果沒準備好,增加
import static java.lang.Math.random;
到導入聲明。 -
在
primaryStage.show()
之前增加Example 7中的活化代碼。Example 7 Animation
Timeline timeline = new Timeline(); for (Node circle: circles.getChildren()) { timeline.getKeyFrames().addAll( new KeyFrame(Duration.ZERO, // set start position at 0 new KeyValue(circle.translateXProperty(), random() * 800), new KeyValue(circle.translateYProperty(), random() * 600) ), new KeyFrame(new Duration(40000), // set end position at 40s new KeyValue(circle.translateXProperty(), random() * 800), new KeyValue(circle.translateYProperty(), random() * 600) ) ); } // play 40s of animation timeline.play();
動畫是由時間線驅動的,所以這裏創建了時間線,然後使用一個
for
循環爲30個圓增加兩個關鍵幀。第一個關鍵幀在0秒時使用translateXProperty
和translateYProperty
屬性設置窗口內的一個隨機位置。第二個關鍵幀在40秒時同樣做。這樣,當時間線play()後,所有圓就在40秒內從一個隨機位置到另一個。
Figure 9展示了運動中的30個圓。完成後查看ColorfulCircles.java文件 .
Figure 9 Animated Circles
Description of "Figure 9 Animated Circles"