JavaFX学习笔记

这篇博客详细记录了JavaFX的学习过程,从HelloWorld开始,介绍如何创建JavaFX表单,利用CSS进行界面美化,以及如何运用FXML构建用户界面。通过这些步骤,读者可以深入理解JavaFX的开发基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HelloWorld创世纪

完成好JavaFX的环境搭建之后,我们开始正式地编写JavaFX的代码。在Eclipse中File->New Project->JavaFx->JavaFX Application,完成项目创建。
我们看到的是这样的默认代码
   
   
  1. /*Main.java*/
  2. package application;
  3. import javafx.application.Application;
  4. import javafx.stage.Stage;
  5. import javafx.scene.Scene;
  6. import javafx.scene.layout.BorderPane;
  7. public class Main extends Application {
  8. @Override
  9. public void start(Stage primaryStage) {
  10. try {
  11. BorderPane root = new BorderPane();
  12. Scene scene = new Scene(root,400,400);
  13. scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
  14. primaryStage.setScene(scene);
  15. primaryStage.show();
  16. } catch(Exception e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. public static void main(String[] args) {
  21. launch(args);
  22. }
  23. }
来看看代码结构中几个关键的点:
Ⅰ. JavaFX应用中的核心类Main是继承自 javafx.application.Application的子类,Application的一个实例化对象在整个生命周期会经历以下几个过程:
  1. 构建一个指定Application类的实例化对象。
  2. 调用init()方法进行初始化工作
  3. 调用start(javafx.stage.Stage)方法
  4. 等待Application结束,即以下两种情况之一:1)调用Platform.exit()方法时 2)所有的window都被关闭,并且Platform的implicitExit参数为true。
  5. 调用stop()方法
Ⅱ.  JavaFX Application通过stage和scene来定义UI容器,其中Stage是最顶层的JavaFX容器,Scene是所有部件的容器。下图描述了一个简单的样例:

Ⅲ.  在JavaFX中,scene的部件被表示成拥有层次关系的节点。在上面例子中,根节点是StackPane root对象,Button btn则是root的子节点。
Ⅳ.   main()方法在JavaFX Application中不是必须的(在一些集成了JavaFX启动器的IDE中,会自动调用start()方法来启动JavaFX Application),但是考虑到某些情况下JavaFX启动器可能未被集成到IDE当中,或者有的时候我们是通过集成了JavaFX代码的Swing Application来启动JavaFX,所以把main()方法写出来还是很有必要的!

创建JavaFX表单

比较简单,直接上代码吧
  
  
  1. package application;
  2. import javafx.application.Application;
  3. import javafx.event.ActionEvent;
  4. import javafx.event.EventHandler;
  5. import javafx.geometry.Insets;
  6. import javafx.geometry.Pos;
  7. import javafx.scene.Scene;
  8. import javafx.scene.control.Button;
  9. import javafx.scene.control.Label;
  10. import javafx.scene.control.PasswordField;
  11. import javafx.scene.control.TextField;
  12. import javafx.scene.layout.GridPane;
  13. import javafx.scene.layout.HBox;
  14. import javafx.scene.paint.Color;
  15. import javafx.scene.text.Font;
  16. import javafx.scene.text.FontWeight;
  17. import javafx.scene.text.Text;
  18. import javafx.stage.Stage;
  19. public class Login extends Application {
  20. @Override
  21. public void start(Stage primaryStage) {
  22. primaryStage.setTitle("My Form");
  23. GridPane grid = new GridPane(); //创建一个GridPane来布局
  24. grid.setAlignment(Pos.CENTER); //GridPane在父容器中的位置
  25. //以下代码设置grid的样式
  26. grid.setHgap(10);
  27. grid.setVgap(10);
  28. grid.setPadding(new Insets(25, 25, 25, 25));
  29. Scene scene = new Scene(grid, 300, 275); //创建scene并把grid设为root节点
  30. primaryStage.setScene(scene); //把scene渲染到primaryStage。
  31. /**
  32. * 注意一个Stage同一时间只能有一个scene,一个scene也只能被渲染到一个Stage。
  33. * 如果同一个scene被渲染到两个Stage,则在新的Stage接受此scene之前会把旧Stage中对scene的引用销毁。
  34. * 可以在任何时候对Stage中的scene进行调整,但是只能发生在JavaFX Application Thread中,
  35. * 如果不是,则会扔出一个IllegalStateException
  36. */
  37. Text scenetitle = new Text("Welcome"); //新建一个Text
  38. scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));
  39. grid.add(scenetitle, 0, 0, 2, 1); //在grid中添加scenetitle作为标题
  40. //后四个参数分别表示行列的起始Index和跨度
  41. //以下代码原理相同
  42. Label userName = new Label("User Name:");
  43. grid.add(userName, 0, 1);
  44. TextField userTextField = new TextField();
  45. grid.add(userTextField, 1, 1);
  46. Label pw = new Label("Password:");
  47. grid.add(pw, 0, 2);
  48. PasswordField pwBox = new PasswordField();
  49. grid.add(pwBox, 1, 2);
  50. Button btn = new Button("Sign in");
  51. HBox hbBtn = new HBox(10);
  52. hbBtn.setAlignment(Pos.BOTTOM_RIGHT);
  53. hbBtn.getChildren().add(btn);
  54. grid.add(hbBtn, 1, 4);
  55. final Text actiontarget = new Text();
  56. actiontarget.setText("Error");
  57. actiontarget.setVisible(false);
  58. actiontarget.setFill(Color.GOLD);
  59. HBox acHBox = new HBox(10);
  60. acHBox.setAlignment(Pos.BASELINE_CENTER);
  61. acHBox.getChildren().add(actiontarget);
  62. grid.add(acHBox, 0, 6, 2, 1);
  63. btn.setOnAction(new EventHandler<ActionEvent>() {
  64. @Override
  65. public void handle(ActionEvent arg0) {
  66. actiontarget.setText(pwBox.getText());
  67. actiontarget.setVisible(true);
  68. }
  69. });
  70. //grid.setGridLinesVisible(true); //可以把GridLinesVisible设为true显示grid的行列线
  71. primaryStage.show();
  72. }
  73. public static void main(String[] args) {
  74. launch(args);
  75. }
  76. }
代码运行效果:


使用CSS装饰

把业务逻辑跟样式代码分开,可以利用CSS。这里我们仍然使用上述Form中的代码来做修改
正式开始之前先把把原本.java代码中关于样式的语句删除
   
   
  1. scenetitle.setFont(Font.font("Tahoma", FontWeight.NORMAL, 20));    //删除
  2. //...
  3. actiontarget.setFill(Color.GOLD);    //删除
OK,首先新建一个.css文件并在.java中关联它
   
   
  1. scene.getStylesheets().add(Login.class.getResource("Login.css").toExternalForm());
然后为需要使用CSS修饰的部件添加ID
   
   
  1. scenetitle.setId("welcome-text");
  2. actiontarget.setId("actiontarget");
接着开始编辑.css文件
    
    
  1. @CHARSET "UTF-8";
  2. .root {
  3. -fx-background-image: url("background.jpg");/*设置背景图片*/
  4. }
  5. .label { /*利用类选择器为label类添加样式*/
  6. -fx-font-size: 14px;
  7. -fx-font-weight: bold;
  8. -fx-text-fill: #333333;
  9. -fx-effect: dropshadow(gaussian, rgba(255, 255, 255, 0.5), 0, 0, 0, 1);
  10. }
  11. #welcome-text { /*利用id选择器为id="welcome-text"的部件添加样式*/
  12. -fx-font-size: 30px;
  13. -fx-font-family: "Arial Black";
  14. -fx-fill: #818181;
  15. -fx-effect: innershadow(three-pass-box, rgba(0, 0, 0, 0.7), 6, 0.0, 0, 2);
  16. }
  17. #actiontarget { /*利用id选择器为id="actiongtarget"的部件添加样式*/
  18. -fx-fill: FIREBRICK;
  19. -fx-font-weight: bold;
  20. -fx-effect: dropshadow(gaussian, rgba(255, 255, 255, 0.5), 0, 0, 0, 1);
  21. }
运行效果如下:


使用FXML来创建UI

JavaFX还支持使用一种FXML的语言来构建UI,以达到把UI和业务逻辑分开的目的。
下面来创建这个FXML项目。
首先,我们的项目包含以下三个文件:

作为整个Application的入口,FXMLExample.java中需载入fxml资源。
所以我们在代码中是通过javafx.fxml.FXMLLoader类来创建Parent节点的。
   
   
  1. @Override
  2. public void start(Stage primaryStage) throws Exception {
  3. Parent root = FXMLLoader.load(getClass().getResource("example.fxml")); //载入example.fxml文件
  4. Scene scene = new Scene(root,300,375);
  5. primaryStage.setTitle("Hello FXML");
  6. primaryStage.setScene(scene);
  7. primaryStage.show();
  8. }
简单完成这一步之后就可以对example.fxml进行编辑了,完整代码如下:
   
   
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <?import java.net.*?>
  3. <?import javafx.geometry.*?>
  4. <?import javafx.scene.control.*?>
  5. <?import javafx.scene.layout.*?>
  6. <?import javafx.scene.text.*?>
  7. <GridPane fx:controller="javaFX_FXML.FXMLExampleController"
  8. xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
  9. <padding>
  10. <Insets top="25" right="25" bottom="10" left="25" />
  11. </padding>
  12. <!-- <gridLinesVisible>true</gridLinesVisible> -->
  13. <Text text="Welcome" GridPane.columnIndex="0" GridPane.rowIndex="0"
  14. GridPane.columnSpan="2" />
  15. <Label text="User Name:" GridPane.columnIndex="0"
  16. GridPane.rowIndex="1" />
  17. <TextField GridPane.columnIndex="1" GridPane.rowIndex="1" />
  18. <Label text="Password:" GridPane.columnIndex="0"
  19. GridPane.rowIndex="2" />
  20. <PasswordField fx:id="passwordField"
  21. GridPane.columnIndex="1" GridPane.rowIndex="2" />
  22. <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="1"
  23. GridPane.rowIndex="4">
  24. <Button text="Sign In" onAction="#handleSubmitButtonAction" />
  25. </HBox>
  26. <Text fx:id="actiontarget" GridPane.columnIndex="0"
  27. GridPane.columnSpan="2" GridPane.halignment="RIGHT" GridPane.rowIndex="6" />
  28. </GridPane>
来看看整个fxml的结构,首行是对版本及字符编码的定义。
然后就把需要用到的包import进来(由于默认Eclipse环境不会自动导入需要的包,暂时还不知道有没有比较方便的途径可以导入需要用到的包)。接下来是一个<GridPane> </GridPane>布局 组件,布局内部放入了需要用到的子组件,参数都是见名知意的。就不再添加注释了。
完成了在fxml中对UI的定义之后就要编辑Controller了,在FXMLExampleController.java中:
    
    
  1. package javaFX_FXML;
  2. import javafx.event.ActionEvent;
  3. import javafx.fxml.FXML;
  4. import javafx.scene.text.Text;
  5. public class FXMLExampleController {
  6. @FXML private Text actiontarget;
  7. @FXML protected void handleSubmitButtonAction(ActionEvent event) {
  8. actiontarget.setText("Sign in button pressed");
  9. }
  10. }
@FXML注释用来标记非public的FXML成员字段以及方法。其中字段名跟fx:id属性相关,方法则跟onAction属性相关。
当然,也可以在FXML中引用CSS。通过以下方法:
    
    
  1. <stylesheets>
  2. <URL value="@Login.css" />
  3. </stylesheets>
  4. </GridPane>
然后在需要引用CSS类的组件中添加styleClass属性,例如在GridPane中添加css的root类。
    
    
  1. <GridPane fx:controller="fxmlexample.FXMLExampleController"
  2. xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10"
  3. styleClass="root">
也可以利用CSS的ID选择器来使用指定ID的样式:
    
    
  1. <Text id="welcome-text" text="Welcome"
  2. GridPane.columnIndex="0" GridPane.rowIndex="0"
  3. GridPane.columnSpan="2"/>
更多相关文档: Introduction to FXML



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值