向GridPane JavaFX

时间:2015-10-01 16:38:01

标签: java animation javafx javafx-2 javafx-8

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

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

最初网格看起来像这样

empty gridpane

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

gridpane with subscenes

enter image description here

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

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

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

如果使用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);
    }
}

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

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

3 个答案:

答案 0 :(得分:9)

不要使用setGridLinesVisible(true)documentation明确说明这仅用于调试。

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

将边框应用于任何区域的推荐方法是使用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 ;
}

答案 1 :(得分:2)

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

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

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

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

答案 2 :(得分:0)

我为回应而不是评论道歉,信誉不足。

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

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

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