为什么我的 CSS 边框没有出现在 JavaFX gui 中?

Why aren't my CSS borders showing up in JavaFX gui?

我正在尝试使用 .getStyleClass().add() 在 GUI (fxml) 上显示带有 CSS 边框的墙,但它们没有显示出来。

我正在使用将相应样式 类 添加到单元格的开关。

Java代码:

private StackPane createCell(int row, int col) {
    var cell = new StackPane();

    cell.getStyleClass().add("cell");
    cell.getStyleClass().add((row + col) % 2 == 0 ? "light": "dark");

    for (var i = 0; i < 2; i++) {
        var pieceView = new ImageView(pieceImages[i]);
        pieceView.visibleProperty().bind(createBindingForPieceAtPosition(i, row, col));
        cell.getChildren().add(pieceView);
    }

    var wallsInDirections = state.checkAllWalls(new Position(row, col));
    for (var direction : wallsInDirections) {
        switch (direction) {
            case UP -> cell.getStyleClass().add("topwall");
            case RIGHT -> cell.getStyleClass().add("rightwall");
            case DOWN -> cell.getStyleClass().add("bottomwall");
            case LEFT -> cell.getStyleClass().add("leftwall");
        }
    }
    return cell;
}

CSS代码:

.cell.light {
    -fx-background-color: white;
}

.cell.dark {
    -fx-background-color: #F6F6F6;
}

.cell.light:hover, .cell.dark:hover {
    -fx-background-color: #FAFA33;
}

.topwall {
    border-top: solid black;
}

.rightwall {
    border-right: solid black;
}

.bottomwall {
    border-bottom: solid black;
}

.leftwall {
    border-left: solid black;
}

之后的 GUI 图片: result

像这样编辑我的CSS:

.topwall {
    -fx-border-style: solid hidden hidden hidden ;
    -fx-border-color: black;
    -fx-border-width: 5;
}

.rightwall {
    -fx-border-style: hidden solid hidden hidden;
    -fx-border-color: black;
    -fx-border-width: 5;
}

.bottomwall {
    -fx-border-style: hidden hidden solid hidden;
    -fx-border-color: black;
    -fx-border-width: 5;
}

.leftwall {
    -fx-border-style: hidden hidden hidden solid;
    -fx-border-color: black;
    -fx-border-width: 5;
}

现在它们出现了,但每个单元格只显示 1 个边框。

Result

属性 border-topborder-right 等不是有效的 JavaFX CSS 属性。

参考documentation,你使用属性设置边框

selector {
    -fx-border-color: color ;
    -fx-border-width: width ;
}

其中 colorwidth 要么是单个值(分别是 paint 和 size 类型),要么是用空格分隔的四个值,分别代表上、右、下和左边框。

还应注意,在 JavaFX 中通常不会以这种方式使用边框。更常用的方法是使用“嵌套背景”,您可以像这样在所有四个边周围定义一个宽度为 5 的边框:

.cell.light {
    -fx-background: white;
}
.cell.dark {
    -fx-background: #f6f6f6;
}
.cell {
    -fx-background-color: black, -fx-background;
    -fx-background-insets: 0, 5;
}

这通过绘制两个背景来实现,一个覆盖另一个。第一个是黑色,没有插图;第二个由“looked-up 颜色”-fx-background 定义,所有边都有 5 个像素的插图。

我的理解(虽然我没有这方面的直接证据)是嵌套背景方法比使用显式边框表现更好。

不幸的是,完全在外部执行此操作 CSS sheet 非常冗长,因为您必须单独处理所有 16 种可能性(除非我错过了一个聪明的技巧):

.cell.light {
    -fx-background: white;
}
.cell.dark {
    -fx-background: #f6f6f6;
}
.cell {
    -fx-background-color: black, -fx-background;
    -fx-background-insets: 0, 0;
}


.cell.topwall {
    -fx-background-insets: 0, 5 0 0 0;
}
.cell.rightwall {
    -fx-background-insets: 0, 0 5 0 0;
}
.cell.bottomwall {
    -fx-background-insets: 0, 0 0 5 0;
}
.cell.leftwall {
    -fx-background-insets: 0, 0 0 0 5;
}
.cell.topwall.rightwall {
    -fx-background-insets: 0, 5 5 0 0;
}
.cell.topwall.bottomwall {
    -fx-background-insets: 0, 5 0 5 0;
}
.cell.topwall.leftwall {
    -fx-background-insets: 0, 5 0 0 5;
}
.cell.rightwall.bottomwall {
    -fx-background-insets: 0, 0 5 5 0;
}
.cell.rightwall.leftwall {
    -fx-background-insets: 0, 0 5 0 5;
}
.cell.bottomwall.leftwall {
    -fx-background-insets: 0, 0 0 5 5;
}
.cell.topwall.rightwall.bottomwall {
    -fx-background-insets: 0, 5 5 5 0;
}
.cell.topwall.bottomwall.leftwall {
    -fx-background-insets: 0, 5 0 5 5;
}
.cell.topwall.rightwall.leftwall {
    -fx-background-insets: 0, 5 5 0 5;
}
.cell.rightwall.bottomwall.leftwall {
    -fx-background-insets: 0, 0 5 5 5;
}
.cell.topwall.rightwall.bottomwall.leftwall {
    -fx-background-insets: 0, 5;
}

(使用 -fx-border-* 也好不到哪去)。

以编程方式将插图设置为内联样式可能更容易:

.cell.light {
    -fx-background: white;
}
.cell.dark {
    -fx-background: #f6f6f6;
}
.cell {
    -fx-background-color: black, -fx-background;
    -fx-background-insets: 0, 0;
}

然后

int top, right, bottom, left ;
top=right=bottom=left=0 ;
var wallsInDirections = state.checkAllWalls(new Position(row, col));
for (var direction : wallsInDirections) {
    switch (direction) {
        case UP -> top=5;
        case RIGHT -> right=5;
        case DOWN -> bottom=5;
        case LEFT -> left=5;
    }
}

cell.setStyle(String.format("-fx-background-insets: %d %d %d %d;", top, right, bottom, left));