JavaFX定義各類別的CSS樣式,各樣式之屬性可參考JavaFX CSS Reference Guide。
以Layout Pane為例,JavaFX分別定義以下各Layout Pane類別的CSS樣式屬性。
FlowPane類別:
- -fx-alignment:設定Flow Pane水平與垂直對齊方式。
- -fx-orientation:設定Flow Pane的配置方向。
- -fx-hgap:設定Flow Pane物件間的水平間距。
- -fx-vgap:設定Flow Pane物件間的垂直間距。
- -fx-column-halignment:當為垂直配置時,設定其直行中各物件的水平對齊方式。
- -fx-row-valignment:當為水平配置時,設定其橫列中各物件的垂直對齊方式。
- -fx-alignment:設定Grid Pane水平與垂直對齊方式。
- -fx-hgap:設定Grid Pane物件間的水平間距。
- -fx-vgap:設定Grid Pane物件間的垂直間距。
- -fx-grid-lines-visible:設定是否顯示Grid Pane的格線。
- -fx-alignment:設定HBox水平與垂直對齊方式。
- -fx-fill-height:設定是否調整各物件的高度為其最佳高度。
- -fx-spacing:設定HBox中各物件間的水平間距。
- -fx-alignment:設定Stack Pane水平與垂直對齊方式。
- -fx-alignment:設定Tile Pane水平與垂直對齊方式。
- -fx-orientation:設定Tile Pane的配置方向。
- -fx-hgap:設定Tile Pane物件間的水平間距。
- -fx-vgap:設定Tile Pane物件間的垂直間距。
- -fx-pref-columns:設定Tile Pane最佳直行數目。
- -fx-pref-rows:設定Tile Pane最佳橫列數目。
- -fx-pref-tile-height:設定每一Tile的最佳高度。
- -fx-pref-tile-width:設定每一Tile的最佳寬度。
- -fx-alignment:設定VBox水平與垂直對齊方式。
- -fx-fill-width:設定是否調整各物件的寬度為其最佳寬度。
- -fx-spacing:設定VBox中各物件間的垂直間距。
第一種方式是將樣式定義於CSS檔案中,以CSS檔案定義樣式的優點在於,JavaFX程式在執行階段只需讀取CSS檔案,則可設定JavaFX中各物件的樣式,一旦樣式變更,僅需修改CSS檔案,不需修改JavaFX程式。
請參考以下範例示範以CSS檔案設定Border Pane與背景樣式,CSS檔案 (LayoutPane.css) 的內容如下,可將此檔案與JavaFX程式檔案置於同一目錄中。由於JavaFX並沒有定義Border Pane的CSS樣式,因此在CSS檔案中沿用Region類別的CSS樣式,分別設定背景顏色、背景圖像、是否重複顯示背景圖像、背景圖像位置等,其中pane在CSS語法中稱為CSS選取器 (CSS Selector):
.pane { -fx-background-color: #abffff; -fx-background-image: url("images/javafx.jpg"); -fx-background-repeat: no-repeat; -fx-background-position: center; } |
待完成CSS檔案設定之後,在JavaFX程式中,以下列方式讀取CSS檔案內容,則完成CSS樣式的設定。首先以Scene類別的getStylesheets().add()方法讀取CSS檔案,以上述範例為例,由於CSS檔案與JavaFX程式檔案置於同一目錄之中,因此其讀取方式如下,其中borderpanedemo代表套件 (Package) 名稱:
// 設定Scene的Layout Pane為BorderPane Scene scene = new Scene(borderpane); // 讀取CSS檔案內容 scene.getStylesheets().add("borderpanedemo/LayoutPane.css"); ... |
接著以BorderPane類別的getStyleClass().add()或getStyleClass().addAll()方法,設定其CSS樣式為CSS檔案中所定義的pane選取器:
BorderPane borderpane = new BorderPane(); // 設定標籤的CSS樣式為CSS檔案中的pane選取器 borderpane.getStyleClass().add("pane"); ... |
如此則完成CSS樣式的設定。
【執行結果】
第二種方式與第一種方式相似,同樣是將標籤樣式定義於CSS檔案中,其差異只在於讀取CSS檔案容的方式不同。請參考以下範例示範以CSS檔案設定Flow Pane與背景樣式,CSS檔案(LayoutPane.css)的內容如下,分別設定pane與flowpane選取器:
.pane { -fx-background-color: #abffff; -fx-background-image: url("images/javafx.jpg"); -fx-background-repeat: no-repeat; -fx-background-position: center; } .flowpane { -fx-padding: 5.0 5.0 5.0 5.0; -fx-hgap: 5; -fx-vgap: 5; -fx-alignment: center; } |
待完成CSS檔案設定之後,在JavaFX程式中,以下列方式讀取CSS檔案內容,則完成CSS樣式的設定,所不同的是其讀取CSS檔案內容的方式,同樣以Scene類別的getStylesheets().add()方法讀取CSS檔案,但其內容與前述範例稍有不同,其中FlowPaneDemo代表範例之類別名稱:
// 設定Scene的Layout Pane為FlowPane Scene scene = new Scene(flowpane); // 讀取CSS檔案內容 scene.getStylesheets().add( FlowPaneDemo.class.getResource("LayoutPane.css").toExternalForm()); ... |
或是以下的方式:
// 設定Scene的Layout Pane為FlowPane Scene scene = new Scene(flowpane); // 讀取CSS檔案內容 scene.getStylesheets().add( getClass().getResource("LayoutPane.css").toExternalForm()); ... |
由於CSS檔案分別設定pane與flowpane選取器,因此接著以FlowPane類別的getStyleClass().addAll()方法,設定其CSS樣式為CSS檔案中所定義的pane與flowpane選取器:
FlowPane flowpane = new FlowPane(); // 設定標籤的CSS樣式為CSS檔案中的pane與flowpane選取器 flowpane.getStyleClass().addAll("pane", "flowpane"); ... |
如此則完成CSS樣式的設定。
【執行結果】
此外,針對GUI物件,則有以下處理CSS樣式的方法。
以標籤 (Label) 為例,JavaFX定義以下有關標籤的CSS樣式:
- -fx-alignment:設定標籤水平與垂直的對齊方式。
- -fx-content-display:設定圖像與文字間的相對位置。
- -fx-ellipsis-string:設定標籤文字的省略符號。
- -fx-font:設定文字字型。
- -fx-font-family:設定文字字體。
- -fx-font-size:設定文字大小。
- -fx-font-style:設定文字樣式。
- -fx-font-weight:設定字體粗細。
- -fx-graphic:設定標籤所使用的圖像。
- -fx-graphic-text-gap:設定圖像與文字間的間距。
- -fx-label-padding:設定標籤四周的間距。
- -fx-text-alignment:設定標籤文字的對齊方式。
- -fx-text-fill:設定標籤文字的顏色。
- -fx-underline:是否設定底線。
- -fx-wrap-text:設定當標籤文字長度超過Layout Pane的寬度時,是否自動換行。
Label label1 = new Label("..."); // 以分號隔開所有的CSS樣式 label1.setStyle("-fx-font-family: Verdana; -fx-font-size: 10px; -fx-font-style: italic; -fx-font-weight: bold; -fx-text-alignment: left; -fx-text-fill: #FF0000; -fx-wrap-text: true;"); ... |
【執行結果】
第二種方式是將CSS樣式定義於CSS檔案中,以CSS檔案定義樣式的優點在於,JavaFX程式在執行階段只需讀取CSS檔案,則可設定JavaFX中各物件的樣式,且一旦樣式變更,也僅需修改CSS檔案,不需修改JavaFX程式。
請參考以下範例示範以CSS檔案設定標籤的樣式,CSS檔案 (Label.css) 的內容如下,可將此檔案與JavaFX程式檔案置於同一目錄中。其中root與label在CSS語法中稱為CSS選取器 (CSS Selector):
root { display: block; } .root { -fx-background-image: url("images/javafx.jpg"); } .label { -fx-font-family: Verdana; -fx-font-size: 10px; -fx-font-style: italic; -fx-font-weight: bold; -fx-text-alignment: left; -fx-text-fill: #FF0000; -fx-wrap-text: true; -fx-graphic: url("images/dukeswing.gif"); } |
上述設定除了示範如何設定標籤的相關文字樣式之外,並示範如何設定背景與標籤所使用的圖像。待完成CSS檔案設定之後,在JavaFX程式中,以下列方式讀取CSS檔案內容,則完成CSS樣式的設定。首先以Scene類別的getStylesheets().add()方法讀取CSS檔案,其中labeldemo代表範例之套件 (Package) 名稱:
// 設定Scene的Layout Pane為HBox Scene scene = new Scene(hbox); // 讀取CSS檔案內容 scene.getStylesheets().add("labeldemo/Label.css"); ... |
接著以Label類別的getStyleClass().add()或getStyleClass().addAll()方法,設定標籤的CSS樣式為CSS檔案中所定義的root與label選取器 (此段程式亦可省略):
Label label1 = new Label("..."); // 設定標籤的CSS樣式為CSS檔案中的root與label選取器 label1.getStyleClass().addAll("root", "label"); ... |
【執行結果】
【參考資料】
[1] 黃嘉輝,深入研究JavaFX 2。
[2] 黃嘉輝,深入研究Java Swing。
[3] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[4] JavaFX:http://www.oracle.com/technetwork/java/javafx
[5] JavaFX 2.2 API Specification.
[6] Java Platform, Standard Edition 7 API Specification.
[7] JavaFX CSS Reference Guide.
[7] JavaFX CSS Reference Guide.
© Chia-Hui Huang
請問一下最後一段"接著以Label類別的getStyleClass().add()或getStyleClass().addAll()方法,設定標籤的CSS樣式為CSS檔案中所定義的root與label選取器 (此段程式亦可省略):" 為何label1.getStyleClass().addAll("root", "label"); 可以省略? 一般不是要設定 node 和 CSS selector 對應關係不是嗎? "深入研究 JavaFX 2" 一書中Example 4-16 和 Example 3-24 使用差別是在哪裡?
回覆刪除Dear uddhava您好
刪除謝謝你的詢問,Example 4-16 和 Example 3-24 並無差別,差別在於兩者CSS的設定,Example 4-16 分別設定.root 和.text,因此程式中使用text1.getStyleClass().addAll("root", "text");,Example 3-24分別設定.pane 和.flowpane,因此程式中使用flowpane.getStyleClass().addAll("pane", "flowpane");
至於"(此段程式亦可省略)",因為之前已經以scene.getStylesheets().add("labeldemo/Label.css");,其實這樣的設定已經足夠,所以label1.getStyleClass().addAll("root", "label");可以省略
感謝你
Leo