我不知道如何设计分隔符的样式.我不理解JavaFX CSS样式website的文档--更具体地说是如何使用子 struct (在本例中是一行).

我是这样创建我的分隔符的:

Separator separator = new Separator(Orientation.HORIZONTAL);
separator.setStyle("-fx-fill: white; -fx-background-color: white; -fx-border-color: null;");

The -fx-fill: white; and -fx-border-color: null; don't do anything. This is how it looks with this styling: Horizontal Separator 这是它没有造型的样子: Horizontal Separator 我希望它看起来只有一行字.

我对垂直分隔符也有同样的问题:

Separator separator = new Separator(Orientation.VERTICAL);
separator.setStyle("-fx-background-color: white; -fx-border-color: null;");

-fx-border-color: null;再一次没有任何作用.这是这个造型的外观:

Vertical Separator

这是它没有造型的样子:

Vertical Separator

我希望它看起来只有一行字.

我的主要代码是:

import java.io.FileNotFoundException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Slider;
import javafx.scene.effect.BoxBlur;
import javafx.scene.input.KeyCombination;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.stage.Stage;

public class Visualisation extends Application {

    private static final int GRID_SIZE = 40;
    private static CheckBox checkBox;
    private static double zoomFactor = 1;
    private static VBox settings = new VBox();
    private static AtomicInteger delay = new AtomicInteger(250);
    private static AtomicBoolean isPaused = new AtomicBoolean(true);

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws FileNotFoundException {

        StackPane root = new StackPane();
        root.setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, javafx.geometry.Insets.EMPTY)));

        Scene scene = new Scene(root, 400, 400);

        Group content = new Group();
        root.getChildren().add(content);
        root.getChildren().add(new Separator(Orientation.HORIZONTAL)); // here I can set horizontal or vertical Seperator
        // root.getChildren().add(new Separator(Orientation.VERTICAL));

        setupSettings(root, stage, content);
        makeZoomable(scene, content);
        makeKeyPresses(stage, scene, content);

        scene.widthProperty().addListener(e -> resetSize(scene, content));
        scene.heightProperty().addListener(e -> resetSize(scene, content));

        stage.setScene(scene);
        stage.setTitle("Visualisation");
        stage.setFullScreen(true);
        stage.setFullScreenExitHint("");
        stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
        stage.show();
    }

    private void makeZoomable(Scene scene, Group content) {
        scene.setOnScroll((ScrollEvent event) -> {
            double deltaY = event.getDeltaY();

            if (deltaY > 0) {
                zoomFactor += 0.01;
            } else {
                zoomFactor -= 0.01;
                if (zoomFactor <= 0) {
                    zoomFactor = 0.01;
                }
            }
            updateTransforms(content);
        });
    }

    private void setupSettings(StackPane root, Stage stage, Group content) {

        checkBox = new CheckBox("Fullscreen");
        checkBox.setStyle("-fx-text-fill: WHITE; -fx-font-size: 20; -fx-font-weight: bold");
        checkBox.fire();
        checkBox.selectedProperty().addListener((observable, oldValue, newValue) -> {
            if (stage.isFullScreen()) {
                stage.setFullScreen(false);
            } else {
                stage.setFullScreen(true);
            }
        });

        Text label = new Text("Speed slider");
        label.setStyle("-fx-fill: WHITE; -fx-font-size: 20");

        Slider slider = new Slider(10, 1000, delay.get());
        slider.setBlockIncrement(100);
        slider.setSnapToTicks(true);
        slider.valueProperty().addListener((observable, oldValue, newValue) -> delay.set(newValue.intValue()));

        VBox speedControler = new VBox();
        speedControler.setAlignment(Pos.CENTER);
        speedControler.getChildren().addAll(label, slider);

        Button button1 = new Button("Back");
        button1.setOnAction(e -> openCloseSettings(content));

        Button button2 = new Button("Exit");
        button2.setOnAction(e -> System.exit(0));

        HBox buttons = new HBox();
        buttons.setAlignment(Pos.CENTER);
        buttons.getChildren().addAll(button1, button2);
        buttons.setSpacing(30);

        settings.setAlignment(Pos.CENTER);
        settings.setMaxWidth(Math.min(root.getWidth(), root.getHeight()));
        settings.getChildren().addAll(checkBox, speedControler, buttons);
        settings.setVisible(false);
        settings.setSpacing(30);
        root.getChildren().add(settings);
    }

    private void makeKeyPresses(Stage stage, Scene scene, Group content) {
        scene.setOnKeyPressed(event -> {
            switch (event.getCode()) {
                case SPACE:
                    if (!settings.isVisible()) {
                        isPaused.set(!isPaused.get());
                    }
                    break;
                case F5:
                    checkBox.fire();
                    break;
                case ESCAPE:
                    openCloseSettings(content);
                    break;
                default:
                    break;
            }
        });
    }

    private static void resetSize(Scene scene, Group root) {
        boolean isPausedRemember = isPaused.get();
        isPaused.set(true);
        root.setLayoutX((scene.getWidth() - root.prefWidth(-1)) / 2);
        root.setLayoutY((scene.getHeight() - root.prefHeight(-1)) / 2);

        double scaleX = scene.getWidth() / root.getBoundsInLocal().getWidth();
        double scaleY = scene.getHeight() / root.getBoundsInLocal().getHeight();
        zoomFactor = Math.min(scaleX, scaleY) - 0.01;
        updateTransforms(root);
        isPaused.set(isPausedRemember);
    }

    private static void updateTransforms(Group root) {
        root.setScaleX(zoomFactor);
        root.setScaleY(zoomFactor);
    }

    private void openCloseSettings(Group content) {
        if (settings.isVisible()) {
            content.setEffect(null);
            settings.setVisible(false);
        } else {
            isPaused.set(true);
            BoxBlur blur = new BoxBlur(20, 20, 2);
            content.setEffect(blur);
            settings.setVisible(true);
        }
    }
}

以下是使用水平分隔符时的外观:

enter image description here

这是垂直分隔符的外观:

enter image description here

这是使用两个分隔符时的外观:

enter image description here

我希望它看起来只像一条线(相同的 colored颜色 和宽度为1;在水平情况下,它看起来像1条灰线,1条白线和1条黑线,在垂直情况下,它看起来像1条灰线,1条白线和1条灰线,在两种情况下都是3的宽度).

我也注意到一件事,如果你算上第三条黑线,水平分隔符可能居中(也许),但垂直分隔符肯定不是.我不知道为什么.我对此感到困惑,因为我的场景集中在放置/添加到Group content的元素上.

setStyle()的答案几乎是完美的,但它有一个问题-阴影仍然存在,这就是为什么差距仍然存在:

enter image description here

推荐答案

默认分隔符样式

Separator的默认样式可以在modena.css文件中找到,该文件位于您的JavaFX发行版的javafx-controlsJAR中.

它是这样的:

.separator:horizontal .line {
    -fx-border-color: -fx-text-box-border transparent transparent transparent,
        -fx-shadow-highlight-color transparent transparent transparent;
    -fx-border-insets: 0, 1 0 0 0;
}
.separator:vertical .line {
    -fx-border-color: transparent transparent transparent -fx-shadow-highlight-color,
        transparent transparent transparent -fx-text-box-border;
    -fx-border-width: 3, 1;
    -fx-border-insets: 0, 0 0 0 1;
}

要更改样式,您需要定义一个自定义样式表并应用它.

默认分隔符呈现为带有插图的边框,因此它们不会占用布局空间,但会呈现到屏幕上.

对于水平分隔符,高度为1的线以-fx-text-box-border色呈现到屏幕上,并且在-fx-shadow-highlight-color中将高度为1的第二行呈现到其正下方的屏幕上,以提供3D样式的外观,当以默认背景 colored颜色 呈现时.因此,水平分隔符的高度为2个像素.

类似地,对于垂直分隔符,宽度为1的线以-fx-text-box-border色渲染到屏幕,并且宽度为1的第二行在-fx-shadow-highlight-color中被渲染到both侧的屏幕上,以在相对于默认背景色渲染时提供3D样式外观.所以垂直分隔符是3个像素宽.

Example: Modifying the 默认分隔符样式

有关该示例的信息:

  • 自定义样式的分隔符删除了为分隔符绘制的模糊阴影线,从而提供了人造3D效果.
  • 该示例更改分隔符中线条的 colored颜色 .
  • 演示了薄分离器和脂肪分离器.
  • 对于脂肪分隔符样式,我们用背景设置替换边框设置.
  • 脂肪分离器调整首选宽度,以满足我们的要求.在本例中,这是在CSS中完成的,但如果您愿意,也可以在Java代码或FXML中设置首选大小.
  • 我们使用线性渐变来设置脂肪分隔符的样式,作为如何定制分隔符样式的进一步示例.

为方便起见,该示例使用内联css样式表来设置分隔符的样式,但您也可以使用外部css样式表来设置它们的样式.

styled separator's screenshot

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.Separator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class SeparatorStylingApp extends Application {
    private static final String CSS =
            """
            data:text/css,
            .styled-separator.separator:horizontal .line {
                -fx-border-color: red transparent transparent transparent,
                    transparent transparent transparent transparent;
                -fx-border-insets: 0, 1 0 0 0;
            }
            .styled-separator.separator:vertical .line {
                -fx-border-color: transparent transparent transparent transparent,
                    transparent transparent transparent lawngreen;
                -fx-border-width: 3, 1;
                -fx-border-insets: 0, 0 0 0 1;
            }

            .fat.styled-separator.separator:horizontal .line {
                -fx-border-color: null;
                -fx-background-color: linear-gradient(to right, papayawhip, crimson);
                -fx-pref-height: 5px;
            }
            .fat.styled-separator.separator:vertical .line {
                -fx-border-color: null;
                -fx-background-color: linear-gradient(to top, darkgreen, palegreen);
                -fx-pref-width: 5px;
            }
            """;

    @Override
    public void start(Stage stage) {
        Separators separators = getSeparators(null);
        Separators fatSeparators = getSeparators("fat");

        VBox layout = new VBox(
                10,
                separators.plainSeparator(),
                separators.styledSeparator(),
                separators.verticalSeparators(),
                fatSeparators.plainSeparator(),
                fatSeparators.styledSeparator(),
                fatSeparators.verticalSeparators()
        );
        layout.setPadding(new Insets(10));

        Scene scene = new Scene(layout);
        scene.getStylesheets().add(CSS);
        stage.setScene(scene);
        stage.show();
    }

    private static Separators getSeparators(String additionalStyleClass) {
        Separator plainSeparator = new Separator();
        Separator styledSeparator = new Separator();
        styledSeparator.getStyleClass().add("styled-separator");
        if (additionalStyleClass != null) {
            styledSeparator.getStyleClass().add(additionalStyleClass);
        }

        Separator plainVerticalSeparator = new Separator(Orientation.VERTICAL);
        Separator styledVerticalSeparator = new Separator(Orientation.VERTICAL);
        styledVerticalSeparator.getStyleClass().add("styled-separator");
        if (additionalStyleClass != null) {
            styledVerticalSeparator.getStyleClass().add(additionalStyleClass);
        }

        HBox verticalSeparators = new HBox(
                30,
                plainVerticalSeparator,
                styledVerticalSeparator
        );
        verticalSeparators.setPadding(new Insets(0, 20, 0, 20));
        verticalSeparators.setPrefHeight(50);

        return new Separators(plainSeparator, styledSeparator, verticalSeparators);
    }

    private record Separators(
            Separator plainSeparator,
            Separator styledSeparator,
            HBox verticalSeparators
    ) {}

    public static void main(String[] args) {
        launch(args);
    }
}

setStyle alternative

你可以通过setStyle来调整一些风格,但不会有那么大的灵活性.

通常,使用前面在此方法中演示的CSS样式表是配置自定义样式的首选且最灵活的方法.

您可以调整查找 colored颜色 值以使线条的 colored颜色 不同,但这是您所能做的全部操作.

separator.setStyle("-fx-text-box-border: blue; -fx-shadow-highlight-color: transparent");`

Css相关问答推荐

不了解重复-线性-渐变 colored颜色 停止

如何在元素上打孔才能看到下面的背景图像?

使用tailwind 将父div限制为其具有溢出的最短子级的高度

靴子,为什么我不能让任何东西正确地排好队?

位置:固定元素只是不固定

如何将动态参数从react tsx文件发送到css

使用 CSS 关键帧动画更改内容

基于高度的容器查询不起作用

如何减少弹性项目之间的差距

如何在 VS Code 中获得 JavaFX CSS 属性的自动完成功能?

在 React 中使用 CSS 动画 onClick()

使用 React JS 和自定义 CSS 创建 Cookie 横幅

为什么 flexbox 中的 在应用居中时不会调整大小?

子组件的css会影响整个页面

使用之前和之后为锚标签添加画笔描边效果

使用 Twitter Bootstrap 使页脚粘在页面底部

使用边距:0 自动;在 Internet Explorer 8 中

IE划掉伪元素CSS?

CSS 否定伪类 :not() 用于父/祖先元素

CSS 外边框