在 JavaFX SceneBuilder 中,我希望将 Pane 的边框样式设置为仅位于右侧,因此我将以下内容放入 JavaFX CSS 样式框中: -fx-border-style: none Solid none none ,但它确实使整个边框可见。然后我发现,如果我将“none”作为第一个值,则边框将始终是完整的。
有人可以告诉我如何修复它,或者是否有其他方法可以做到这一点?
这似乎是 JavaFX 21 中 CSS 边框处理的一个错误。这不是 SceneBuilder 或 FXML 或 JavaFX 核心边框逻辑中的问题。
正如詹姆斯在评论中指出的:
实现(如果顶部边框设置为“无”,则无法正常工作)和文档(未描述边框样式的四个不同边的四个值的集合)似乎都有错误。
您可能希望就此提交错误报告。如果您这样做,您可以链接回此问题并向此答案添加评论(或编辑它)以添加对相关错误报告的引用。
问题是,如果您在 CSS 规则中指定所有四种边框样式 并且第一个边框样式设置为
none
,则边框样式不会生效 -> 所有边框都会显示。
复制问题
下面的代码复制了该问题(在 JavaFX 21 上测试)。
第一个框渲染不正确,显示所有四个边框,而只应显示右边框。
-fx-border-style: none solid none none;
第二个框渲染正确,顶部和右侧边框显示,而其他边框不显示。
-fx-border-style: solid solid none none;
第三个框渲染正确,仅显示右边框。然而,这是通过代码而不是 CSS 实现的。作为解决您的问题的方法,您可以在代码中编写边框样式,而不是使用 CSS。
Border codedBorder = new Border(
new BorderStroke(
Color.BLACK, Color.RED, Color.GREEN, Color.BLUE,
BorderStrokeStyle.NONE, BorderStrokeStyle.SOLID, BorderStrokeStyle.NONE, BorderStrokeStyle.NONE,
CornerRadii.EMPTY,
new BorderWidths(10, 8, 6, 4),
Insets.EMPTY
)
);
示例代码:BrokenBorders.java
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class BrokenBorders extends Application {
private static final String CSS = "data:text/css,";
private static final String CUSTOM_BORDER_CSS = CSS + // language=CSS
"""
.broken-border {
-fx-border-style: none solid none none;
-fx-border-color: black red green blue;
-fx-border-width: 10 8 6 4;
-fx-background-color: lightgreen;
}
.working-border {
-fx-border-style: solid solid none none;
-fx-border-color: black red green blue;
-fx-border-width: 10 8 6 4;
-fx-background-color: lightblue;
}
.root {
-fx-font-size: 40px;
}
""";
@Override
public void start(Stage stage) {
stage.setScene(new Scene(createLayout()));
stage.show();
}
private static VBox createLayout() {
StackPane brokenBorderedPane = new StackPane(new Label("1"));
brokenBorderedPane.getStyleClass().add("broken-border");
brokenBorderedPane.setPrefSize(100, 100);
StackPane workingBorderedPane = new StackPane(new Label("2"));
workingBorderedPane.getStyleClass().add("working-border");
workingBorderedPane.setPrefSize(100, 100);
StackPane codedBorderPane = new StackPane(new Label("3"));
Border codedBorder = new Border(
new BorderStroke(
Color.BLACK, Color.RED, Color.GREEN, Color.BLUE,
BorderStrokeStyle.NONE, BorderStrokeStyle.SOLID, BorderStrokeStyle.NONE, BorderStrokeStyle.NONE,
CornerRadii.EMPTY,
new BorderWidths(10, 8, 6, 4),
Insets.EMPTY
)
);
codedBorderPane.setBackground(Background.fill(Color.LIGHTPINK));
codedBorderPane.setBorder(codedBorder);
codedBorderPane.setPrefSize(100, 100);
VBox layout = new VBox(
10,
brokenBorderedPane,
workingBorderedPane,
codedBorderPane
);
layout.getStylesheets().add(CUSTOM_BORDER_CSS);
layout.setPadding(new Insets(10));
return layout;
}
public static void main(String[] args) {
launch();
}
}