向GridPane JavaFX添加边框

我正在使用GridPane在JavaFX中创建一个棋盘游戏。

有7种不同的动画可以放置在网格的每个网格(单元格)中。

最初网格看起来像这样

空格子

我在编程动画插入之前测试了添加一个简单的圆圈。 它看起来像这样

带有子场景的网格窗格

在此处输入图像描述

添加的节点是SubScenes,包括TimeLine动画。 每个单元大小为40×40,SubScene大小也为40×40。

添加后的子场景,位于网格窗格边框线的顶部,看起来不太好。

我该怎么做才能将节点添加到网格线下面? 即网格线位于节点之上。

如果使用GridPane是不可能的,还有什么我可以使用的吗?

我为游戏执行的课程

class Game { static GridPane grid; public void start(final Stage stage) throws Exception { int rows = 5; int columns = 5; stage.setTitle("Enjoy your game"); grid = new GridPane(); for(int i = 0; i < columns; i++) { ColumnConstraints column = new ColumnConstraints(40); grid.getColumnConstraints().add(column); } for(int i = 0; i < rows; i++) { RowConstraints row = new RowConstraints(40); grid.getRowConstraints().add(row); } grid.setOnMouseReleased(new EventHandler () { public void handle(MouseEvent me) { grid.add(Anims.getAnim(1), (int)((me.getSceneX() - (me.getSceneX() % 40)) / 40), (int)((me.getSceneY() - (me.getSceneY() % 40)) / 40)); //here the getAnim argument could be between 1-7 } }); grid.setStyle("-fx-background-color: white; -fx-grid-lines-visible: true"); Scene scene = new Scene(grid, (columns * 40) + 100, (rows * 40) + 100, Color.WHITE); stage.setScene(scene); stage.show(); } public static void main(final String[] arguments) { Application.launch(arguments); } } 

包含动画的类,这里我只创建一个圆圈

 public class Anims { public static SubScene getAnim(final int number) throws Exception { Circle circle = new Circle(20, 20f, 7); circle.setFill(Color.RED); Group group = new Group(); group.getChildren().add(circle); SubScene scene = new SubScene(group, 40, 40); scene.setFill(Color.WHITE); return scene; } } 

不要使用setGridLinesVisible(true) : 文档明确声明这仅用于调试。

而是将窗格放在所有网格单元格中(甚至是空格子单元格),并设置窗格样式以便您看到边框。 (这使您有机会非常小心地控制边框,因此可以避免双边框等。)然后将内容添加到每个窗格。 您还可以使用窗格注册鼠标侦听器,这意味着您无需进行丑陋的数学运算来确定单击了哪个单元格。

将边框应用于任何区域的推荐方法是使用CSS和“嵌套背景”方法。 在此方法中,您在区域上绘制两个(或更多)背景填充,使用不同的插入,给出边框的外观。 例如:

 -fx-background-fill: black, white ; -fx-background-insets: 0, 1 ; 

将首先绘制一个没有插入的黑色背景,然后在其上绘制一个白色背景,所有侧面都有1个像素的插图,给出宽度为1像素的黑色边框的外观。 虽然这看起来可能是违反直觉的,但这种表现(据称)比直接指定边界更好。 您还可以为每个填充的插入指定四个值的序列,这些值分别被解释为顶部,右侧,底部和左侧的插入。 所以

 -fx-background-fill: black, white ; -fx-background-insets: 0, 0 1 1 0 ; 

在右侧和底部等具有黑色边框的效果。

我也不确定SubScene是你真正想要的,除非你打算将不同的相机连接到每个单元。 如果您确实需要子场景,请使填充变得透明以避免绘制单元格的边缘。 您可以直接将Group添加到每个单元格(您可能只需添加圆圈,具体取决于您需要的…)。

就像是:

 import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.layout.ColumnConstraints; import javafx.scene.layout.GridPane; import javafx.scene.layout.Pane; import javafx.scene.layout.RowConstraints; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; import javafx.stage.Stage; public class Game2 extends Application{ @Override public void start(final Stage stage) throws Exception { int rows = 5; int columns = 5; stage.setTitle("Enjoy your game"); GridPane grid = new GridPane(); grid.getStyleClass().add("game-grid"); for(int i = 0; i < columns; i++) { ColumnConstraints column = new ColumnConstraints(40); grid.getColumnConstraints().add(column); } for(int i = 0; i < rows; i++) { RowConstraints row = new RowConstraints(40); grid.getRowConstraints().add(row); } for (int i = 0; i < columns; i++) { for (int j = 0; j < rows; j++) { Pane pane = new Pane(); pane.setOnMouseReleased(e -> { pane.getChildren().add(Anims.getAtoms(1)); }); pane.getStyleClass().add("game-grid-cell"); if (i == 0) { pane.getStyleClass().add("first-column"); } if (j == 0) { pane.getStyleClass().add("first-row"); } grid.add(pane, i, j); } } Scene scene = new Scene(grid, (columns * 40) + 100, (rows * 40) + 100, Color.WHITE); scene.getStylesheets().add("game.css"); stage.setScene(scene); stage.show(); } public static class Anims { public static Node getAtoms(final int number) { Circle circle = new Circle(20, 20f, 7); circle.setFill(Color.RED); Group group = new Group(); group.getChildren().add(circle); // SubScene scene = new SubScene(group, 40, 40); // scene.setFill(Color.TRANSPARENT); return group; } } public static void main(final String[] arguments) { Application.launch(arguments); } } 

和CSS:

 .game-grid { -fx-background-color: white ; -fx-padding: 10 ; } .game-grid-cell { -fx-background-color: black, white ; -fx-background-insets: 0, 0 1 1 0 ; } .game-grid-cell.first-row { -fx-background-insets: 0, 1 1 1 0 ; } .game-grid-cell.first-column { -fx-background-insets: 0, 0 1 1 1 ; } .game-grid-cell.first-row.first-column { -fx-background-insets: 0, 1 ; } 

@James_D在评论中已批准此方法。

只需添加一个像素宽度的H和V间隙,让网格窗格的背景颜色“闪耀”通过:

 .my-grid-pane { -fx-background-color: lightgray; -fx-vgap: 1; -fx-hgap: 1; -fx-padding: 1; } 

如果网格窗格的背景颜色从外部扩展到多个像素(如果其父级大于自身,则会发生),只需将网格包装在一个Group