JavaFX之FXML+CSS创建窗体以及透明窗体添加阴影


前言

开通博客园有一段日子了,一直没空也没想好该写点什么。最近正好在做一个桌面程序,初次接触JavaFX,体验下来确实比swing好用不少。索性便记记学习笔记吧,虽然FX好像挺没存在感,没人用的感觉。本人技术有限,悟性不高,学得也很慢。不过 道阻且长,行则将至,写点笔记好日后待查,顺手练练Markdown了。可能不会那么系统,不过尽量详细。

本文目录

1. JavaFX窗体加载
 1.1 传统方式
 1.1 FXML+CSS

2. 透明窗体添加阴影
 2.1 传统方式下
 2.1 FXML+CSS方式下


JavaFX窗体加载

传统方式

一般的,我们有:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class demo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane root = new BorderPane();//底层面板
        Scene scene = new Scene(root,400,400);//设置窗体面板和大小
        primaryStage.initStyle(StageStyle.DECORATED);//设置窗体样式
        primaryStage.setTitle("Demo From"); //设置窗口标题
        primaryStage.getIcons().add(null);//设置窗口图标
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

布局太基础了就不说了,对于窗体样式,有如下几个:

1、DECORATED——白色背景,带有最小化/最大化/关闭等有操作系统平台装饰( 默认)
2、UNDECORATED——白色背景,没有操作系统平台装饰
3、TRANSPARENT——透明背景,没有操作系统平台装饰
4、UTILITY——白色背景,只有关闭操作系统平台装饰
5、UNIFIED——有操作系统平台装饰,消除装饰和内容之间的边框,内容背景和边框背景一致

(对于窗体图标,代码中null代表一个Image对象,不展开说了)


FXML+CSS方式

除了传统方式,使用更多也更方便的是FXML+CSS方式,一般的,我们有:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class demo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        FXMLLoader fxmlLoader = new FXMLLoader("FXML file path");
        Parent root = fxmlLoader.load();
        Scene scene = new Scene(root,400,400);//设置窗体面板和大小
        primaryStage.initStyle(StageStyle.DECORATED);//设置窗体样式
        primaryStage.setTitle("Demo From"); //设置窗口标题
        primaryStage.getIcons().add(null);//设置窗口图标
        primaryStage.setScene(scene);
        primaryStage.getScene().getStylesheets().add("CSS file path");
        primaryStage.show();
    }

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

在这种方式下,在FXML中为控件设置id,在css文件中使用id选择器即可设置不同的样式,用法大致上同于CSS3,主要差别和传统方式如何为控件设置样式参见下一段。
(伪代码不可直接运行)


透明窗体添加阴影

我们先来看看有阴影和无阴影窗体的差别:
JavaFX之FXML+CSS创建窗体以及透明窗体添加阴影_第1张图片

(因博客为白色背景,所以图换成了灰色背景。同时为了方便对比无阴影下额外加了0.3的黑色边框,否则可能看不见)

这里值得注意的是,

1、JavaFX中CSS语法前面是必有“-fx-”否则不会生效,对于使用CSS文件加载也是一样

2、窗体阴影在使用“操作系统平台装饰”的stage样式时是默认自动生成的,无需自己设置,因此,自定义窗体阴影需要使用透明样式(TRANSPARENT)

3、透明窗体添加阴影必须使用StackPane作为底层布局

传统方式下

对于传统方式下,我们有:
        stage.initStyle(StageStyle.TRANSPARENT);
        StackPane root = new StackPane();//底层面板
        Scene scene = new Scene(root);
        stackPane.setStyle(
                "-fx-background-color: rgba(255, 255, 255, 1);" +
                "-fx-effect: dropshadow(gaussian, black, 50, 0, 0, 0);" +
                "-fx-background-insets: 50;"
        );
        scene.setFill(Color.TRANSPARENT);
        stage.setScene(scene);
        stage.show();

不难看出这里同样使用了CSS,只不过不是以文件方式加载,那么对于其他控件,同样可以使用setStyle()方法为其设置样式。


FXML+CSS方式下

其实两种方式大同小异,原理上一样。在此方式下,有:

代码部分

        stage.initStyle(StageStyle.TRANSPARENT);
        StackPane stackPane = new FXMLLoader("FXML file path").load();
        Scene scene = new Scene(stackPane);
        scene.setFill(Color.TRANSPARENT);
        stage.setScene(scene);
        stage.getScene().getStylesheets().add("CSS file path");
        stage.show();

FXML部分



CSS部分

.root{
    -fx-background-color: rgba(255, 255, 255, 1);
    -fx-effect: dropshadow(gaussian, black, 50, 0, 0, 0);
    -fx-background-insets: 50;
}

这里不难看出FXML+CSS方式对于传统方式,本质上是拆分以做到更加简明。
需要注意的是,必须在FXML中设置id或者styleClass,css样式表才可以生效,并且很多属性,既可以在代码里设置,也可以在FXML或者css中设置,比如控件大小。
因此,两种方式完全可以混用,比如使用FXML加载布局,而后直接在代码中设置样式,又或者在代码中设置布局和id,加载css样式表文件,这一切均可以按照自己的需求来选择。


参考文章:https://blog.csdn.net/qq_32571359/article/details/72957307

(本文最后更新于2020.3.10,原创文章,转载请注明)

你可能感兴趣的:(JavaFX之FXML+CSS创建窗体以及透明窗体添加阴影)