向GridPane JavaFX添加边框

向GridPane JavaFX添加边框,java,animation,javafx,javafx-2,javafx-8,Java,Animation,Javafx,Javafx 2,Javafx 8,我正在使用GridPane在JavaFX中创建一个棋盘游戏 有7种不同的动画可以放置在网格的每个网格(单元)中 最初网格是这样的 在编程动画插入之前,我测试了添加一个简单的圆圈。看起来是这样的 添加的节点是包含时间轴动画的子场景。每个单元大小为40x40,子场景大小也为40x40 添加子场景时,子场景位于gridpane边界线上,看起来不太好 如何将节点添加到轴网线下方?i、 e.网格线位于节点顶部 如果不能使用GridPane,还有什么我可以使用的吗 我为游戏执行的类 class Gam

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

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

最初网格是这样的

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

添加的节点是包含时间轴动画的子场景。每个单元大小为40x40,子场景大小也为40x40

添加子场景时,子场景位于gridpane边界线上,看起来不太好

如何将节点添加到轴网线下方?i、 e.网格线位于节点顶部

如果不能使用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<MouseEvent> () {
            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);
    }
}

不要使用
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
是否是您真正想要的,除非您打算在每个单元上安装不同的摄像头。如果确实需要子场景,请使填充透明,以避免在单元边缘上绘制。您可以直接将
添加到每个单元格中(您可能只需添加圆圈,具体取决于您需要什么…)

比如:

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);
    }
}

只需添加一个像素宽度的H和V间隙,并让网格窗格的背景色“发光”:


如果网格窗格的背景颜色从外部扩散到一个以上的像素(如果其父像素大于其自身,则会发生这种情况),只需将网格包装在一个
组中

我为回复而不是评论道歉,因为没有足够的声誉

奇怪的是,@James_D的回答对我没有帮助;调整窗口大小时,单元格边框随机改变其宽度,彼此重叠

帮助解决了问题,因此通过稍微更改@James_D(仅.css文件)给出的代码,我们得到:


如果没有代码,你的问题是不可能回答的:我们怎么知道你在做什么,而不知道你是如何实现它的?创建一个显示相同行为的问题,并编辑您的问题以将其包括在内。@James_希望如果您发布了一个,此帮助会更容易,但有足够的内容来查看出了什么问题。此问题类似于(可能是重复的?)。使用子场景是解决此问题的一种非常有效的方法,通常,子场景用于将2D/3D场景与不同的摄影机透视图和照明进行混合(这似乎不是您在这里要做的),您可以从实现中删除子场景,只使用常规容器节点,例如窗格子类组。我正在尝试使其与我的代码兼容,当一个单元格被点击时,除了得到一个动画外,还有很多事情在进行。我对css了解不多,所以你能简要解释一下.css文件中的数字是什么吗?@vicky提供的css中的数字是分层背景的背景插图,请在中阅读它们(以及其他css相关主题)。效果很好,按照你和jewelsea的建议,将子场景替换为窗格,感谢您对“嵌套背景”技术的解释。很好,但是添加1像素的h和v间距并让网格窗格的背景颜色“发光”不是更容易吗?
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);
    }
}
.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 ;
}
.my-grid-pane {
    -fx-background-color: lightgray;
    -fx-vgap: 1;
    -fx-hgap: 1;
    -fx-padding: 1;
}
.classes-grid {
    -fx-background-color: white ;
    -fx-padding: 10 ;
}
.classes-grid-cell {
    -fx-border-color: dimgray;
    -fx-border-width: 0 1 1 0;
    -fx-background-color: transparent;
}
.classes-grid-cell.first-row {
    -fx-border-width: 1 1 1 0 ;
}
.classes-grid-cell.first-column {
    -fx-border-width: 0 1 1 1 ;
}
.classes-grid-cell.first-row.first-column {
    -fx-border-width: 1 ;
}