珍藏的javafx教程——简单了解
创始人
2024-03-23 16:07:18
0

java fx是什么

是java实现图形界面的一种方式,其他还有java的awt、swing,但是逐渐被淘汰。

javafx可以实现逻辑和样式的分离,可以使用xml和css来编写样式。

在学习之前请确保你已经熟练掌握面向对象、包装类、枚举、注解、匿名对象等内容的概念和使用。

java 11及以后使用javafx的方法

jdk 11+的使用

自从java11以后,jdk已经不内置javafx库,已交给开源社区管理,所以我们需要自己导入。

可以到这个网址去下载 jar 包。注意下载的类型是sdk。

gluonhq.com

使用maven的同学可以使用以下语句导入

 org.openjfxjavafx-controls19-ea+8

本教程使用的java版本是18,因此可能与java8的写法有所出入。

开发文档

老版本的fx文档

新版本的fx文档

fx基本

java fx的两种写法和helloworld

第一种写法把fx app实现方法和main方法写在一个类里面,在java 11之后这个方式就失效了。

 import javafx.application.Application;import javafx.stage.Stage;​public class _1helloJfx extends Application {public static void main(String[] args) {launch(args);  //调用start}​@Overridepublic void start(Stage primaryStage) throws Exception {primaryStage.setTitle("javafx"); //设置标题primaryStage.show(); //展示窗口​}​}

 第二种方法把两个方法分开放置,在launch里面传入有start方法类的反射。

 import javafx.application.Application;​public class App{public static void main(String[] args) {Application.launch(Window.class, args);}}import javafx.application.Application;import javafx.stage.Stage;​public class Window extends Application {@Overridepublic void start(Stage arg0) throws Exception {// TODO Auto-generated method stubarg0.show();}}

javafx的分层

一个javafx程序有三层,最外面的是Stage层,一个Stage就是一个独立的窗口。

在往里是Scene层,一个Scene就是一个窗口内部的一个状态。

在往里就是一个一个的node节点,节点可以是按钮、标签、文本等组件。

javafx的生命周期

任何一个事物都有产生、发展、消亡的过程,人是这样,程序也不例外。

javafx的生命周期分为init、start和stop,分别是初始化,正在运行和结束。

 @Overridepublic void init() throws Exception {System.out.println("开始");System.out.println("init():" + Thread.currentThread().getName());}​@Overridepublic void start(Stage primaryStage) throws Exception {System.out.println("运行");primaryStage.show();System.out.println("start():" + Thread.currentThread().getName());}​@Overridepublic void stop() throws Exception {System.out.println("结束");System.out.println("stop():" + Thread.currentThread().getName());}

运行后发现init是一个独立的线程,start和stop同属一个JavaFX Application Thread线程,关闭窗口后就会进入stop,我们可以在这个方法里放一些停止连接之类的函数。

fx窗口

Stage类

一个Stage类代表一个窗口,我们可以不使用方法提供的Stage,再写一个.

另外,Stage的setHeight()和setWidth()方法用来设置窗口的宽高。

  @Overridepublic void start(Stage primaryStage) throws Exception {Stage stage = new Stage();​stage.setHeight(500);stage.setWidth(500);stage.show();​}

Stage类的其他方法如下表所示

方法作用
setMaxHeight(int);窗口最大高度
setMaxWidth(int);窗口最大宽度
setResizable(boolean);是否允许改变大小
setMinHeight(int);窗口最小高度
setMinWidth(int);窗口最小宽度
setMaximized(boolean);是否最大化
setIconified(boolean);是否最小化
setFullScreen(boolean);是否全屏
setAlwaysOnTop(boolean);窗口是否保持置顶
setY(int)窗口出生距离屏幕上面的高度
setX(int)窗口出生举例屏幕左边的宽度
primaryStage.setOpacity();透明度
setTitle(String)设置窗口标题
initStyle(StageStyle);设置窗口样式,只要知道三个常用的函数,StageStyle.DECORATED是正常,StageStyle.UTILITY没有最大最小化,StageStyle.TRANSPARENT是透明就行;
setScene(Scene)给窗口设置场景
close();关闭窗口

Srage宽度高度监听和位置监听

可以用监听来做界面自适应之类的东西。

窗口大小监听

 

Stage类的其他方法如下表所示方法	作用
setMaxHeight(int);	窗口最大高度
setMaxWidth(int);	窗口最大宽度
setResizable(boolean);	是否允许改变大小
setMinHeight(int);	窗口最小高度
setMinWidth(int);	窗口最小宽度
setMaximized(boolean);	是否最大化
setIconified(boolean);	是否最小化
setFullScreen(boolean);	是否全屏
setAlwaysOnTop(boolean);	窗口是否保持置顶
setY(int)	窗口出生距离屏幕上面的高度
setX(int)	窗口出生举例屏幕左边的宽度
primaryStage.setOpacity();	透明度
setTitle(String)	设置窗口标题
initStyle(StageStyle);	设置窗口样式,只要知道三个常用的函数,StageStyle.DECORATED是正常,StageStyle.UTILITY没有最大最小化,StageStyle.TRANSPARENT是透明就行;
setScene(Scene)	给窗口设置场景
close();	关闭窗口Srage宽度高度监听和位置监听
可以用监听来做界面自适应之类的东西。窗口大小监听

 窗口位置监听

 

 @Overridepublic void start(Stage primaryStage) throws Exception {primaryStage.setY(100);primaryStage.setX(100);primaryStage.setWidth(200);primaryStage.setHeight(200);​primaryStage.xProperty().addListener(new ChangeListener() {​@Overridepublic void changed(ObservableValue observable, Number oldValue, Number newValue) {System.out.println("举例屏幕左边有 = "+newValue.doubleValue()+" px");}​});​primaryStage.yProperty().addListener(new ChangeListener() {​@Overridepublic void changed(ObservableValue observable, Number oldValue, Number newValue) {System.out.println("举例屏幕上面有 = "+newValue.doubleValue()+" px");}});primaryStage.show();

窗口图标设置

在对应的包下放置文件,然后在getIcons的add方法里面填写相对路径。

package com.javafx;import javafx.application.Application;
import javafx.scene.image.Image;
import javafx.stage.Stage;public class Window extends Application{
@Overridepublic void start(Stage primaryStage) throws Exception {primaryStage.getIcons().add(new Image("com/javafx/ico-01.png"));stage.show();}
}

子窗口

可以用initOwner()方法来设置一个窗口的父窗口,子窗口不关父窗口不会响应

    public void start(Stage primaryStage) throws Exception {// 模态化窗口。Stage s1 = new Stage();s1.setTitle("s1");Stage s2 = new Stage();s2.setTitle("s2");// s1有s2;s2.initOwner(s1);s1.show();s2.show();}

Scene类

在之前的练习中你可能发现了,窗口放大或缩小后,有些地方变成黑色,就是因为还没有添加一个Scene场景。

Group group = new Group();
Scene scene = new Scene(group); //创建一个场景
primaryStage.setScene(scene);//给窗口设置场景

创建一个场景需要传入一个参数,这个参数可以是一个布局,也可以是一个控件。

group是控件的集合,本身不是布局。

常用组件

添加组件的方法

布局或集合组件.getChildren().add(组件对象1); //添加一个组件
布局或集合组件.getChildren().addAll(组件对象1, 组件对象2); //添加多个组件

常用组件添加

常用信息输出组件

Label()标签
Text()文本
TextFlow()文本域,fx8版本后出现
ImageView图片框
ProgressBar进度条

常用控制组件

Button()按钮

常用信息输入组件

TextField()文本单行输入框
TextField()文本多行输入域
RadioButton()单选按钮
checkBox()多选按钮
PasswordField()密码框
slider()滑条
package com.javafx;import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;public class Window extends Application{@Overridepublic void start(Stage primaryStage) throws Exception {Button btn = new Button("b1");Label lab=new Label("标签");Text t1=new Text("文本。。。");Text t2=new Text();t2.setText("文本2。。。");TextFlow tf=new TextFlow();tf.getChildren().addAll(t1,t2);ProgressBar pb=new ProgressBar();pb.setProgress(0.25);ImageView iv=new ImageView();iv.setImage(new Image("com/javafx/ico-01.png", 100, 100, true, true, true));RadioButton rb1=new RadioButton();RadioButton rb2=new RadioButton();rb2.setLayoutX(20);CheckBox cb=new CheckBox();cb.setLayoutX(40);Group group=new Group();group.getChildren().addAll(rb1,rb2,cb);TextField tfIn=new TextField();TextArea ta=new TextArea();PasswordField psf=new PasswordField();FlowPane pane=new FlowPane();pane.getChildren().addAll(btn,lab,tf,pb,iv,group,tfIn,ta,psf);Scene scene=new Scene(pane);primaryStage.setScene(scene);primaryStage.setY(100);primaryStage.setX(100);primaryStage.setWidth(1000);primaryStage.setHeight(600);primaryStage.show();}
}

布局

布局请自行了解。这些布局之间可以互相嵌套,就像html里面的div一样。

S.No形状和描述
1HBoxHBox布局将应用程序中的所有节点排列在一个水平行中。
2VBoxVBox布局将我们应用程序中的所有节点排列在一个垂直列中。
3BorderPane边框窗格布局将应用程序中的节点排列在顶部,左侧,右侧,底部和中心位置。
4StackPane堆栈窗格布局将应用程序中的节点排列在另一个上面,就像在堆栈中一样。
5TextFlow文本流布局在单个流中排列多个文本节点。
6AnchorPane“锚点”窗格布局将应用程序中的节点锚定在距窗格特定距离处。
7TilePaneTile窗格布局以均匀大小的tile的形式添加应用程序的所有节点。
8GridPane网格窗格布局将应用程序中的节点排列为行和列的网格。
9FlowPane流窗格布局包装流中的所有节点。

监听

在所有节点上,都可以添加监听,以下是所有节点都通用的监听事件。

单击

方式1

package com.javafx;import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;public class Window extends Application{@Overridepublic void start(Stage primaryStage) throws Exception {Button btn = new Button("b1");btn.setOnAction(new javafx.event.EventHandler() {@Overridepublic void handle(ActionEvent event) {Button bu = (Button) event.getSource();System.out.println(bu.getText() + "单击");}}); FlowPane pane=new FlowPane();pane.getChildren().add(btn);Scene scene=new Scene(pane);primaryStage.setScene(scene);primaryStage.setWidth(500);primaryStage.setHeight(500);primaryStage.show();}   
}

双击

这个方法也可以改成单击

package com.javafx;import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;public class Window extends Application{@Overridepublic void start(Stage primaryStage) throws Exception {Button btn = new Button("b1");btn.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler() {@Overridepublic void handle(MouseEvent arg0) {System.out.println("鼠标按键 = " + arg0.getButton().name());Button bu = (Button) arg0.getSource();//连续点击只有两次且用的是鼠标左键if(arg0.getClickCount() == 2 &&arg0.getButton().name().equals(MouseButton.PRIMARY.name())){System.out.println(bu.getText()+"双击");}}});FlowPane pane=new FlowPane();pane.getChildren().add(btn);Scene scene=new Scene(pane);primaryStage.setScene(scene);primaryStage.setWidth(200);primaryStage.setHeight(200);primaryStage.show();}}

键盘

如果想监测到多个键同时按到,需要用另外一个方法,这个后面会讲

package com.javafx;import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.FlowPane;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;public class Window extends Application{public Text text;@Overridepublic void start(Stage primaryStage) throws Exception {text=new Text("你按下了 “ ” 键。");text.setFont(Font.font(25));FlowPane pane=new FlowPane();pane.getChildren().add(text);Scene scene=new Scene(pane);scene.setOnKeyPressed(new EventHandler(){@Overridepublic void handle(KeyEvent arg0) {if (arg0.getCode().getName().equals(KeyCode.A.getName())) {System.out.println("A被按下");}text.setText("你按下了“"+arg0.getCode().getName()+"”键。");             }   });primaryStage.setScene(scene);primaryStage.setWidth(300);primaryStage.setHeight(100);primaryStage.show();}}

相关内容

热门资讯

原创 打... 打完乌克兰就收手,俄方拍着胸脯承诺北约和欧盟,可以立字据为证。 (俄方向北约承诺,打完乌克兰就收手...
政策纾困与转型升级并举 中国乳... 新华社北京12月27日电 题:政策纾困与转型升级并举 中国乳业迎来破局窗口期 新华社记者谢希瑶 乳制...
男子将女子约至酒店后杀害,女子... 12月27日,南都N视频记者从山东省聊城市中级人民法院获悉,山东男子董某与女子陶某曾是恋人关系,后分...
杨伟民:刺激消费政策应该逐步转... 12月27日,中国财富管理50人论坛2025年会在京举行,第十三届全国政协经济委员会副主任杨伟民在会...
从KS直播异常事件切入,湖南芙... 12月22日晚,针对网络平台直播异常引发的社会关注事件,湖南芙蓉律师事务所围绕“黑灰产攻击、平台责任...
出行观 | 智驾出关“水土不服... (文/观察者网 高莘)据香港《南华早报》12月26日报道,香港有关部门将要调查一名违反“粤车南下”政...
全国人大常委会关于《中华人民共... 全国人民代表大会常务委员会关于 《中华人民共和国刑事诉讼法》 第二百九十二条的解释 (2025年12...
渊亭信息科技申请基于检索增强生... 国家知识产权局信息显示,厦门渊亭信息科技有限公司申请一项名为“基于检索增强生成的智能政策问答方法、系...
政策纾困与转型升级并举,中国乳... 乳制品行业是一二三产业深度融合的重要行业。近日,商务部一则公告引发外界对于这一行业发展形势的关注。 ...
重庆荣豪律师事务所:医疗纠纷处... 推荐指数:★★★★★ 在医疗纠纷频发的当下,如何高效、专业地处理医疗纠纷成为众多患者及其家属、医疗机...