繁体   English   中英

JavaFX-覆盖BorderPane的居中BackgroundImage

[英]JavaFX - Centering BackgroundImage that covers BorderPane

我正在尝试将BackgroundImage设置为JavaFX中BorderPanepane )的背景。 我希望BackgroundImage覆盖BorderPane ,并且始终将其定位在中心。 我想使用background-image与CSS(用于Web)中的操作相同。

我已经尝试过:

  1. 使用CSS(fx-CSS)

     package application; import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.BorderPane; public class ExternalCSS extends Application { @Override public void start(Stage primaryStage) { try { //BorderPane() //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html BorderPane borderPane = new BorderPane(); //Button(String text) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html Button btn = new Button("Center"); //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node- borderPane.setCenter(btn); Scene scene = new Scene(borderPane, 600, 600); URL path = getClass().getResource("resources/BackgroundStyle.css"); if(path != null) { scene.getStylesheets().add(path.toExternalForm()); } else { scene.getStylesheets().add("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/BackgroundStyleExternalURL.css"); } borderPane.setId("background_id"); primaryStage.setScene(scene); primaryStage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } } 

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

     package application; import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.layout.BorderPane; public class InlineCSS extends Application { @Override public void start(Stage primaryStage) { try { //BorderPane() //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html BorderPane borderPane = new BorderPane(); //Button(String text) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html Button btn = new Button("Center"); //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node- borderPane.setCenter(btn); Scene scene = new Scene(borderPane, 600, 600); URL path = getClass().getResource("resources/black_clock.png"); String image = null; if(path != null) { image = path.toExternalForm(); } else { image = "https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png"; } borderPane.setStyle("-fx-background-image: url('" + image + "'); " + "-fx-background-position: center center; " + "-fx-background-repeat: no-repeat;" + "-fx-background-size: cover"); primaryStage.setScene(scene); primaryStage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } } 
  2. 仅使用JavaFX:

     package application; import java.io.File; import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.image.Image; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundImage; import javafx.scene.layout.BackgroundPosition; import javafx.scene.layout.BackgroundRepeat; import javafx.scene.layout.BackgroundSize; import javafx.scene.layout.BorderPane; public class OnlyJavaFX extends Application { @Override public void start(Stage primaryStage) { try { //BorderPane() //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html BorderPane borderPane = new BorderPane(); //File(String pathname) //https://docs.oracle.com/javase/8/docs/api/java/io/File.html File file = new File("./src/application/resourcesa/black_clock.png"); Image img = null; if(file.exists()) { //Image(InputStream is) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html img = new Image(file.getAbsoluteFile().toURI().toString()); } else { //Image(String url) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html img = new Image("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png"); } //BackgroundSize(double width, double height, boolean widthAsPercentage, boolean heightAsPercentage, boolean contain, boolean cover) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BackgroundSize.html BackgroundSize bgSize = new BackgroundSize(0, 0, false, false, false, true); //public BackgroundImage(Image image, BackgroundRepeat repeatX, BackgroundRepeat repeatY, BackgroundPosition position, BackgroundSize size) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BackgroundImage.html BackgroundImage bgImg = new BackgroundImage(img, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, bgSize); //Background(BackgroundImage... images) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/Background.html Background bg = new Background(bgImg); //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/Region.html#setBackground-javafx.scene.layout.Background- borderPane.setBackground(bg); //Button(String text) //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html Button btn = new Button("Center"); //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node- borderPane.setCenter(btn); Scene scene = new Scene(borderPane, 600, 600); primaryStage.setScene(scene); primaryStage.show(); } catch(Exception e) { e.printStackTrace(); } } public static void main(String[] args) { launch(args); } } 

当前,所有版本的代码( InlineCSSExternalCSSOnlyJavaFX )都会产生如下结果:

样本图片

这是同一示例的CSS和HTML代码。 这就是我想要的样子:

样本图片

编辑1:

我意识到我已经发布了旧版本的代码,所以我将对其进行更新。 (唯一的代码更改是,即使在计算机上不保存图像和CSS文件的情况下,它也可以正常运行,而程序将使其联机。)

Jose Martinez的 答案之后编辑2:

我已经测试过您的代码,但是无法正常工作。 (我什至在Y轴的方向上添加了背景ImageView的平移,在您的答案中,它仅在X轴的方向上平移,并且我还设置了borderPane的大小以匹配场景(应用程序窗口)的大小,但是仍然不起作用)。 这是完整的代码(与您的答案相同,但有我已经提到的较小修复):

package application;


import java.io.File;

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;

public class Try1 extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {


            //BorderPane()
            //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
            BorderPane borderPane = new BorderPane();

            //jot down the width and height of the scene
            double width = 600;
            double height = 600;

            //File(String pathname)
            //https://docs.oracle.com/javase/8/docs/api/java/io/File.html
            File file = new File("./src/application/resourcesa/black_clock.png");

            Image img = null;
            if(file.exists()) {
                //Image(InputStream is)
                //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
                img = new Image(file.getAbsoluteFile().toURI().toString());
            } else {
                //Image(String url)
                //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
                img = new Image("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png");
            }


            ImageView background = new ImageView(img);

            //..center the background
            double translateX = width/2 - img.getWidth()/2;
            System.out.println(translateX);
            background.setTranslateX(translateX);

            double translateY = height/2 - img.getHeight()/2;
            System.out.println(translateY);
            background.setTranslateY(translateY);

            //Button(String text)
            //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
            Button btn = new Button("Center");

            //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
            borderPane.setCenter(btn);

            //make root with BorderPane and background image
            Group root = new Group (background, borderPane);

            Scene scene = new Scene(root, width, height);        

            primaryStage.setScene(scene);

            //this lines set borderPane's dimensions to be the same as scene
            borderPane.prefHeightProperty().bind(scene.heightProperty());
            borderPane.prefWidthProperty().bind(scene.widthProperty());

            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

问题是此代码仅在启动程序时有效

样本图片

调整(应用程式)视窗大小后,它便不再居中。

样本图片

我将通过不使用BackGroundImage来实现此目的,而只需在其中可以包含背景ImageView的另一个Region中进行处理。然后转换背景ImageView使其居中。

我调整了您的代码来做到这一点。 我使用“组”作为场景的根节点。 在该根目录中,我放置了背景和BorderPane的ImageView。

        //BorderPane()
        //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
        BorderPane borderPane = new BorderPane();

        //jot down the width and height of the scene
        double width = 600;
        double height = 600;

        //Image(InputStream is)
        //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
        Image img = new Image(file.getAbsoluteFile().toURI().toString());
        ImageView background = new ImageView(img);
        //..center the background
        double translateX = width/2 - img.getWidth()/2;
        background.setTranslateX(translateX);

        //Button(String text)
        //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
        Button btn = new Button("Center");

        //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
        borderPane.setCenter(btn);

        //make root with BorderPane and background image
        Group root = new Group (background, borderPane);

        Scene scene = new Scene(root, width, height);

编辑:处理调整大小

1)将背景ImageView移动为对象字段。 2)创建将背景ImageView居中的方法。 3)每当窗口调整大小时,创建回调以使背景ImageView居中。

public class Try1 extends Application {

    private ImageView background = new ImageView(img);

    private final ChangeListener<Number> windowWidthResized = (ObservableValue<? extends Number> ov, Number t, Number t1) -> {
    windowResized();
};

    private final ChangeListener<Number> windowHeightResized = (ObservableValue<? extends Number> ov, Number t, Number t1) -> {
    windowResized();
};

    private void windowResized(){
        double newHeight = scene.getHeight();
        double newWidth = scene.getWidth();
        centerBackgroundImage(newWidth, newHeight);
    }

    private void centerBackgroundImage(double width, double height) {
            double translateX = width/2 - img.getWidth()/2;
            System.out.println(translateX);
            background.setTranslateX(translateX);

            double translateY = height/2 - img.getHeight()/2;
            System.out.println(translateY);
            background.setTranslateY(translateY);
    }

    @Override
    public void start(Stage primaryStage) {
        try {


            //BorderPane()
            //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html
            BorderPane borderPane = new BorderPane();

            //jot down the width and height of the scene
            double width = 600;
            double height = 600;

            //File(String pathname)
            //https://docs.oracle.com/javase/8/docs/api/java/io/File.html
            File file = new File("./src/application/resourcesa/black_clock.png");

            Image img = null;
            if(file.exists()) {
                //Image(InputStream is)
                //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
                img = new Image(file.getAbsoluteFile().toURI().toString());
            } else {
                //Image(String url)
                //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html
                img = new Image("https://raw.githubusercontent.com/4nds/CenteredBackgroundImage/master/Background/src/application/resources/black_clock.png");
            }


            background.setImage(img);

            //..center the background
            centerBackgroundImage(width, height);

            //Button(String text)
            //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/Button.html
            Button btn = new Button("Center");

            //https://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/BorderPane.html#setCenter-javafx.scene.Node-
            borderPane.setCenter(btn);

            //make root with BorderPane and background image
            Group root = new Group (background, borderPane);

            Scene scene = new Scene(root, width, height);

            //add callbacks to handle window resize
            scene.heightProperty().addListener(windowResized);
            scene.widthProperty().addListener(windowWidthResized);        

            primaryStage.setScene(scene);

            //this lines set borderPane's dimensions to be the same as scene
            borderPane.prefHeightProperty().bind(scene.heightProperty());
            borderPane.prefWidthProperty().bind(scene.widthProperty());

            primaryStage.show();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM