前言
開通博客園有一段日子了,一直沒空也沒想好該寫點什么。最近正好在做一個桌面程序,初次接觸JavaFX,體驗下來確實比swing好用不少。索性便記記學習筆記吧,雖然FX好像挺沒存在感,沒人用的感覺。本人技術有限,悟性不高,學得也很慢。不過 道阻且長,行則將至,寫點筆記好日后待查,順手練練Markdown了。可能不會那么系統,不過盡量詳細。
本文目錄
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部分
<StackPane xmlns="http://javafx.com/javafx"
fx:id="root"
xmlns:fx="http://javafx.com/fxml"
prefHeight="680.0" prefWidth="1000.0">
</StackPane>
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,原創文章,轉載請注明)