javafx-centering backgroundimage覆盖borderpane

monwx1rj  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(357)

我在试一套 BackgroundImage 作为背景 BorderPane ( pane )在javafx中。我想要那个 BackgroundImage 盖子 BorderPane 它总是位于中心。我想做同样的css(网页)与背景图像。
我已经试过了:
使用css(fx css)

  1. package application;
  2. import javafx.application.Application;
  3. import javafx.stage.Stage;
  4. import javafx.scene.Scene;
  5. import javafx.scene.control.Button;
  6. import javafx.scene.layout.BorderPane;
  7. public class ExternalCSS extends Application {
  8. @Override
  9. public void start(Stage primaryStage) {
  10. try {
  11. //BorderPane()
  12. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
  13. BorderPane borderPane = new BorderPane();
  14. //Button(String text)
  15. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
  16. Button btn = new Button("Center");
  17. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
  18. borderPane.setCenter(btn);
  19. Scene scene = new Scene(borderPane, 600, 600);
  20. URL path = getClass().getResource("resources/BackgroundStyle.css");
  21. if(path != null) {
  22. scene.getStylesheets().add(path.toExternalForm());
  23. } else {
  24. scene.getStylesheets().add("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/BackgroundStyleExternalURL.css");
  25. }
  26. borderPane.setId("background_id");
  27. primaryStage.setScene(scene);
  28. primaryStage.show();
  29. } catch(Exception e) {
  30. e.printStackTrace();
  31. }
  32. }
  33. public static void main(String[] args) {
  34. launch(args);
  35. }
  36. }

此代码使用外部css(您可以在此处找到我的css代码),也可以将以下代码与内联css一起使用:

  1. package application;
  2. import javafx.application.Application;
  3. import javafx.stage.Stage;
  4. import javafx.scene.Scene;
  5. import javafx.scene.control.Button;
  6. import javafx.scene.layout.BorderPane;
  7. public class InlineCSS extends Application {
  8. @Override
  9. public void start(Stage primaryStage) {
  10. try {
  11. //BorderPane()
  12. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
  13. BorderPane borderPane = new BorderPane();
  14. //Button(String text)
  15. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
  16. Button btn = new Button("Center");
  17. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
  18. borderPane.setCenter(btn);
  19. Scene scene = new Scene(borderPane, 600, 600);
  20. URL path = getClass().getResource("resources/black_clock.png");
  21. String image = null;
  22. if(path != null) {
  23. image = path.toExternalForm();
  24. } else {
  25. image = "https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png";
  26. }
  27. borderPane.setStyle("-fx-background-image: url('" + image + "'); " +
  28. "-fx-background-position: center center; " +
  29. "-fx-background-repeat: no-repeat;" +
  30. "-fx-background-size: cover");
  31. primaryStage.setScene(scene);
  32. primaryStage.show();
  33. } catch(Exception e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. public static void main(String[] args) {
  38. launch(args);
  39. }
  40. }

仅使用javafx:

  1. package application;
  2. import java.io.File;
  3. import javafx.application.Application;
  4. import javafx.stage.Stage;
  5. import javafx.scene.Scene;
  6. import javafx.scene.control.Button;
  7. import javafx.scene.image.Image;
  8. import javafx.scene.layout.Background;
  9. import javafx.scene.layout.BackgroundImage;
  10. import javafx.scene.layout.BackgroundPosition;
  11. import javafx.scene.layout.BackgroundRepeat;
  12. import javafx.scene.layout.BackgroundSize;
  13. import javafx.scene.layout.BorderPane;
  14. public class OnlyJavaFX extends Application {
  15. @Override
  16. public void start(Stage primaryStage) {
  17. try {
  18. //BorderPane()
  19. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
  20. BorderPane borderPane = new BorderPane();
  21. //File(String pathname)
  22. //https://docs.oracle.com/javase/8/docs/api/java/io/File.html
  23. File file = new File("./src/application/resourcesa/black_clock.png");
  24. Image img = null;
  25. if(file.exists()) {
  26. //Image(InputStream is)
  27. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
  28. img = new Image(file.getAbsoluteFile().toURI().toString());
  29. } else {
  30. //Image(String url)
  31. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
  32. img = new Image("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png");
  33. }
  34. //BackgroundSize(double width, double height, boolean widthAsPercentage, boolean heightAsPercentage, boolean contain, boolean cover)
  35. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BackgroundSize.html
  36. BackgroundSize bgSize = new BackgroundSize(0, 0, false, false, false, true);
  37. //public BackgroundImage(Image image, BackgroundRepeat repeatX, BackgroundRepeat repeatY, BackgroundPosition position, BackgroundSize size)
  38. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BackgroundImage.html
  39. BackgroundImage bgImg = new BackgroundImage(img,
  40. BackgroundRepeat.NO_REPEAT,
  41. BackgroundRepeat.NO_REPEAT,
  42. BackgroundPosition.CENTER,
  43. bgSize);
  44. //Background(BackgroundImage... images)
  45. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/Background.html
  46. Background bg = new Background(bgImg);
  47. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/Region.html#setBackground-javafx.scene.layout.Background-
  48. borderPane.setBackground(bg);
  49. //Button(String text)
  50. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
  51. Button btn = new Button("Center");
  52. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
  53. borderPane.setCenter(btn);
  54. Scene scene = new Scene(borderPane, 600, 600);
  55. primaryStage.setScene(scene);
  56. primaryStage.show();
  57. } catch(Exception e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. public static void main(String[] args) {
  62. launch(args);
  63. }
  64. }

当前所有版本的代码(inlinecss、externalcss和onlyjavafx)都会产生如下结果:

下面是相同示例的css和html代码。我希望它看起来像这样:

jsfidle示例:代码,全屏
jsbin示例:代码,全屏
编辑1:
我意识到我已经发布了我的代码的旧版本,所以我会更新它(代码中唯一的变化是,现在它可以工作,即使没有图像和css文件保存在您的计算机上,相反,程序会让它在线。)
在jose martinez的回答之后编辑2:
我已经测试了你的代码,但它不工作(我甚至添加了背景图像视图在y轴方向的平移,在你的回答中它只是在x轴方向,而且我还设置了borderpane的大小以匹配场景(应用程序窗口)的大小,但它仍然不起作用)。下面是完整的代码(与您的答案相同,但我已经提到了一些小的修复):

  1. package application;
  2. import java.io.File;
  3. import javafx.application.Application;
  4. import javafx.stage.Stage;
  5. import javafx.scene.Group;
  6. import javafx.scene.Scene;
  7. import javafx.scene.control.Button;
  8. import javafx.scene.image.Image;
  9. import javafx.scene.image.ImageView;
  10. import javafx.scene.layout.BorderPane;
  11. public class Try1 extends Application {
  12. @Override
  13. public void start(Stage primaryStage) {
  14. try {
  15. //BorderPane()
  16. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
  17. BorderPane borderPane = new BorderPane();
  18. //jot down the width and height of the scene
  19. double width = 600;
  20. double height = 600;
  21. //File(String pathname)
  22. //https://docs.oracle.com/javase/8/docs/api/java/io/File.html
  23. File file = new File("./src/application/resourcesa/black_clock.png");
  24. Image img = null;
  25. if(file.exists()) {
  26. //Image(InputStream is)
  27. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
  28. img = new Image(file.getAbsoluteFile().toURI().toString());
  29. } else {
  30. //Image(String url)
  31. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
  32. img = new Image("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png");
  33. }
  34. ImageView background = new ImageView(img);
  35. //..center the background
  36. double translateX = width/2 - img.getWidth()/2;
  37. System.out.println(translateX);
  38. background.setTranslateX(translateX);
  39. double translateY = height/2 - img.getHeight()/2;
  40. System.out.println(translateY);
  41. background.setTranslateY(translateY);
  42. //Button(String text)
  43. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
  44. Button btn = new Button("Center");
  45. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
  46. borderPane.setCenter(btn);
  47. //make root with BorderPane and background image
  48. Group root = new Group (background, borderPane);
  49. Scene scene = new Scene(root, width, height);
  50. primaryStage.setScene(scene);
  51. //this lines set borderPane's dimensions to be the same as scene
  52. borderPane.prefHeightProperty().bind(scene.heightProperty());
  53. borderPane.prefWidthProperty().bind(scene.widthProperty());
  54. primaryStage.show();
  55. } catch(Exception e) {
  56. e.printStackTrace();
  57. }
  58. }
  59. public static void main(String[] args) {
  60. launch(args);
  61. }
  62. }

问题是,这段代码只有在启动程序时才起作用

一旦你调整了(应用程序)窗口的大小,它就不再居中了。

wljmcqd8

wljmcqd81#

我将通过不使用backgroundimage来实现这一点,而只是使用另一个可以包含backgroundimageview的区域。然后平移背景图像视图,使其居中。
我对你的代码进行了调整。我使用组作为场景的根节点。在这个根目录中,我放置了背景的imageview和borderpane。

  1. //BorderPane()
  2. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
  3. BorderPane borderPane = new BorderPane();
  4. //jot down the width and height of the scene
  5. double width = 600;
  6. double height = 600;
  7. //Image(InputStream is)
  8. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
  9. Image img = new Image(file.getAbsoluteFile().toURI().toString());
  10. ImageView background = new ImageView(img);
  11. //..center the background
  12. double translateX = width/2 - img.getWidth()/2;
  13. background.setTranslateX(translateX);
  14. //Button(String text)
  15. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
  16. Button btn = new Button("Center");
  17. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
  18. borderPane.setCenter(btn);
  19. //make root with BorderPane and background image
  20. Group root = new Group (background, borderPane);
  21. Scene scene = new Scene(root, width, height);

编辑:处理调整大小
1) 将背景图像视图移动为对象字段。2) 创建背景图像视图居中的方法。3) 每当调整窗口大小时,创建回调以使背景图像视图居中。

  1. public class Try1 extends Application {
  2. private ImageView background = new ImageView(img);
  3. private final ChangeListener<Number> windowWidthResized = (ObservableValue<? extends Number> ov, Number t, Number t1) -> {
  4. windowResized();
  5. };
  6. private final ChangeListener<Number> windowHeightResized = (ObservableValue<? extends Number> ov, Number t, Number t1) -> {
  7. windowResized();
  8. };
  9. private void windowResized(){
  10. double newHeight = scene.getHeight();
  11. double newWidth = scene.getWidth();
  12. centerBackgroundImage(newWidth, newHeight);
  13. }
  14. private void centerBackgroundImage(double width, double height) {
  15. double translateX = width/2 - img.getWidth()/2;
  16. System.out.println(translateX);
  17. background.setTranslateX(translateX);
  18. double translateY = height/2 - img.getHeight()/2;
  19. System.out.println(translateY);
  20. background.setTranslateY(translateY);
  21. }
  22. @Override
  23. public void start(Stage primaryStage) {
  24. try {
  25. //BorderPane()
  26. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
  27. BorderPane borderPane = new BorderPane();
  28. //jot down the width and height of the scene
  29. double width = 600;
  30. double height = 600;
  31. //File(String pathname)
  32. //https://docs.oracle.com/javase/8/docs/api/java/io/File.html
  33. File file = new File("./src/application/resourcesa/black_clock.png");
  34. Image img = null;
  35. if(file.exists()) {
  36. //Image(InputStream is)
  37. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
  38. img = new Image(file.getAbsoluteFile().toURI().toString());
  39. } else {
  40. //Image(String url)
  41. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
  42. img = new Image("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png");
  43. }
  44. background.setImage(img);
  45. //..center the background
  46. centerBackgroundImage(width, height);
  47. //Button(String text)
  48. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
  49. Button btn = new Button("Center");
  50. //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
  51. borderPane.setCenter(btn);
  52. //make root with BorderPane and background image
  53. Group root = new Group (background, borderPane);
  54. Scene scene = new Scene(root, width, height);
  55. //add callbacks to handle window resize
  56. scene.heightProperty().addListener(windowResized);
  57. scene.widthProperty().addListener(windowWidthResized);
  58. primaryStage.setScene(scene);
  59. //this lines set borderPane's dimensions to be the same as scene
  60. borderPane.prefHeightProperty().bind(scene.heightProperty());
  61. borderPane.prefWidthProperty().bind(scene.widthProperty());
  62. primaryStage.show();
  63. } catch(Exception e) {
  64. e.printStackTrace();
  65. }
  66. }
  67. public static void main(String[] args) {
  68. launch(args);
  69. }
  70. }
展开查看全部

相关问题