[英]How to add edges to gridpane
我正在努力编写一个程序,该程序需要我使用 GUI 和 MVC 设计模式制作一个非图形游戏。 由于它是一个非图游戏,我需要创建一个网格。 一个非图游戏应该是这样的:
这是我在 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 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.