原文: http://zetcode.com/gui/javafx/effects/

JavaFX 包含javafx.scene.effect包,该包具有执行各种视觉效果的一组或类。 在本章中,我们创建DropShadowReflectionLightingGaussianBlurSepiaTonePerspectiveTransform效果。 我们还将展示如何组合多种效果。

通过setEffect()方法将效果应用于节点的effectProperty

阴影

DropShadow是一种高级效果,可使用指定的颜色,半径和偏移量在内容后面渲染阴影。

DropShadowEx.java

  1. package com.zetcod;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.effect.DropShadow;
  5. import javafx.scene.layout.StackPane;
  6. import javafx.scene.paint.Color;
  7. import javafx.scene.shape.Rectangle;
  8. import javafx.stage.Stage;
  9. /**
  10. * ZetCode JavaFX tutorial
  11. *
  12. * This program applies a DropShadow effect
  13. * on a Rectangle.
  14. *
  15. * Author: Jan Bodnar
  16. * Website: zetcode.com
  17. * Last modified: June 2015
  18. */
  19. public class DropShadowEx extends Application {
  20. @Override
  21. public void start(Stage stage) {
  22. initUI(stage);
  23. }
  24. private void initUI(Stage stage) {
  25. StackPane root = new StackPane();
  26. Rectangle rect = new Rectangle(0, 0, 100, 100);
  27. rect.setFill(Color.GREENYELLOW);
  28. DropShadow ds = new DropShadow(15, Color.DARKGREEN);
  29. rect.setEffect(ds);
  30. root.getChildren().add(rect);
  31. Scene scene = new Scene(root, 250, 200, Color.WHITESMOKE);
  32. stage.setTitle("DropShadow");
  33. stage.setScene(scene);
  34. stage.show();
  35. }
  36. public static void main(String[] args) {
  37. launch(args);
  38. }
  39. }

该示例在矩形周围创建阴影。

  1. Rectangle rect = new Rectangle(0, 0, 100, 100);
  2. rect.setFill(Color.GREENYELLOW);

构造一个绿色黄色矩形。

  1. DropShadow ds = new DropShadow(15, Color.DARKGREEN);

创建DropShadow效果。 构造器接受半径和颜色。

  1. rect.setEffect(ds);

通过setEffect()方法应用效果。

JavaFX 效果 - 图1

图:DropShadow

反射

Reflection是一种将输入的反射版本呈现在实际输入内容之下的效果。

ReflectionEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.effect.Reflection;
  5. import javafx.scene.layout.StackPane;
  6. import javafx.scene.paint.Color;
  7. import javafx.scene.text.Font;
  8. import javafx.scene.text.FontWeight;
  9. import javafx.scene.text.Text;
  10. import javafx.stage.Stage;
  11. /**
  12. * ZetCode JavaFX tutorial
  13. *
  14. * This program applies a Reflection effect
  15. * on a Text node.
  16. *
  17. * Author: Jan Bodnar
  18. * Website: zetcode.com
  19. * Last modified: June 2015
  20. */
  21. public class ReflectionEx extends Application {
  22. @Override
  23. public void start(Stage stage) {
  24. initUI(stage);
  25. }
  26. private void initUI(Stage stage) {
  27. StackPane root = new StackPane();
  28. Text text = new Text();
  29. text.setText("ZetCode");
  30. text.setFill(Color.STEELBLUE);
  31. text.setFont(Font.font("Serif", FontWeight.BOLD, 60));
  32. Reflection ref = new Reflection();
  33. text.setEffect(ref);
  34. root.getChildren().add(text);
  35. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  36. stage.setTitle("Reflection");
  37. stage.setScene(scene);
  38. stage.show();
  39. }
  40. public static void main(String[] args) {
  41. launch(args);
  42. }
  43. }

本示例在Text节点上应用Reflection效果。

  1. Text text = new Text();
  2. text.setText("ZetCode");
  3. text.setFill(Color.STEELBLUE);
  4. text.setFont(Font.font("Serif", FontWeight.BOLD, 60));

创建一个Text控件。 它的油漆是STEELBLUE。 字体变为粗体和放大。

  1. Reflection ref = new Reflection();
  2. text.setEffect(ref);

将创建默认的Reflection并将其应用于文本控件。

JavaFX 效果 - 图2

图:反射

灯光

Lighting模拟照在给定内容上的光源,该光源可用于为平面对象提供更逼真的三维外观。 Light源的setAzimuth()方法设置方位角-光源的方向角。

LightingEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.beans.property.DoubleProperty;
  4. import javafx.beans.property.SimpleDoubleProperty;
  5. import javafx.geometry.Insets;
  6. import javafx.scene.Scene;
  7. import javafx.scene.control.Slider;
  8. import javafx.scene.effect.Light;
  9. import javafx.scene.effect.Lighting;
  10. import javafx.scene.layout.VBox;
  11. import javafx.scene.paint.Color;
  12. import javafx.scene.text.Font;
  13. import javafx.scene.text.FontWeight;
  14. import javafx.scene.text.Text;
  15. import javafx.stage.Stage;
  16. /**
  17. * ZetCode JavaFX tutorial
  18. *
  19. * This program applies a Lighting effect on
  20. * a Text control. The azimuth of the light is
  21. * controlled by a Slider.
  22. *
  23. * Author: Jan Bodnar
  24. * Website: zetcode.com
  25. * Last modified: June 2015
  26. */
  27. public class LightingEx extends Application {
  28. @Override
  29. public void start(Stage stage) {
  30. initUI(stage);
  31. }
  32. private void initUI(Stage stage) {
  33. VBox root = new VBox(30);
  34. root.setPadding(new Insets(10));
  35. DoubleProperty azimuth = new SimpleDoubleProperty(0);
  36. Light.Distant light = new Light.Distant();
  37. light.setAzimuth(0);
  38. Lighting lighting = new Lighting(light);
  39. lighting.setSurfaceScale(5.0);
  40. Text text = new Text();
  41. text.setText("ZetCode");
  42. text.setFill(Color.LIGHTSKYBLUE);
  43. text.setFont(Font.font(null, FontWeight.BOLD, 60));
  44. Slider slider = new Slider(1, 360, 0);
  45. azimuth.bind(slider.valueProperty());
  46. slider.valueProperty().addListener(event -> {
  47. light.setAzimuth(azimuth.get());
  48. lighting.setLight(light);
  49. text.setEffect(lighting);
  50. });
  51. text.setEffect(lighting);
  52. root.getChildren().addAll(slider, text);
  53. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  54. stage.setTitle("Lighting");
  55. stage.setScene(scene);
  56. stage.show();
  57. }
  58. public static void main(String[] args) {
  59. launch(args);
  60. }
  61. }

本示例对Text控件应用Lighting效果。 光的方位角由Slider控制。

  1. Light.Distant light = new Light.Distant();
  2. light.setAzimuth(0);

创建一个Light源。

  1. Lighting lighting = new Lighting(light);

该行使用指定的光源创建Lighting的新实例。

  1. Text text = new Text();
  2. text.setText("ZetCode");
  3. text.setFill(Color.LIGHTSKYBLUE);
  4. text.setFont(Font.font(null, FontWeight.BOLD, 60));

这是在其上设置了Lighting效果的Text控件。

  1. Slider slider = new Slider(1, 360, 0);
  2. azimuth.bind(slider.valueProperty());
  3. slider.valueProperty().addListener(event -> {
  4. light.setAzimuth(azimuth.get());
  5. lighting.setLight(light);
  6. text.setEffect(lighting);
  7. });

Slider控件管理光源的方位角。

JavaFX 效果 - 图3

图:Lighting

高斯模糊

GaussianBlur是使用具有可配置半径的高斯卷积核的模糊效果。

GaussianBlurEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import static javafx.application.Application.launch;
  4. import javafx.beans.property.DoubleProperty;
  5. import javafx.beans.property.SimpleDoubleProperty;
  6. import javafx.geometry.Insets;
  7. import javafx.scene.Scene;
  8. import javafx.scene.control.Slider;
  9. import javafx.scene.effect.GaussianBlur;
  10. import javafx.scene.layout.VBox;
  11. import javafx.scene.paint.Color;
  12. import javafx.scene.text.Font;
  13. import javafx.scene.text.Text;
  14. import javafx.stage.Stage;
  15. /**
  16. * ZetCode JavaFX tutorial
  17. *
  18. * This program applies a GaussianBlur effect on
  19. * a Text control. The radius of the blur is
  20. * controlled by a Slider.
  21. *
  22. * Author: Jan Bodnar
  23. * Website: zetcode.com
  24. * Last modified: June 2015
  25. */
  26. public class GaussianBlurEx extends Application {
  27. @Override
  28. public void start(Stage stage) {
  29. initUI(stage);
  30. }
  31. private void initUI(Stage stage) {
  32. VBox root = new VBox(30);
  33. root.setPadding(new Insets(10));
  34. DoubleProperty radius = new SimpleDoubleProperty(0);
  35. Text blurredText = new Text("Inception");
  36. blurredText.setFont(Font.font(38));
  37. Slider slider = new Slider(1, 20, 1);
  38. radius.bind(slider.valueProperty());
  39. slider.valueProperty().addListener(event -> {
  40. blurredText.setEffect(new GaussianBlur(radius.get()));
  41. });
  42. root.getChildren().addAll(slider, blurredText);
  43. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  44. stage.setTitle("Blur effect");
  45. stage.setScene(scene);
  46. stage.show();
  47. }
  48. public static void main(String[] args) {
  49. launch(args);
  50. }
  51. }

本示例对Text控件应用GaussianBlur效果。 模糊的半径由Slider控制。

  1. Text blurredText = new Text("Inception");
  2. blurredText.setFont(Font.font(38));

模糊效果将应用于此文本控件。

  1. Slider slider = new Slider(1, 20, 1);
  2. radius.bind(slider.valueProperty());
  3. slider.valueProperty().addListener(event -> {
  4. blurredText.setEffect(new GaussianBlur(radius.get()));
  5. });

Slider控件管理GaussianBlur效果的radius属性。

JavaFX 效果 - 图4

图:GaussianBlur

棕褐色调

SepiaTone是产生棕褐色调效果的滤镜,类似于古董照片。

SepiaToneEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.beans.binding.Bindings;
  4. import javafx.scene.CacheHint;
  5. import javafx.scene.Scene;
  6. import javafx.scene.effect.ColorAdjust;
  7. import javafx.scene.effect.Effect;
  8. import javafx.scene.effect.SepiaTone;
  9. import javafx.scene.image.Image;
  10. import javafx.scene.image.ImageView;
  11. import javafx.scene.layout.StackPane;
  12. import javafx.scene.paint.Color;
  13. import javafx.stage.Stage;
  14. /**
  15. * ZetCode JavaFX tutorial
  16. *
  17. * This program applies a SepiaTone effect
  18. * on an Image when a mouse pointer is over
  19. * the image.
  20. *
  21. * Author: Jan Bodnar
  22. * Website: zetcode.com
  23. * Last modified: June 2015
  24. */
  25. public class SepiaToneEx extends Application {
  26. @Override
  27. public void start(Stage stage) {
  28. initUI(stage);
  29. }
  30. private void initUI(Stage stage) {
  31. StackPane root = new StackPane();
  32. Image image = new Image("file:mushroom.png");
  33. ImageView iw = new ImageView(image);
  34. SepiaTone sepia = new SepiaTone();
  35. iw.effectProperty().bind(
  36. Bindings
  37. .when(iw.hoverProperty())
  38. .then((Effect) sepia)
  39. .otherwise((Effect) null)
  40. );
  41. iw.setCache(true);
  42. iw.setCacheHint(CacheHint.SPEED);
  43. root.getChildren().add(iw);
  44. Scene scene = new Scene(root);
  45. stage.setTitle("SepiaTone");
  46. scene.setFill(Color.WHITESMOKE);
  47. stage.setScene(scene);
  48. stage.show();
  49. }
  50. public static void main(String[] args) {
  51. launch(args);
  52. }
  53. }

当鼠标指针悬停在图像上时,该示例在Image上应用SepiaTone效果。

  1. Image image = new Image("file:mushroom.png");
  2. ImageView iw = new ImageView(image);

我们从磁盘加载Image并创建一个ImageView控件。

  1. SepiaTone sepia = new SepiaTone();
  2. iw.effectProperty().bind(
  3. Bindings
  4. .when(iw.hoverProperty())
  5. .then((Effect) sepia)
  6. .otherwise((Effect) null)
  7. );

当鼠标指针位于ImageView控件的边界上时,将设置SepiaTone效果。

  1. iw.setCache(true);
  2. iw.setCacheHint(CacheHint.SPEED);

出于性能原因,将缓存节点渲染。

透视变换

PerspectiveTransform提供输入内容的非仿射变换。 它通常用于在二维内容上创建三维效果。

PerspectiveEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.effect.PerspectiveTransform;
  5. import javafx.scene.layout.Pane;
  6. import javafx.scene.layout.StackPane;
  7. import javafx.scene.paint.Color;
  8. import javafx.scene.shape.Rectangle;
  9. import javafx.stage.Stage;
  10. /**
  11. * ZetCode JavaFX tutorial
  12. *
  13. * This program creates a chessboard
  14. * with a PerspectiveTransform effect.
  15. *
  16. * Author: Jan Bodnar
  17. * Website: zetcode.com
  18. * Last modified: June 2015
  19. */
  20. public class PerspectiveEx extends Application {
  21. private final int SIZE = 50;
  22. @Override
  23. public void start(Stage stage) {
  24. initUI(stage);
  25. }
  26. private void initUI(Stage stage) {
  27. StackPane root = new StackPane();
  28. Pane board = new Pane();
  29. for (int row = 0; row < 8; row++) {
  30. for (int col = 0; col < 8; col++) {
  31. Rectangle r = new Rectangle(col * SIZE, row*SIZE,
  32. SIZE, SIZE);
  33. if ((col+row) % 2 == 0) {
  34. r.setFill(Color.WHITE);
  35. } else {
  36. r.setFill(Color.BLACK);
  37. }
  38. board.getChildren().add(r);
  39. }
  40. }
  41. PerspectiveTransform e = new PerspectiveTransform();
  42. e.setUlx(30); // Upper-left point
  43. e.setUly(170);
  44. e.setUrx(370); // Upper-right point
  45. e.setUry(170);
  46. e.setLlx(0); // Lower-left point
  47. e.setLly(300);
  48. e.setLrx(400); // Lower-right point
  49. e.setLry(300);
  50. board.setEffect(e);
  51. root.getChildren().add(board);
  52. Scene scene = new Scene(root, Color.WHITESMOKE);
  53. stage.setTitle("ChessBoard");
  54. stage.setScene(scene);
  55. stage.show();
  56. }
  57. public static void main(String[] args) {
  58. launch(args);
  59. }
  60. }

该示例形成具有PerspectiveTransform效果的棋盘。

  1. for (int row = 0; row < 8; row++) {
  2. for (int col = 0; col < 8; col++) {
  3. Rectangle r = new Rectangle(col * SIZE, row*SIZE,
  4. SIZE, SIZE);
  5. if ((col+row) % 2 == 0) {
  6. r.setFill(Color.WHITE);
  7. } else {
  8. r.setFill(Color.BLACK);
  9. }
  10. board.getChildren().add(r);
  11. }
  12. }

此代码产生 64 个矩形。 矩形具有黑色和白色。

  1. PerspectiveTransform e = new PerspectiveTransform();
  2. e.setUlx(30); // Upper-left point
  3. e.setUly(170);
  4. e.setUrx(370); // Upper-right point
  5. e.setUry(170);
  6. e.setLlx(0); // Lower-left point
  7. e.setLly(300);
  8. e.setLrx(400); // Lower-right point
  9. e.setLry(300);
  10. board.setEffect(e);

实例化一个PerspectiveTransform并将其应用于该节点。 我们提供四个角点的 x 和 y 坐标。 这些点形成一个矩形,在其中渲染效果。

JavaFX 效果 - 图5

图:Chessboard

组合效果

可以组合效果。 如果已经设置了一种效果,则setEffect()方法将替换一种效果。 为了组合多种效果,我们使用EffectsetInput()方法。

CombiningEffectsEx.java

  1. package com.zetcode;
  2. import javafx.application.Application;
  3. import javafx.scene.Scene;
  4. import javafx.scene.effect.Light;
  5. import javafx.scene.effect.Lighting;
  6. import javafx.scene.effect.Reflection;
  7. import javafx.scene.layout.StackPane;
  8. import javafx.scene.paint.Color;
  9. import javafx.scene.text.Font;
  10. import javafx.scene.text.FontWeight;
  11. import javafx.scene.text.Text;
  12. import javafx.stage.Stage;
  13. /**
  14. * ZetCode JavaFX tutorial
  15. *
  16. * This program combines a Reflection effect
  17. * with a Lighting effect on a Text node.
  18. *
  19. * Author: Jan Bodnar
  20. * Website: zetcode.com
  21. * Last modified: June 2015
  22. */
  23. public class CombiningEffectsEx extends Application {
  24. @Override
  25. public void start(Stage stage) {
  26. initUI(stage);
  27. }
  28. private void initUI(Stage stage) {
  29. StackPane root = new StackPane();
  30. Light.Distant light = new Light.Distant();
  31. light.setAzimuth(50);
  32. Lighting lighting = new Lighting();
  33. lighting.setLight(light);
  34. lighting.setSurfaceScale(5);
  35. Text text = new Text();
  36. text.setText("ZetCode");
  37. text.setFill(Color.CADETBLUE);
  38. text.setFont(Font.font(null, FontWeight.BOLD, 60));
  39. Reflection ref = new Reflection();
  40. ref.setInput(lighting);
  41. text.setEffect(ref);
  42. root.getChildren().add(text);
  43. Scene scene = new Scene(root, 300, 250, Color.WHITESMOKE);
  44. stage.setTitle("Combining effects");
  45. stage.setScene(scene);
  46. stage.show();
  47. }
  48. public static void main(String[] args) {
  49. launch(args);
  50. }
  51. }

该示例程序在Text节点上结合了Reflection效果和Lighting效果。

  1. Light.Distant light = new Light.Distant();
  2. light.setAzimuth(50);
  3. Lighting lighting = new Lighting();
  4. lighting.setLight(light);
  5. lighting.setSurfaceScale(5.0);

这些行创建Lighting效果。

  1. Text text = new Text();
  2. text.setText("ZetCode");
  3. text.setFill(Color.CADETBLUE);
  4. text.setFont(Font.font(null, FontWeight.BOLD, 60));

创建一个Text控件。 字体是放大和粗体。 文本的颜色是CADETBLUE

  1. Reflection ref = new Reflection();
  2. ref.setInput(lighting);

构造了Reflection效果。 使用setInput()方法将其与照明效果结合在一起。

  1. text.setEffect(ref);

效果的最终组合通过setEffect()方法应用于节点。

JavaFX 效果 - 图6

图:组合效果

在本章中,我们创建了几种视觉效果。