前言
开通博客园有一段日子了,一直没空也没想好该写点什么。最近正好在做一个桌面程序,初次接触JavaFX,体验下来确实比swing好用不少。索性便记记学习笔记吧,虽然FX好像挺没存在感,没人用的感觉。本人技术有限,悟性不高,学得也很慢。不过 道阻且长,行则将至,写点笔记好日后待查,顺手练练Markdown了。可能不会那么系统,不过尽量详细。
本文目录
1. JavaFX窗体加载
1.1 传统方式
1.1 FXML+CSS2. 透明窗体添加阴影
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,主要差别和传统方式如何为控件设置样式参见下一段。
(伪代码不可直接运行)
透明窗体添加阴影
(因博客为白色背景,所以图换成了灰色背景。同时为了方便对比无阴影下额外加了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,原创文章,转载请注明)