JavaFX 介绍
一提到Java的图形界面库,我们通常听到的都是Swing,或者更老一点的AWT,包括很多书上面介绍的也都是这两种。很多学校、培训班教学的也是这两种技术。但是其实这两种技术都已经过时很长时间了。Swing虽然学起来也不算很难,但是用它来写界面其实也很不好写。因为它的界面和代码没有做到分离,所以在编写的时候,代码中肯定充斥着大量坐标,修改极其不易。这方面做的比较好的就是微软的WPF,只能说谁用谁知道。
当然,虽然编写客户端图形程序是Java的弱项,但是Java并没有放弃这方面的努力。今天介绍的JavaFX就是Java在编写图形界面程序的最新技术。如果你准备使用Java编写图形界面程序,又没有历史包袱,那么强烈推荐使用JavaFX。
这是Oracle官网关于JavaFX的资源和文档。
这是官方的示例程序,我们可以参考JavaFX的部分来学习如何使用。
如何安装
只要你安装了最新版本的JDK 8,那么就可以使用JavaFX库了。如果没有安装的话,那么赶快开始安装吧。
快速上手
第一个程序
新建一个项目,然后编写如下的类,然后编译运行,即可看到结果。关于这个程序不用做解释吧。如果有学习过Swing以及其他图形界面框架的经验的话,应该非常容易理解这段代码。当然由于JavaFX是新东西,所以我也顺便使用Java 8的新特性——lambda表达式。
1 package yitian.javafxsample; 2 3 import javafx.application.Application; 4 import javafx.scene.Scene; 5 import javafx.scene.control.Button; 6 import javafx.scene.layout.StackPane; 7 import javafx.stage.Stage; 8 9 public class HelloJavaFX extends Application { 10 11 @Override 12 public void start(Stage primaryStage) throws Exception { 13 Button btn = new Button(); 14 btn.setText("你好啊,世界"); 15 btn.setOnAction(event -> { 16 System.out.println("你好,世界!"); 17 }); 18 19 StackPane root = new StackPane(); 20 root.getChildren().add(btn); 21 22 Scene scene = new Scene(root, 300, 250); 23 24 primaryStage.setTitle("Hello World!"); 25 primaryStage.setScene(scene); 26 primaryStage.show(); 27 } 28 29 30 public static void main(String[] args) { 31 launch(args); 32 } 33 }
运行截图如下。
用户输入
这个程序可以用来处理用户登录的情况,代码如下,重要部分都添加了注释。代码的最后一部分使用setOnAction函数为按钮添加了点击事件,当点击按钮的时候会显示文本。
1 public class UserInput extends Application { 2 @Override 3 public void start(Stage primaryStage) throws Exception { 4 //网格布局 5 GridPane grid = new GridPane(); 6 grid.setAlignment(Pos.CENTER); 7 //网格垂直间距 8 grid.setHgap(10); 9 //网格水平间距 10 grid.setVgap(10); 11 grid.setPadding(new Insets(25, 25, 25, 25)); 12 //新建场景 13 Scene scene = new Scene(grid, 300, 275); 14 primaryStage.setScene(scene); 15 //添加标题 16 Text scenetitle = new Text("Welcome"); 17 scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20)); 18 grid.add(scenetitle, 0, 0, 2, 1); 19 //添加标签及文本框 20 Label userName = new Label("用户名:"); 21 grid.add(userName, 0, 1); 22 23 TextField userTextField = new TextField(); 24 grid.add(userTextField, 1, 1); 25 //添加标签及密码框 26 Label pw = new Label("密码:"); 27 grid.add(pw, 0, 2); 28 29 PasswordField pwBox = new PasswordField(); 30 grid.add(pwBox, 1, 2); 31 //添加提交按钮 32 Button btn = new Button("登录"); 33 HBox hbBtn = new HBox(10); 34 hbBtn.setAlignment(Pos.BOTTOM_RIGHT); 35 hbBtn.getChildren().add(btn); 36 grid.add(hbBtn, 1, 4); 37 //提交文本提示 38 final Text actiontarget = new Text(); 39 grid.add(actiontarget, 1, 6); 40 41 btn.setOnAction(event -> { 42 actiontarget.setFill(Color.FIREBRICK); 43 actiontarget.setText("已经登录"); 44 }); 45 46 primaryStage.setTitle("JavaFX Welcome"); 47 primaryStage.show(); 48 } 49 50 public static void main(String[] args) { 51 launch(args); 52 } 53 }
程序运行截图如下。
这个程序其实也没什么难点,就是使用了网格布局,然后将每个元素添加到网格中。关于网格布局的属性意义可以参考官方的图。
用FXML设计用户界面
现代图形界面框架都支持将界面和代码分离开,而且比较常用的描述语言是XML,例如QT的QML、WPF的XAML,当然JavaFX也有类似的语言,叫做FXML。如果需要详细了解FXML,可以参考Oracle官网的文章Introduction to FXML。
下面用FXML重写一下上面那个小例子,每个部分都做了注释。如果学习过其他类似描述语言的话,会发现这些其实都差不多。唯一需要注意的就是布局里面的fx:controller属性,它指定一个控制器,控制器的作用就是编写界面对应的代码。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!--导入类--> 3 <?import javafx.geometry.Insets?> 4 <?import javafx.scene.control.*?> 5 <?import javafx.scene.layout.*?> 6 <?import javafx.scene.text.Font?> 7 <?import javafx.scene.text.Text?> 8 <!--设置布局--> 9 <GridPane xmlns="http://javafx.com/javafx" 10 xmlns:fx="http://javafx.com/fxml" 11 fx:controller="yitian.javafxsample.Controller" 12 prefHeight="400.0" prefWidth="600.0" 13 alignment="center" hgap="10" vgap="10"> 14 <padding> 15 <Insets top="25" right="25" bottom="10" left="25"/> 16 </padding> 17 <!--欢迎文本--> 18 <Text text="Welcome" 19 GridPane.columnIndex="0" GridPane.rowIndex="0" 20 GridPane.columnSpan="2"> 21 <font> 22 <Font name="Consolas" size="20"/> 23 </font> 24 </Text> 25 26 <Label text="用户名:" 27 GridPane.columnIndex="0" GridPane.rowIndex="1"/> 28 29 <TextField 30 GridPane.columnIndex="1" GridPane.rowIndex="1"/> 31 32 <Label text="密码:" 33 GridPane.columnIndex="0" GridPane.rowIndex="2"/> 34 35 <PasswordField fx:id="passwordField" 36 GridPane.columnIndex="1" GridPane.rowIndex="2"/> 37 <!--按钮及提示文本--> 38 <HBox spacing="10" alignment="bottom_right" 39 GridPane.columnIndex="1" GridPane.rowIndex="4"> 40 <Button text="显示密码" 41 onAction="#showPasswordButton"/> 42 </HBox> 43 44 <Text fx:id="hintText" 45 GridPane.columnIndex="0" GridPane.columnSpan="2" 46 GridPane.halignment="RIGHT" GridPane.rowIndex="6"/> 47 </GridPane>
下面就是这个FXML文件对应的控制器,它是一个标准的Java类。在FXML中用fx:id属性指定的ID,可以在控制器中声明为一个类字段,通过这个字段就可以和界面组件进行交互。同样道理,onAction声明的事件处理程序,在控制器中就是一个方法。注意这些字段和方法都需要使用@FXML注解进行标注。
1 import javafx.event.ActionEvent; 2 import javafx.fxml.FXML; 3 import javafx.scene.control.PasswordField; 4 import javafx.scene.text.Text; 5 6 7 public class Controller { 8 @FXML 9 private Text hintText; 10 @FXML 11 private PasswordField passwordField; 12 13 @FXML 14 protected void showPasswordButton(ActionEvent event) { 15 hintText.setText("显示密码:" + passwordField.getText()); 16 } 17 }
最后要做修改的就是主程序了。在主程序中需要使用FXMLLoader来加载FXML资源,其他部分没有太大变化。
1 public class UseFxml extends Application { 2 @Override 3 public void start(Stage primaryStage) throws Exception { 4 Parent root = FXMLLoader.load(getClass().getResource("ui.fxml")); 5 6 Scene scene = new Scene(root, 300, 275); 7 primaryStage.setTitle("使用FXML"); 8 primaryStage.setScene(scene); 9 primaryStage.show(); 10 } 11 12 public static void main(String[] args) { 13 launch(args); 14 } 15 }
程序运行截图如下。
如果希望修改组件样式,JavaFX提供了CSS接口,让我们可以直接使用CSS文件修改样式。首先需要在FXML文件中添加相应样式表的引用。文件名前面的@表示这个CSS文件和FXML文件在同一目录下。
1 <GridPane> 2 <stylesheets> 3 <URL value="@style.css"/> 4 </stylesheets> 5 <GridPane/>
样式表和普通的样式表差不多,只不过需要添加JavaFX特有的前缀-fx-。
1 #btnShowPassword { 2 -fx-background-color: deeppink; 3 }
上面用了ID选择器,所以对应地,在FXML中也需要ID属性。
1 <Button id="btnShowPassword" text="显示密码" 2 onAction="#showPasswordButton"/>
自定义之后的程序如图所示。这里只简单修改了一下按钮的背景色,其实可以更改的样式有很多,包括程序背景等等,有兴趣的同学可以自行尝试。
JavaFx在线文档:https://docs.oracle.com/javafx/2/api/index.html
以上就是这篇文章的内容了。如果有同学想使用Java编写图形界面程序,可以考虑使用JavaFX,这是一个很不错的选择。