这是JavaFX SceneBuilder的错误吗?

问题描述 投票:0回答:1

在 JavaFX SceneBuilder 中,我希望将 Pane 的边框样式设置为仅位于右侧,因此我将以下内容放入 JavaFX CSS 样式框中: -fx-border-style: none Solid none none ,但它确实使整个边框可见。然后我发现,如果我将“none”作为第一个值,则边框将始终是完整的。

有人可以告诉我如何修复它,或者是否有其他方法可以做到这一点?

java javafx scenebuilder
1个回答
1
投票

这似乎是 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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.