添加边框GridPane的JavaFX [英] Adding borders to GridPane JavaFX

查看:4374
本文介绍了添加边框GridPane的JavaFX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

有可能的网格被放置在每个网格(单元)7种不同的动画效果。

最初电网看起来像这样

空gridpane

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

gridpane与子场景

在这里输入的形象描述

添加的节点是子场景,其中包括时间轴动画。每个单元尺寸为40×40和子场景大小也是40×40。

该子场景添加时,坐上gridpane边界线的顶部,它看起来并不好。

我能做些什么,这样的节点添加网格线以下?即,网格线上的节点之上。

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

类,我执行的游戏

 类游戏{
    静态GridPane网格;
    公共无效启动(最后阶段阶段)抛出异常{
        INT行= 5;
        INT列= 5;        stage.setTitle(享受你的游戏);
        格=新GridPane();
        的for(int i = 0; I<列;我++){
            ColumnConstraints柱=新ColumnConstraints(40);
            。grid.getColumnConstraints()加(列);
        }        的for(int i = 0; I<行;我++){
            RowConstraints行=新RowConstraints(40);
            。grid.getRowConstraints()加(行);
        }        grid.setOnMouseReleased(新的EventHandler<&的MouseEvent GT;(){
            公共无效手柄(我的MouseEvent){
                grid.add(Anims.getAnim(1),(INT)((me.getSceneX() - (me.getSceneX()%40))/ 40),(INT)((me.getSceneY() - (箱。 getSceneY()%40))/ 40)); //这里的getAnim说法可能是1-7之间
            }
        });        grid.setStyle( - FX-背景颜色:白色; -fx网格线可见:真正的);
        一幕一幕=新场景(格(列* 40)+ 100(行* 40)+ 100,Color.WHITE);
        stage.setScene(场景);
        stage.show();
    }    公共静态无效的主要(最终的String []参数){
        Application.launch(参数);
    }
}

类,它包含动画,在这里我只是创造了一圈

 公共类Anims {    公共静态射手网getAnim(最终诠释号)抛出异常{
        圈圈=新圈(20,20F,7);
        circle.setFill(Color.RED);
        群组=新集团();
        。group.getChildren()加(圈子);
        射手网现场=新射手网(组,40,40);
        scene.setFill(Color.WHITE);
        返回现场;
    }
}


解决方案

不要使用 setGridLinesVisible(真):在<一个href=\"http://docs.oracle.com/javase/8/javafx/api/javafx/scene/layout/GridPane.html#gridLinesVisibleProperty\"相对=nofollow>文档明确指出这是为调试只。

相反,将在所有的网格窗格(即使是空的),和样式面板,所以你看到的边界。 (这让你有机会非常仔细地控制边界,这样就可以避免双边框等),然后添加内容,每个窗格。你也可以用面板,这意味着你不必做丑陋的数学弄清楚单击了哪个小区上注册鼠标监听器。

要边框适用于任何地区推荐的方法是使用CSS和一个嵌套背景的做法。在这种方法中,你画两个(或更多)的背景填充的区域,具有不同的插图,给人一种边框的外观。因此,例如:

  -fx背景填充黑色,白色;
-fx-背景插图:0,1;

将先画一个黑色的背景,没有插图,然后在将画一个白色背景上的各方1个像素的插图,让宽度为1像素的黑色边框的外观。虽然这可能似乎违反直觉,这种表现(据说),比直接指定边界更好。您还可以指定四个值的插图为的每个的填补,这是PTED为顶部的插图间$ P $序列,右,下,左,分别为。因此,

  -fx背景填充黑色,白色;
-fx-背景插图:0,0 1 1 0;

有一个黑色的边界上的右侧和底部等的效果。

我也不清楚射手网是你真正想要的,除非你正打算不同的摄像机连接到每一个细胞。如果你真的需要一个子场景,要使填充透明,以避免绘制在单元的边缘。你可以只在直接添加到每个单元格(你很可能只是增加了一圈,这取决于你需要什么...)。

是这样的:

 进口javafx.application.Application;
进口javafx.scene.Group;
进口javafx.scene.Node;
进口javafx.scene.Scene;
进口javafx.scene.layout.ColumnConstraints;
进口javafx.scene.layout.GridPane;
进口javafx.scene.layout.Pane;
进口javafx.scene.layout.RowConstraints;
进口javafx.scene.paint.Color;
进口javafx.scene.shape.Circle;
进口javafx.stage.Stage;公共类GAME2扩展应用{
    @覆盖
    公共无效启动(最后阶段阶段)抛出异常{
        INT行= 5;
        INT列= 5;        stage.setTitle(享受你的游戏);        GridPane格=新GridPane();
        。grid.getStyleClass()加(游戏网);        的for(int i = 0; I&LT;列;我++){
            ColumnConstraints柱=新ColumnConstraints(40);
            。grid.getColumnConstraints()加(列);
        }        的for(int i = 0; I&LT;行;我++){
            RowConstraints行=新RowConstraints(40);
            。grid.getRowConstraints()加(行);
        }        的for(int i = 0; I&LT;列;我++){
            对于(INT J = 0; J&LT;行; J ++){
                窗格窗格=新窗格();
                pane.setOnMouseReleased(E - &GT; {
                    pane.getChildren()加(Anims.getAtoms(1))。
                });
                。pane.getStyleClass()加(游戏网格细胞);
                如果(我== 0){
                    。pane.getStyleClass()加(第一列);
                }
                如果(J == 0){
                    。pane.getStyleClass()加(第一行);
                }
                grid.add(窗格,I,J);
            }
        }
        一幕一幕=新场景(格(列* 40)+ 100(行* 40)+ 100,Color.WHITE);
        。scene.getStylesheets()加(game.css);
        stage.setScene(场景);
        stage.show();
    }    公共静态类Anims {        公共静态节点getAtoms(最终​​诠释号){
            圈圈=新圈(20,20F,7);
            circle.setFill(Color.RED);
            群组=新集团();
            。group.getChildren()加(圈子);
//射手网现场=新射手网(组,40,40);
// scene.setFill(Color.TRANSPARENT);
            返回组;
        }
    }    公共静态无效的主要(最终的String []参数){
        Application.launch(参数);
    }
}

和CSS的:

 。游戏网{
    -fx背景颜色:白色;
    -fx-填充:10;
}
。游戏网细胞{
    -fx背景色:黑色,白色;
    -fx-背景插图:0,0 1 1 0;
}
。游戏并网cell.first行{
    -fx-背景插图:0,1 1 1 0;
}
。游戏并网cell.first列{
    -fx-背景插图:0,0 1 1 1;
}
。游戏并网cell.first-row.first列{
    -fx-背景插图:0,1;
}

I am creating a board game in JavaFX using GridPane.

There are 7 different animations which could be placed in each grid (cell) of the grid.

Initially the grid looks like this

I tested adding a simple circle to it before programming my animation insertions. And it looks like this

The nodes added are SubScenes which include TimeLine animation. Each cell size is 40x40 and the SubScene size is also 40x40.

The subscenes when added, get on top of the gridpane border lines and it doesn't look good.

What can I do so that the nodes are added below the grid lines? i.e. the gridlines are on top of the nodes.

If it is not possible with GridPane, is there anything else I can use?

class which i execute for the game

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

class which contains animations, here I am just creating a circle

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

解决方案

Don't use setGridLinesVisible(true): the documentation explicitly states this is for debug only.

Instead, place a pane in all the grid cells (even the empty ones), and style the pane so you see the borders. (This gives you the opportunity to control the borders very carefully, so you can avoid double borders, etc.) Then add the content to each pane. You can also register the mouse listeners with the pane, which means you don't have to do the ugly math to figure out which cell was clicked.

The recommended way to apply a border to any region is to use CSS and a "nested background" approach. In this approach, you draw two (or more) background fills on the region, with different insets, giving the appearance of a border. So for example:

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

will first draw a black background with no insets, and then over that will draw a white background with insets of 1 pixel on all sides, giving the appearance of a black border of width 1 pixel. While this may seem counter-intuitive, the performance of this is (allegedly) better than specifying border directly. You can also specify a sequence of four values for the insets for each fill, which are interpreted as the insets on the top, right, bottom, and left, respectively. So

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

has the effect of a black border on the right and bottom, etc.

I'm also not sure SubScene is what you really want, unless you are intending attaching different cameras to each cell. If you really need a subscene, make the fill transparent to avoid drawing over the edges of the cell. You could just add the Group directly to each cell (you could probably just add the circle, depending on exactly what you need...).

Something like:

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

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

这篇关于添加边框GridPane的JavaFX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆