
【JDK8】迎接 JavaFX 8(1)
【JDK8】JavaScript 引擎 Nashorn 之 jjs << 前情 2014年3月18日Oracle正式釋出Java SE Development Kit 8,應 CodeData 的邀請,特別整理JavaFX 8與JavaFX 2之比較,作為【JDK8】系列之一。 移除各物件對應的Builder類別 JavaFX 8移除各物件對應的Builder類別,最初建議移除的提案,可以參考 Proposal: Deprecate Builders 的內容。 這裡回顧一下JavaFX 2的Builder類別,Builder是JavaFX 2一個特殊功能與語法,以Button類別 (按鈕) 為例,其對應之Builder類別為ButtonBuilder,透過ButtonBuilder類別可精簡程式長度,但程式的撰寫方式與以往的Java程式不同。 ButtonBuilder類別的方法包括:
以ButtonBuilder類別建立按鈕的程式架構如下,首先以create()方法建立ButtonBuilder的實體,最後再以build()方法以ButtonBuilder物件建立Button物件,其間並以上述方法設定按鈕的相關屬性,各方法可為任意順序或省略: Button button = ButtonBuilder.create() .cancelButton(...) .defaultButton(...) .build(); 請參考以下範例示範以ButtonBuilder類別建立按鈕: Image image = new Image( ButtonDemo.class.getResourceAsStream("images/dukeswing.gif")); Scene scene = SceneBuilder.create() .width(250) .height(250) .root( FlowPaneBuilder.create() .hgap(5) .vgap(5) .padding(new Insets(5, 5, 5, 5)) .alignment(Pos.CENTER) .children( ButtonBuilder.create() // 建立一般按鈕 .text("Plain Text") // 設定按鈕文字 .prefWidth(100) // 設定按鈕最佳寬度 .prefHeight(20) // 設定按鈕的最佳高度 .build(), ButtonBuilder.create() // 建立圖像按鈕 .text("Image Button") .graphic(new ImageView(image)) // 設定按鈕所使用的圖像 .contentDisplay(ContentDisplay.TOP) // 設定圖像與文字間的相對位置 .prefWidth(100) .build(), ... ) .build() ) .build(); ... Lambda Expression Lambda Expression為Java S.E. 8.0新增的一項語言描述方式,其語法如下: (argument) -> (body) Lambda Expression是一種匿名函式 (Anonymous Function),沒有Method Declaration (方法宣告),亦不需要Modifier (修飾詞) 與Return Value Declaration (回傳值宣告) 等,因此程式更為精簡。 以下是一些簡單的例子: (int a, int b) -> {return a + b;} () -> System.out.println("..."); (String value) -> {return value;} 我們可以將Lambda Expression運用於JavaFX 8的事件 (Event) 處理上,讓處理事件的方式更為簡單。在這之前,先來回顧JavaFX 2處理事件的程式架構。 JavaFX 2處理事件的方式,不像以往Java以不同的Listener介面處理各類事件,JavaFX 2僅以EventHandler介面處理各類事件,且介面僅提供handle()方法,並以事件類型 (Event Type) 定義各類事件,其基礎類別為javafx.event.Event,繼承自Event類別的事件類別分別如下,其中較特殊的是手勢與觸控事件:
JavaFX 2處理事件的第一種方式是以物件的setOnXXX()方法設定處理事件的Event Handler函式,其語法如下,其中[Event_TYPE]為上述之事件類別: [object].setOnXXX(new EventHandler() { @Override public void handle([Event_TYPE] e) { ... } }); 以按鈕的動作事件為例,其設定Event Handler函式的方法為setOnAction()、事件類別為ActionEvent: Button button = new Button(); button.setOnAction(new EventHandler() { @Override public void handle(ActionEvent e) { ... } }); 亦可使用建立類別的方式處理: Button button = new Button(); button.setOnAction(onActionEventHandler); ... EventHandler onActionEventHandler = new EventHandler() { @Override public void handle(ActionEvent e) { ... } }; 透過Java S.E. 8.0的Lambda Expression可將上述程式精簡如下,省略EventHandler介面的描述: Button button = new Button(); button.setOnMouseMoved((ActionEvent e) -> { ... }); 或以建立類別的方式處理: Button button = new Button(); button.setOnAction(onActionEventHandler); ... EventHandler onActionEventHandler = (EventHandler)(ActionEvent e) -> { ... }; 更進一步可依賴編譯器的型態推斷 (Type Inference),讓程式更精簡: Button button = new Button(); button.setOnAction(event -> { ... }); JavaFX 2處理事件的第二種方式是以物件的addEventHandler()方法註冊事件的Event Handler,其語法如下,其中[eventType]代表事件類型、[Event_TYPE]為前述之事件類別: [object].addEventHandler([eventType], new EventHandler() { @Override public void handle([Event_TYPE] e) { ... } }); 以按鈕的動作事件為例,其事件類型為ActionEvent.ACTION、事件類別為ActionEvent,註冊Event Handler的程式架構如下: Button button = new Button(); button.addEventHandler(ActionEvent.ACTION, new EventHandler() { @Override public void handle(ActionEvent e) { ... } } ); 透過Lambda Expression可將上述程式精簡如下: Button button = new Button(); button.addEventHandler(ActionEvent.ACTION, (ActionEvent e) -> { ... }; JavaFX 2處理事件的第三種方式是以物件的addEventFilter()方法註冊事件的Event Filter,其語法如下,與Event Handler幾乎一樣: [object].addEventFilter([eventType], new EventHandler() { @Override public void handle([Event_TYPE] e) { ... } }); 以按鈕的動作事件為例,註冊Event Filter的程式架構如下: Button button = new Button(); button.addEventFilter(ActionEvent.ACTION, new EventHandler() { @Override public void handle(ActionEvent e) { ... } } ); 透過Lambda Expression可將上述程式精簡如下: Button button = new Button(); button.addEventFilter(ActionEvent.ACTION, (ActionEvent e) -> { ... }; Modena主題樣式 JavaFX 2預設外觀主題 (Theme) 稱為Caspian,例如以下為選單之Caspian主題樣式: JavaFX 8新增Modena主題,可使用javafx.application.Application抽象類別新增的setUserAgentStylesheet()方法設定,其中參數為以下之主題樣式:
例如: // 設定Modena主題 setUserAgentStylesheet(STYLESHEET_MODENA); // 設定Caspian主題 setUserAgentStylesheet(STYLESHEET_CASPIAN); 以下範例以單選選單項目 (Radio Menu Item) 控制主題樣式,可分別選取Modena與Caspian主題。 JavaFX Scene Builder 2.0 Oracle為加速JavaFX圖形介面的開發,2014/05/13 Oracle正式發表JavaFX Scene Builder 2.0,可至以下網址下載: JavaFX Scene Builder如同NetBeans與JBuilder IDE一般,藉由拖曳的方式配置物件,待完成配置之後,並儲存成FXML格式檔案,此檔案以XML描述物件配置,再交由JavaFX程式處理,因此可減少直接以JavaFX撰寫配置物件程式的困難度。 JavaFX Scene Builder 2.0新增JavaFX Theme預覽功能,可點選「Preview」→「JavaFX Theme」選單選擇不同的主題,包括:
待完成物件配置之後,點選「File」→「Save」選單儲存為FXML檔案,其內容如下所示: <?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.net.*?> <?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> <GridPane alignment="CENTER" styleClass="root" hgap="10.0" vgap="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxapplication.JavaFXController"> <padding> <Insets bottom="25.0" left="25.0" right="25.0" top="25.0" /> </padding> <Text id="welcome-text" text="Welcome to JavaFX" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.rowIndex="0" /> <Label text="User Name:" GridPane.columnIndex="0" GridPane.rowIndex="1" /> <TextField GridPane.columnIndex="1" GridPane.rowIndex="1" /> <Label text="Password:" GridPane.columnIndex="0" GridPane.rowIndex="2" /> <PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="2" /> <HBox alignment="BOTTOM_RIGHT" spacing="10.0" GridPane.columnIndex="1" GridPane.rowIndex="4"> <Button fx:id="button" text="Login" /> </HBox> </GridPane> 【參考資料】 |