简体   繁体   English

BorderPane 不显示除中心 Javafx 之外的其他窗格

[英]BorderPane not showing other pane except for center Javafx

I have this piece of code here that has a borderpane as a parent and 2 other panes, one is a minesweeper game and the other is an empty pane with a black background, the minesweeper game is set to be in the center of the borderpane and the empty pane is set to be in the bottom.我在这里有一段代码,它有一个边框作为父窗格和另外两个窗格,一个是扫雷游戏,另一个是黑色背景的空窗格,扫雷游戏设置在边框的中心和空窗格设置在底部。 Right now when I run the code, it will only show the minesweeper game and not the empty pane (can be seen in the image).现在当我运行代码时,它只会显示扫雷游戏而不是空窗格(可以在图像中看到)。 How do I make it show the empty pane at the bottom of the borderpane?如何让它在边框底部显示空窗格?

(Layout as of right now) (目前的布局)

在此处输入图片说明

package project;

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class MinesweeperApp extends Application {

    private static final int TILE_SIZE = 40;
    private static final int W = 800;
    private static final int H = 800;

    private static final int X_TILES = W / TILE_SIZE;
    private static final int Y_TILES = H / TILE_SIZE;

    private Tile[][] grid = new Tile[X_TILES][Y_TILES];
//    private ArrayList[][] grid = new ArrayList[X_TILES][Y_TILES];
    private Scene scene;

    private Parent createContent() {
        BorderPane root = new BorderPane();
        Pane middlepane = new Pane();
        Pane lowerPane = new Pane();
        

        lowerPane.setStyle("-fx-background-color: black;");
        root.setTop(lowerPane);
        root.setBottom(middlepane);
        middlepane.setPrefSize(W, H);

        for (int y = 0; y < Y_TILES; y++) {
            for (int x = 0; x < X_TILES; x++) {
                Tile tile = new Tile(x, y, Math.random() < 0.2);

                grid[x][y] = tile;
                middlepane.getChildren().add(tile);
            }
        }

        for (int y = 0; y < Y_TILES; y++) {
            for (int x = 0; x < X_TILES; x++) {
                Tile tile = grid[x][y];

                if (tile.hasBomb)
                    continue;

                long bombs = getNeighbors(tile).stream().filter(t -> t.hasBomb).count();

                if (bombs > 0)
                    tile.text.setText(String.valueOf(bombs));
            }
        }

        return root;
    }

    private List<Tile> getNeighbors(Tile tile) {
        List<Tile> neighbors = new ArrayList<>();

        // ttt
        // tXt
        // ttt

        int[] points = new int[] {
                -1, -1,
                -1, 0,
                -1, 1,
                0, -1,
                0, 1,
                1, -1,
                1, 0,
                1, 1
        };

        for (int i = 0; i < points.length; i++) {
            int dx = points[i];
            int dy = points[++i];

            int newX = tile.x + dx;
            int newY = tile.y + dy;

            if (newX >= 0 && newX < X_TILES
                    && newY >= 0 && newY < Y_TILES) {
                neighbors.add(grid[newX][newY]);
            }
        }

        return neighbors;
    }

    private class Tile extends StackPane {
        private int x, y;
        private boolean hasBomb;
        private boolean isOpen = false;

        private Rectangle border = new Rectangle(TILE_SIZE - 2, TILE_SIZE - 2);
        private Text text = new Text();

        public Tile(int x, int y, boolean hasBomb) {
            this.x = x;
            this.y = y;
            this.hasBomb = hasBomb;

            border.setStroke(null);
            border.setFill(Color.NAVY);

            text.setFont(Font.font(18));
            text.setText(hasBomb ? "X" : "");
            text.setVisible(false);

            getChildren().addAll(border, text);

            setTranslateX(x * TILE_SIZE);
            setTranslateY(y * TILE_SIZE);

            setOnMouseClicked(e -> open());
        }

        public void open() {
            System.out.println("clicked");
            System.out.println("x: " + this.x + " " + "y: " + this.y);
            if (isOpen){
                return;
            }



            if (hasBomb) {
                System.out.println("Game Over");
                scene.setRoot(createContent());
                return;
            }

            isOpen = true;
            text.setVisible(true);
            border.setFill(Color.RED);

            if (text.getText().isEmpty()) {
                getNeighbors(this).forEach(Tile::open);
            }
        }
    }

    @Override
    public void start(Stage stage) throws Exception {
        scene = new Scene(createContent());
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {

        launch(args);
    }
}

Absent children, an empty Pane has zero width and height.如果没有孩子,一个空的Pane宽度和高度为零。 Try adding non-empty content to the top and bottom to see the effect:尝试在顶部和底部添加非空内容,看看效果:

root.setTop(new Label("top"));
root.setCenter(middlepane);
root.setBottom(new Label("bottom"));

最佳


底部

As an aside, your original root.setBottom(middlepane) may be misleading. root.setBottom(middlepane) ,您原来的root.setBottom(middlepane)可能会产生误导。

If you want to “see” a Pane which has no content, ie take up space in the layout, you can set size constraints on it.如果您想“看到”一个没有内容的 Pane,即在布局中占用空间,您可以对其设置大小限制。

You could configure the min width or height, or, pref width or height, or any combination of those that will make the app behave as you desire.您可以配置最小宽度或高度,或者首选宽度或高度,或者可以使应用程序按照您的意愿运行的任意组合。

For example to set a min height for the top pane in a border pane例如,为边框窗格中的顶部窗格设置最小高度

BorderPane borderPane = new BorderPane();

Pane top = new Pane();
top.setMinHeight(15);
borderPane.setTop(top); 

Or you could put some content in the pane and make it invisible until it is needed.或者您可以在窗格中放置一些内容并使其不可见,直到需要它为止。

For example:例如:

Label header = new Label("header");
header.setVisible(false);
Pane top = new Pane(header);
borderPane.setTop(top);

This works because things in the scene graph which are not visible still take up layout space, even though they are not displayed, unless you also call setManaged(false).这是有效的,因为场景图中不可见的东西仍然占用布局空间,即使它们没有显示,除非你也调用 setManaged(false)。

For the specific case of a label, you wouldn't need the visibility setting, you could just set the label to an empty string and it would still take up room, even though nothing would be shown.对于标签的特定情况,您不需要可见性设置,您只需将标签设置为空字符串,它仍然会占用空间,即使不会显示任何内容。

For myself, I try to avoid sizing hints where I can so I would use an empty label.就我自己而言,我尽量避免调整提示的大小,因此我会使用空标签。 Or, set the visibility, for a more complex pane.或者,为更复杂的窗格设置可见性。 That way I let the layout engine calculate the appropriate amount of space to reserve.这样我让布局引擎计算出适当的空间来保留。

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

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