繁体   English   中英

如何将边缘添加到网格窗格

[英]How to add edges to gridpane

我正在努力编写一个程序,该程序需要我使用 GUI 和 MVC 设计模式制作一个非图形游戏。 由于它是一个非图游戏,我需要创建一个网格。 一个非图游戏应该是这样的:

游戏1

这是我在 GridPane 中创建矩形得到的结果:

游戏2

但我不知道如何在我创建的网格周围添加包含游戏线索的边缘。

这是我的代码:

public class PuzzleView implements FXComponent {

  private Controller controller;
  Model model;

  public PuzzleView(Controller controller) {
    this.controller = controller;
    model = ((ControllerImpl) controller).getModel();
  }
So
  @Override
  public Parent render() {

    GridPane board = new GridPane();
    double width = 30;
    board.setLayoutX(300);
    board.setLayoutY(300);
    int h = model.getHeight();
    int w = model.getWidth();

    Rectangle[][] rec = new Rectangle[w][h];

    for (int i = 0; i < w; i++) {
      for (int j = 0; j < h; j++) {
        rec[i][j] = new Rectangle();
        rec[i][j].setX(i * width);
        rec[i][j].setY(j * width);
        rec[i][j].setWidth(width);
        rec[i][j].setHeight(width);
        rec[i][j].setFill(Color.WHITE);
        rec[i][j].setStroke(Color.BLACK);
        board.add(rec[i][j], i, j);
      }
    }

考虑使用 JavaFX Control (或Pane )而不是 shape 来表示网格单元,并使用 4 GridPane来表示板的不同区域:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class MonogramBoard extends Application {

    private static final int BOARD_SIZE = 5, HINT_SIZE = 2;

    @Override
    public void start(Stage primary) {
        Node corner = new Board(HINT_SIZE, HINT_SIZE, false, false).getNode();
        Node topHint = new Board(HINT_SIZE, BOARD_SIZE, true, true).getNode();
        HBox topPane = new HBox(corner, topHint);

        Node leftHint =  new Board(BOARD_SIZE,HINT_SIZE, true, true).getNode();
        Node board = new Board(BOARD_SIZE, BOARD_SIZE, true, true).getNode();
        HBox bottomPane = new HBox(leftHint, board);
        VBox root = new VBox(topPane, bottomPane);
        root.setPadding(new Insets(10));
        primary.setScene(new Scene(root));
        primary.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

class Board{
    private final GridPane grid;

    public Board(int rows, int columns, boolean isBorder, boolean isGridLines) {
        grid = new GridPane();
        grid.setPadding(new Insets(1));
        if(isBorder) {
            grid.setStyle("-fx-background-color: white; -fx-border-color: black ; -fx-border-width: 2px");
        }else{
            grid.setStyle("-fx-background-color: white; -fx-border-color: white ; -fx-border-width: 2px");
        }
        for(int row = 0; row < rows; row++){
            for(int col = 0; col < columns; col++){
                grid.add(new Cell(isGridLines).getNode(), col, row);
            }
        }
    }

    Node getNode() {return grid; }
}

//represents a single cell
class Cell{
    private final Label label;
    private final int CELL_SIZE = 50;

    Cell(){
        this(true);
    }

    Cell(boolean isBorder){

        label = new Label();
        if(isBorder) {
            label.setStyle("-fx-background-color: white; -fx-border-color: black ; -fx-border-width: 1px");
        }else{
            label.setStyle("-fx-background-color: white; -fx-border-color: white ; -fx-border-width: 1px");
        }
        label.setPrefSize(CELL_SIZE,CELL_SIZE);
    }

    Node getNode() {return label; }
}

在此处输入图像描述

在布局方面,将有不止一种方法来解决它。 您可以选择评论中建议的方式,也可以使用以下方法 go。

下面的方法依赖于使用 CSS 设置边框样式。 通过这种方式,您可以准确地获得您所期望的外观,并且也可以完美地适用于任何尺寸的电路板。

首先,您将提示部分和拼图部分分成单独的网格窗格。 这样您就可以对各个部分进行更多控制。

然后在网格窗格中设置网格窗格和框的样式以获得所需的样式。 在第二个屏幕截图中,我添加了间距以展示每个网格窗格和框的样式以实现最终外观。

关键是您专门设置每个边框边宽(0px、1px 或 2px)。 渲染最终布局后,您将获得所需的外观。

请查看以下演示:

在此处输入图像描述

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.util.stream.Stream;

public class GridPaneBordersDemo extends Application {
    @Override
    public void start(Stage stage) throws Exception {
         double width = 30; // each box size
        int rows = 8; // Main box rows & cols
        int cols = 6;
        int topHintRows = 3;
        int sideHintCols = 4;

        // Top hint pane
        GridPane topHint = new GridPane();
        topHint.getStyleClass().add("topHintPane");
        for (int i = 0; i < cols; i++) {
            for (int j = 0; j < topHintRows; j++) {
                StackPane box = getBox(width);
                box.getStyleClass().add("topHintBox");
                topHint.add(box, i, j);
            }
        }

        // Side hint pane
        GridPane sideHint = new GridPane();
        sideHint.getStyleClass().add("sideHintPane");
        for (int i = 0; i < sideHintCols; i++) {
            for (int j = 0; j < rows; j++) {
                StackPane box = getBox(width);
                box.getStyleClass().add("sideHintBox");
                sideHint.add(box, i, j);
            }
        }

        // Main Puzzle
        GridPane mainPuzzle = new GridPane();
        mainPuzzle.getStyleClass().add("puzzlePane");
        for (int i = 0; i < cols; i++) {
            for (int j = 0; j < rows; j++) {
                StackPane box = getBox(width);
                box.getStyleClass().add("puzzleBox");
                mainPuzzle.add(box, i, j);
            }
        }

        GridPane emptyGrid = new GridPane();
        emptyGrid.getStyleClass().add("emptyGrid");

        GridPane pane = new GridPane();
        pane.setPadding(new Insets(10));
        pane.add(emptyGrid,0,0);
        pane.add(topHint,1,0);
        pane.add(sideHint,0,1);
        pane.add(mainPuzzle,1,1);

        CheckBox checkBox = new CheckBox("Show spacing");
        checkBox.selectedProperty().addListener((obs,old,val)->{
            double gap = val?10:0;
            Insets insets = val? new Insets(10):Insets.EMPTY;
            Stream.of(pane,topHint,sideHint,mainPuzzle,emptyGrid).forEach(grid->{
                grid.setHgap(gap);
                grid.setVgap(gap);
                grid.setPadding(insets);
                stage.sizeToScene();
            });
        });
        VBox root =new VBox(checkBox,pane);
        root.setSpacing(10);
        root.setPadding(new Insets(10));
        Scene scene = new Scene(root);
        scene.getStylesheets().add(getClass().getResource("grid.css").toExternalForm());
        stage.setScene(scene);
        stage.setTitle("GridPane Border");
        stage.setOnShown(e->stage.sizeToScene());
        stage.show();

    }

    private StackPane getBox(double width){
        StackPane box = new StackPane();
        box.setMinSize(width,width);
        box.setMaxSize(width,width);
        box.getStyleClass().add("box");
        return box;
    }
}

CSS 代码(grid.css):

.emptyGrid{
   -fx-border-width: 0px 1px 1px 0px;
   -fx-border-color: black;
}

.topHintPane{
   -fx-border-width: 2px 1px 1px 1px;
   -fx-border-color: black;
}

.sideHintPane{
   -fx-border-width: 1px 1px 1px 2px;
   -fx-border-color: black;
}

.puzzlePane{
   -fx-border-width: 1px;
   -fx-border-color: black;
}

.box{
  -fx-background-color:transparent ;
}

.topHintBox{
   -fx-border-width: 0px 1px 0px 0px;
   -fx-border-color: black;
}

.sideHintBox{
   -fx-border-width: 0px 0px 1px 0px;
   -fx-border-color: black;
}

.puzzleBox{
   -fx-border-width: 0px 1px 1px 0px;
   -fx-border-color: black;
}

我再次提醒您,您也可以通过其他方法实现。 这只是使用单个框和 gridPane 样式的一种方式。

暂无
暂无

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

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