简体   繁体   English

如何将JavaFX Canvas嵌入BorderPane?

[英]How to embed JavaFX Canvas into BorderPane?

I'm trying to make a application using JavaFX. 我正在尝试使用JavaFX创建一个应用程序。

What I want to make is the window with MenuBar on the top of it and Canvas in the center. 我想要做的是窗口,其顶部是MenuBar ,中间是Canvas I also want the window to be able to resize. 我也希望窗口能够调整大小。 Referring to the following link, which shows how to make Canvas resizable, I first made the following code: 参考以下链接,其中显示了如何使Canvas可调整大小,我首先做了以下代码:

JavaFX Tip 1: Resizable Canvas – DLSC JavaFX技巧1:可调整大小的画布 - DLSC

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class CanvasInBorderPane extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane borderPane = new BorderPane();

        // Put menu bar on the top of the window
        MenuBar menuBar = new MenuBar(new Menu("File"), new Menu("Edit"),
                new Menu("Help"));
        borderPane.setTop(menuBar);

        // Put canvas in the center of the window (*)
        Canvas canvas = new Canvas();
        borderPane.setCenter(canvas);
        // Bind the width/height property so that the size of the Canvas will be
        // resized as the window is resized
        canvas.widthProperty().bind(borderPane.widthProperty());
        canvas.heightProperty().bind(borderPane.heightProperty());
        // redraw when resized
        canvas.widthProperty().addListener(event -> draw(canvas));
        canvas.heightProperty().addListener(event -> draw(canvas));
        draw(canvas);

        Scene scene = new Scene(borderPane);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * Draw crossed red lines which each each end is at the corner of window,
     * and 4 blue circles whose each center is at the corner of the window,
     * so that make it possible to know where is the extent the Canvas draws
     */
    private void draw(Canvas canvas) {
        int width = (int) canvas.getWidth();
        int height = (int) canvas.getHeight();
        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.clearRect(0, 0, width, height);
        gc.setStroke(Color.RED);
        gc.strokeLine(0, 0, width, height);
        gc.strokeLine(0, height, width, 0);
        gc.setFill(Color.BLUE);
        gc.fillOval(-30, -30, 60, 60);
        gc.fillOval(-30 + width, -30, 60, 60);
        gc.fillOval(-30, -30 + height, 60, 60);
        gc.fillOval(-30 + width, -30 + height, 60, 60);
    }
}

Then I got a window like (1) (See the picture below.) 然后我有一个像(1)的窗口(见下图)

I know this is because the actual size the Canvas should be is smaller than the size of borderPane . 我知道这是因为Canvas应该的实际大小小于borderPane的大小。 But I don't know how to get the CENTER region of the BorderPane . 但我不知道如何获得BorderPane的CENTER区域。

I then tried putting a wrapper Pane in the center of the borderPane and embed the Canvas into it, binding the width and height of the wrapper Pane to the Canvas . 然后,我尝试将一个包装器Pane放在borderPane的中心,并将Canvas嵌入其中,将包装器Pane的宽度和高度绑定到Canvas I changed the 10+ lines of the code above which initializes the Canvas (which start from the comment-line with (*)) as follows: 我更改了上面代码的10+行,用于初始化Canvas (从带有(*)的注释行开始),如下所示:

        // Create a wrapper Pane first
        BorderPane wrapperPane = new BorderPane();
        borderPane.setCenter(wrapperPane);
        // Put canvas in the center of the window
        Canvas canvas = new Canvas();
        wrapperPane.setCenter(canvas);
        // Bind the width/height property to the wrapper Pane
        canvas.widthProperty().bind(wrapperPane.widthProperty());
        canvas.heightProperty().bind(wrapperPane.heightProperty());
        // redraw when resized
        canvas.widthProperty().addListener(event -> draw(canvas));
        canvas.heightProperty().addListener(event -> draw(canvas));
        draw(canvas);

Then something strange happened. 然后发生了奇怪的事情 When I increased the width of the window, everything went good as I supposed. 当我增加窗口的宽度时,一切都如我所想的那样好。 (Picture (2)) (图(2))

However, though I decreased the width, the width of the Canvas wouldn't decrease, in other words, fit to the size of the window. 但是,虽然我减小了宽度,但Canvas的宽度不会减小,换句话说,适合窗口的大小。 (Picture (3)) (图(3))

And so does the height. 身高也是如此。

Does anybody have an idea to do away with this problem? 有人有想法解决这个问题吗? My Java version is 1.8.0_71. 我的Java版本是1.8.0_71。

The screenshots of the window 窗口的截图

Use a plain Pane to wrap the canvas, instead of a BorderPane : 使用普通Pane来包装画布,而不是BorderPane

    // Create a wrapper Pane first
    Pane wrapperPane = new Pane();
    borderPane.setCenter(wrapperPane);
    // Put canvas in the center of the window
    Canvas canvas = new Canvas();
    wrapperPane.getChildren().add(canvas);
    // Bind the width/height property to the wrapper Pane
    canvas.widthProperty().bind(wrapperPane.widthProperty());
    canvas.heightProperty().bind(wrapperPane.heightProperty());
    // redraw when resized
    canvas.widthProperty().addListener(event -> draw(canvas));
    canvas.heightProperty().addListener(event -> draw(canvas));
    draw(canvas);

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

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