如何将边缘添加到网格窗格
Posted
技术标签:
【中文标题】如何将边缘添加到网格窗格【英文标题】:How to add edges to gridpane 【发布时间】:2022-01-05 21:02:36 【问题描述】:我正在努力编写一个程序,该程序需要我使用 GUI 和 MVC 设计模式制作 nonogram 游戏。由于它是一个非图游戏,我需要创建一个网格。一个非图游戏应该是这样的:
这是我在 GridPane 中创建矩形得到的结果:
但我不知道如何在我创建的网格窗格周围添加包含游戏线索的边缘。
这是我的代码:
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),您应该使用复合布局。也就是说,您使用一个父容器,它在包含GridPane
的容器周围布置“提示”,也许使用BorderPane
?然后,BorderPane
的每个边缘都可以根据您的需要包含不同的布局窗格
首先,将board.add(rec[i][j], i, j)
更改为board.add(rec[i][j], i + 1, j + 1)
。然后您可以将“线索”框添加到第 0 行和第 0 列。
【参考方案1】:
考虑使用 JavaFX Control
(或 Pane
)而不是 shape 来表示网格单元,并使用 4 个 GridPane
s 来表示板的不同区域:
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;
【讨论】:
【参考方案2】:在布局方面,将有不止一种方法来解决它。您可以选择 cmets 中建议的方式,也可以使用以下方法。
以下方法依赖于使用 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 样式的一种方式。
【讨论】:
以上是关于如何将边缘添加到网格窗格的主要内容,如果未能解决你的问题,请参考以下文章
php 如何以编程方式使用panelizer将窗格添加到节点