JavaFX入門:簡單Demo-學習NetBeans開發平台


零、 最終目標

通過兩種方式(純代碼控制、FXML),實現一個簡單的登錄界面:

 
Paste_Image.png

涉及到的控件:
文本(Text,動態顯示內容)、標簽(Label,顯示文本)、文本域(TextField,用戶交互輸入)、按鈕(Button,登錄點擊)

一、 控件通過Code動態添加實現方法

1、 新建項目

新建JavaFXLoginDemo項目,具體新建方法參見前篇:
JavaFX開發環境:NetBeans開發環境搭建

完成項目新建后,進入開發正題。

入口參數:

public class JavaFXLoginDemo extends Application { @Override public void start(Stage primaryStage) { } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } 
2、 布局方式

JavaFX的UI控件均擺放在Scene上,一般通過增加控制布局的Panel,並將實際的UI擺放在布局Panel上,有點類似於Android的布局方式。Panel有多種樣式,包括了行、列、棧等等,如BorderPaneGridPaneHboxVBox等等。
本文將使用GridPane進行布局。

GridPane grid = new GridPane();//網格式布局,由行列網格控制 grid.setAlignment(Pos.CENTER);//對齊方式,默認靠左對齊,當前設置居中對齊 grid.setHgap(10);//設置水平間隔 grid.setVgap(10);//設置垂直間隔 grid.setPadding(new Insets(25, 25, 25, 25));//設置Padding,順序是:上、右、下、左 Scene scene = new Scene(grid, 300, 275);//新建Scene,並將網格式Panel置於其中 primaryStage.setScene(scene);//設置場景 primaryStage.show(); 
3、 添加控件
        Text scenetitle = new Text("歡迎標題"); //scenetitle.setFont(Font.font("Times New Roman", FontWeight.NORMAL, 20)); grid.add(scenetitle, 0, 0, 2, 1); //創建Label對象,放到第0列,第1行 Label userName = new Label("用戶名:"); grid.add(userName, 0, 1); //創建文本輸入框,放到第1列,第1行 TextField userTextField = new TextField(); grid.add(userTextField, 1, 1); Label pw = new Label("密 碼:"); grid.add(pw, 0, 2); PasswordField pwBox = new PasswordField(); grid.add(pwBox, 1, 2); Button btn = new Button("登錄"); HBox hbBtn = new HBox(10); hbBtn.setAlignment(Pos.BOTTOM_RIGHT); hbBtn.getChildren().add(btn);//將按鈕控件作為子節點 grid.add(hbBtn, 1, 4);//將HBox pane放到grid中的第1列,第4行 final Text actiontarget = new Text();//增加用於顯示信息的文本 grid.add(actiontarget, 1, 6); 
4、 添加處理事件

只有一個按鈕需要事件處理:

        btn.setOnAction(new EventHandler<ActionEvent>() {//注冊事件handler @Override public void handle(ActionEvent e) { actiontarget.setFill(Color.FIREBRICK);//將文字顏色變成 firebrick red actiontarget.setText("登錄中..."); } }); 
5、 添加樣式CSS

步驟一:新建CSS文件:
在包上右擊:


 
Paste_Image.png
 
Paste_Image.png

輸入文件名Login.css,完成樣式表文件的創建:

 
Paste_Image.png

樣式表中定義的內容,主要用在控件的樣式控制上,需要在UI中應用。樣式表需要應用到Root容器中:

scene.getStylesheets().add(JavaFXLoginDemo.class.getResource("Login.css").toExternalForm()); 

設置后,將會在JavaFXLoginDemo.class相對路徑下尋找給出的樣式表Login.css,並應用到scene中。
步驟二:添加一張背景圖,到當前包路徑下:

 
Paste_Image.png

步驟三:添加CSS樣式控制

//根元素樣式布局,設置背景圖 .root { -fx-background-image: url("background.jpg"); } //標簽控件樣式 .label { -fx-font-size: 12px; -fx-font-weight: bold; -fx-text-fill: #333333; -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 ); } //給Button增加樣式 .button { -fx-text-fill: white; -fx-font-family: "Arial Narrow"; -fx-font-weight: bold; -fx-background-color: linear-gradient(#61a2b1, #2A5058); -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.6) , 5, 0.0 , 0 , 1 ); } .button:hover { -fx-background-color: linear-gradient(#2A5058, #61a2b1); } //增加文本效果 #welcome-text { -fx-font-size: 32px; -fx-fill: #818181; -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7) , 6, 0.0 , 0 , 2 ); } //登錄點擊事件顯示效果 #actiontarget { -fx-fill: FIREBRICK; -fx-font-weight: bold; -fx-effect: dropshadow( gaussian , rgba(255,255,255,0.5) , 0,0,0,1 ); } 

注意,最后兩個是采用了CSS中的ID控制樣式,而非Label、Button中針對類型設置的樣式,因此需要給目標控件增加ID規則:

        scenetitle.setId("welcome-text"); actiontarget.setId("actiontarget"); 

☆☆☆ 中文字體庫應用

任何事情,涉及到了中文之后,字體庫使用有點麻煩。
(1)新建文件夾,在當前包下建立resources/fonts,如圖所示:

 
Paste_Image.png

將字體庫粘貼進去,一般是ttf文件,Windows常用,Mac可以用,Linux也是兼容的。我粘貼的是微軟雅黑和粗體版,在Windows操作系統的系統盤下Windows/Fonts目錄下。
(2)增加fonts.mf文件
使用“文件”選項卡查看工程:


 
Paste_Image.png

fonts.mf內容:

msyh=/javafxlogindemo/resources/fonts/msyh.ttf msyhbd=/javafxlogindemo/resources/fonts/msyhbd.ttf hwxk=/javafxlogindemo/resources/fonts/STXINGKA.TTF hwcy=/javafxlogindemo/resources/fonts/STCAIYUN.TTF 

hwcy:


 
Paste_Image.png

hwxk:


 
Paste_Image.png

"="前面,是項目使用時的字體名稱,即font-family,后面是字體庫文件的路徑。
(3)fonts.mf需要在打包時放到jar包的META-INF目錄下,因此需要配置NetBeans工程的build.xml文件內容:

NetBeans工程使用Ant管理項目,配置的build.xml文件,根文件在工程根目錄下,具體配置文件在nbproject目錄下的build-impl.xml文件中。
在build.xml中增加如下內容:

    <target name="-post-compile"> <mkdir dir="${build.classes.dir}/META-INF"/> <copy todir="${build.classes.dir}/META-INF" file="fonts.mf"/> </target> 

完成之后,運行一下項目,在項目目錄的dist目錄下,可以看到打包的jar包,用壓縮文件查看器打開(WinRAR):

 
Paste_Image.png
 
Paste_Image.png

包含了配置文件和字體庫文件。
(4)code中使用:

import javafx.scene.text.Font; Font font = Font.font("hwcy", 32);//字體,尺寸,注意不能使用加粗,即FontWeight 
 
Paste_Image.png

(5)在CSS樣式文件中使用:

//增加文本效果 #welcome-text { -fx-font-size: 32px; -fx-font-family: "hwcy"; -fx-fill: #818181; -fx-effect: innershadow( three-pass-box , rgba(0,0,0,0.7) , 6, 0.0 , 0 , 2 ); } 

注意,-fx-font-weight: bold;加粗不能一起使用,會使字體失效。

經過上述的配置,中文字體也能夠輕松走起啦。

6、 完成編碼,啟動項目,運行測試。

二、 FXML實現界面

NetBeans實現方法
1、 新建工程JavaFXLoginFXMLDemo:

與前一種方法新的工程種類稍有區別,這里選擇JavaFX FXML應用程序

 
Paste_Image.png
 
Paste_Image.png

對比一下工程結構,FXML工程多了一些FXML文件和控制器文件:

 
Paste_Image.png

新建工程后,立刻運行:

 
Paste_Image.png

代碼也稍有區別,FXML文件中定義了控件和控制器映射關系等等:

<?xml version="1.0" encoding="UTF-8"?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="javafxloginfxmldemo.FXMLDocumentController"> <children> <Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" /> <Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" /> </children> </AnchorPane> 

默認生成的FXML樣例界面文件中,根容器是一個AnchorPane:

AnchorPane布局面板可錨定節點於面板的頂、底、左邊、右邊或中間。當窗口尺寸調整時,相應節點維護它們相對於錨點的位置。節點可被錨定於多個位置,多個節點也可錨定於同一個位置。

在后面,將要修改實際的布局容器。

控制器Controller定義了事件處理方法:

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package javafxloginfxmldemo; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label; /** * * @author guorui.he */ public class FXMLDocumentController implements Initializable { @FXML private Label label; @FXML private void handleButtonAction(ActionEvent event) { System.out.println("You clicked me!"); label.setText("Hello World!"); } @Override public void initialize(URL url, ResourceBundle rb) { // TODO } } 

主文件內,與之前的純代碼實現基本類似,但是加載頁面的機制稍有不同,這時通過FXML文件加載,搞過Android的人很熟悉:

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package javafxloginfxmldemo; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; /** * * @author guorui.he */ public class JavaFXLoginFXMLDemo extends Application { @Override public void start(Stage stage) throws Exception { //通過fxml的UI布局文件加載實際的界面內容 Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } } 

由於默認文件名定義的比較弱,我們要自己改一下文件名,這樣才能更清晰的展示:

 
Paste_Image.png

注意不要忘記修改控制器和FXML的映射,以及主類加載的FXML界面名稱。

2、在FXML文件中,編寫界面內容:
<?xml version="1.0" encoding="UTF-8"?> //整理引入包 <?import java.net.*?> <?import javafx.geometry.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <?import javafx.scene.text.*?> //編寫界面 <GridPane xmlns:fx="http://javafx.com/fxml" fx:controller="javafxloginfxmldemo.FXMLLoginDemoDocumentController" alignment="center" hgap="10" vgap="10"> <padding> <Insets top="25" right="25" bottom="10" left="25"/> </padding> <Text text="歡迎登錄FXML Demo系統" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/> <Label text="用戶名:" GridPane.columnIndex="0" GridPane.rowIndex="1"/> <TextField GridPane.columnIndex="1" GridPane.rowIndex="1"/> <Label text="密 碼:" GridPane.columnIndex="0" GridPane.rowIndex="2"/> <PasswordField fx:id="passwordField" GridPane.columnIndex="1" GridPane.rowIndex="2"/> <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="1" GridPane.rowIndex="4"> <Button text="登錄" /> </HBox> <Text fx:id="actiontarget" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="RIGHT" GridPane.rowIndex="6"/> </GridPane> 

此時,沒有添加事件處理,可以試運行:

 
Paste_Image.png

大致內容都在了,但是沒有樣式,沒有登錄按鈕點擊處理事件。

3、 添加處理事件:

方法一:使用Java處理

//給Button增加一個事件處理 <Button text="登錄" onAction="#handleSubmitButtonAction"/> 

添加之后,會報錯:

 
Paste_Image.png

需要在控制器中為其添加事件處理:

 
Paste_Image.png

會自動的在控制器內添加處理程序:

package javafxloginfxmldemo; import java.net.URL; import java.util.ResourceBundle; import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.control.Label; import javafx.scene.control.PasswordField; import javafx.scene.text.Text; /** * * @author guorui.he */ public class FXMLLoginDemoDocumentController implements Initializable { private Label label; @FXML private PasswordField passwordField; @FXML private Text actiontarget; @Override public void initialize(URL url, ResourceBundle rb) { // TODO } @FXML private void handleSubmitButtonAction(ActionEvent event) { actiontarget.setText("登錄中..."); } } 

@FXML注解,可以刪除,最好保留,閱讀方便。
添加好處理事件后,點擊登錄按鈕,就會有反應了:

 

 
Paste_Image.png

方法二.1:使用內置JS腳本處理

 

<?xml version="1.0" encoding="UTF-8"?> <?language javascript?> 

添加腳本聲明。
修改Button的事件處理方法(局部代碼)

<GridPane xmlns:fx="http://javafx.com/fxml" fx:controller="javafxloginfxmldemo.FXMLLoginDemoDocumentController" alignment="center" hgap="10" vgap="10"> <!-- 腳本處理代碼 --> <fx:script> function handleSubmitButtonAction() { actiontarget.setText("Calling the JavaScript"); } </fx:script> <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="1" GridPane.rowIndex="4"> <Button text="登錄" onAction="handleSubmitButtonAction(event);"/> </HBox> <Text fx:id="actiontarget" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="RIGHT" GridPane.rowIndex="6"/> </GridPane> 

點擊之后,調用腳本:

 
Paste_Image.png

腳本語言提供與JSR 223規范兼容的引擎即可。例如JavaScript、Groovy、Jython、Clojure。

方法二.2:使用外置JS腳本處理
腳本可以放在外部,正確引用即可:

 
Paste_Image.png
 
Paste_Image.png
 
Paste_Image.png
function handleSubmitButtonAction() { actiontarget.setText("Calling the Outline JavaScript"); } 

同時,在FXML中引入腳本:

<GridPane xmlns:fx="http://javafx.com/fxml" fx:controller="javafxloginfxmldemo.FXMLLoginDemoDocumentController" alignment="center" hgap="10" vgap="10"> <fx:script source="FXMLJSLoginDemo.js"/> <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="1" GridPane.rowIndex="4"> <Button text="登錄" onAction="handleSubmitButtonAction(event);"/> </HBox> <Text fx:id="actiontarget" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="RIGHT" GridPane.rowIndex="6"/> </GridPane> 

試運行,得到結果:

 
Paste_Image.png
4、 添加樣式控制:

添加樣式表文件、字體庫文件、背景圖片,增加fonts.mf配置文件,修改build.xml等等,與前面純代碼開發基本一致,注意路徑名(包名有變化)。
在FXML中引入樣式表,並給特定的控件增加id,以便於CSS樣式篩選器能夠正確篩選適配:

<GridPane xmlns:fx="http://javafx.com/fxml" fx:controller="javafxloginfxmldemo.FXMLLoginDemoDocumentController" alignment="center" hgap="10" vgap="10" styleClass="root" > <stylesheets> <URL value="@Login.css" /> </stylesheets> <Text id="welcome-text" text="歡迎登錄FXML Demo系統" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/> <Text id="actiontarget" fx:id="actiontarget" GridPane.columnIndex="0" GridPane.columnSpan="2" GridPane.halignment="RIGHT" GridPane.rowIndex="6"/> </GridPane> 
5、 最終運行結果:
 
Paste_Image.png

FXML方式開發界面完成。

JavaFX Scene Builder 2.0協助開發

JavaFX Scene Builder 2.0下載位置
下載完成,一路安裝,開始運行:

 
Paste_Image.png

非常簡單的一個界面,就是做做界面……
配置一下:

 
Paste_Image.png
 
Paste_Image.png

選擇JavaFX Scene Builder安裝主目錄,即可。

然后,雙擊或者右擊打開FXML,則會自動使用SB編輯器打開。

NetBeans是JavaFX的一個開發工具,比較好用。
除此之外,e(fx)clipse也是一個不錯的JavaFX開發工具,有時間可以適當查下資料,看看如何使用。



作者:heguorui
鏈接:https://www.jianshu.com/p/a80d1eedc507
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM