总结常用的Javafx功能及用法(下)
总结常用的Javafx功能及用法
- 控件的绑定和监听
- 事件驱动编程
- 什么是事件驱动
- 创建一个点击移动事件
- 创建一个拖拽移动文件的事件
- FXML布局
- Scene Builder的使用
- Controller 的Initialize
- 控件的绑定和监听 (不在主线程)
- 多线程问题
控件的绑定和监听
在主线程
这里是让控件(Lable,Circle…)和页面大小做一个绑定
1.创建一个圆
Circle circle = new Circle();circle.setCenterX(250);circle.setCenterY(250);circle.setRadius(100);circle.setStroke(Color.BLACK);circle.setFill(Color.WHITE);
2.坐标绑定
让圆一直显示在页面中间,也就是让圆的中心坐标属性和scence的长宽做一个绑定
//让圆的中心坐标等于scene长度和宽度的一半
circle.centerXProperty().bind(scene.widthProperty().divide(2));
circle.centerYProperty().bind(scene.heightProperty().divide(2));
当我们缩小界面的时候,可以保证圆始终在页面的正中间
3.监听器
我们也可以尝试用监听器对stage进行监听,每当页面大小被更改,则内部对圆的坐标进行更改,完成同样的效果。
//对窗口的宽度属性加上一个监听器//添加一个ChangeListener,每当ObservalEvalue的值发生变化时,就会通知它。stage.widthProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {//一旦窗口变化,这里做一个输出System.out.println("窗口宽度发生变化"+newValue);circle.setCenterX((Double) newValue/2);}});//对窗口高度属性加上监听器stage.heightProperty().addListener(new ChangeListener<Number>() {@Overridepublic void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {circle.setCenterY((Double) newValue/2);}});
事件驱动编程
什么是事件驱动
点击一个按键,点击鼠标,拖拽鼠标,点击按钮,电脑执行了(#¥……@#¥)操作,这样一个过程叫事件驱动。
创建一个点击移动事件
这里举例点击按钮,让label实现向下移动20
1.创建Label和Button
Label label = new Label("hello world");Button button = new Button("移动label");label.setLayoutX(200);label.setLayoutY(50);button.setLayoutX(200);button.setLayoutY(250);
2.添加场景布局
AnchorPane root = new AnchorPane();root.getChildren().addAll(label,button);Scene scene = new Scene(root,500,500);stage.setTitle("移动事件");stage.getIcons().add(new Image("com/yu/abc/1.jpg"));stage.setScene(scene);stage.show();
3.添加Button的点击移动事件
button.setOnAction(new EventHandler<ActionEvent>() {//创建一个handler处理者@Overridepublic void handle(ActionEvent event) {//让他干事就完了label.setLayoutY(label.getLayoutY()+20);}});
4.添加一个按键移动事件
//键盘点击事件可以放在任意控件或者场景中//可以使用创建handler 也可以lamda表达式scene.setOnKeyReleased(event -> {KeyCode kc = event.getCode();if (kc.equals(KeyCode.UP)){label.setLayoutY(label.getLayoutY()-20);}});
创建一个拖拽移动文件的事件
这里完成从桌面拖拽文件到窗口,文本框显示文件路径
//创建一个文本框TextField textField = new javafx.scene.control.TextField();textField.setLayoutX(150);textField.setLayoutY(150);//对拖拽的信息进行反馈textField.setOnDragOver(event -> {//接收拖拽事件,为拖拽目标选择通用的Any模式event.acceptTransferModes(TransferMode.ANY);});//松手时反馈拖拽的文件的绝对路径textField.setOnDragDropped(event -> {//dragboard是一个剪贴板,鼠标拖拽松手时获取剪贴板的文件Dragboard dragboard =event.getDragboard();if (dragboard.hasFiles()){//如果剪贴板有文件,则返回绝对路径到文本框中String path = dragboard.getFiles().get(0).getAbsolutePath();textField.setText(path);}});
FXML布局
使用FXML布局以后 我们将程序分成 布局 控制 main方法的衔接
Fxml布局文件设置各种控件位置,属性,以及绑定控制器:
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?><?import javafx.scene.text.Font?>
<AnchorPane xmlns="http://javafx.com/javafx"xmlns:fx="http://javafx.com/fxml"fx:controller="com.yu.abc.Fxml.DemoControl"prefHeight="400.0" prefWidth="600.0"><children><Label fx:id="la" text="Hello World!" layoutX="150" layoutY="200"><font><Font size="30"></Font></font></Label><!--onUp是使用控制器类里面的方法进行操作--><Button fx:id="bu" text="向上移动" layoutX="150" layoutY="250" onAction="#onUp"></Button></children>
</AnchorPane>
在控制器中绑定fxml中控件名,以及我们想要让控件做什么事(创建方法):
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;public class DemoControl {@FXMLLabel la;@FXMLButton bu;public void onUp(){la.setLayoutY(la.getLayoutY()-10);}}
最后在主方法中,对fxml布局和Controller控制器做一个衔接:
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.IOException;public class Buju extends Application {public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage primaryStage) throws IOException {//找到fxml文件进行加载Pane root = FXMLLoader.load(getClass().getResource("buju1.fxml"));Scene scene = new Scene(root,500,500);primaryStage.setScene(scene);primaryStage.setTitle("Fxml");primaryStage.show();}
}
Scene Builder的使用
搭建JavaFX可以分成三部分: fxml controler 主方法
利用scene Builder 拖拽的方式进行布局自动生成FXML文件,会简单很多
在设置里绑定 scence Builder 可以直接从 fxml文件中打开scence builder布局
Controller 的Initialize
由于加载布局并完成Controller属性的绑定以后就会开始调用 controller的initialize方法,因此可以利用这个特性在加载初始化数据上
这里举例tableView
Controller里编写initialize的逻辑:
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;public class ControlPerson {@FXMLprivate TableView<Person> tableView;@FXMLprivate TableColumn<Person,String> name;@FXMLprivate TableColumn<Person, Integer> age;public void initialize()throws Exception{ObservableList<Person> celldata = FXCollections.observableArrayList();name.setCellValueFactory(new PropertyValueFactory<Person,String>("name"));age.setCellValueFactory(new PropertyValueFactory<Person,Integer>("age"));celldata.add(new Person("张三",18));celldata.add(new Person("lisi",23));celldata.add(new Person("berry",38));tableView.setItems(celldata);}
}
控件的绑定和监听 (不在主线程)
fxml布局 :添加node,设置node属性,绑定控制器
<?xml version="1.0" encoding="UTF-8"?><?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.shape.Circle?><AnchorPane fx:controller="com.yu.abc.Hello.HelloControl" prefHeight="500.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" ><children><Circle fx:id="circle" centerX="250.0" centerY="250.0" fill="DODGERBLUE" radius="100.0" stroke="BLACK" strokeType="INSIDE" /></children>
</AnchorPane>
controller:绑定node名,编写绑定事件的方法控制node
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;public class HelloControl {@FXMLprivate Circle circle;public void circleLocationBind(Scene scene){circle.centerXProperty().bind(scene.widthProperty().divide(2));circle.centerYProperty().bind(scene.heightProperty().divide(2));}}
main:读取fxml文件,获取controller,创建scene,stage…
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;public class Main extends Application {public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage primaryStage)throws Exception {//加载fxml文件FXMLLoader fxmlLoader =new FXMLLoader();fxmlLoader.setLocation(getClass().getResource("Hello.fxml"));Parent root = fxmlLoader.load();Scene scene = new Scene(root);//使用Controller进行绑定监听,先获取这个controllerHelloControl helloControl = fxmlLoader.getController();//调用绑定方法,将场景放在里面helloControl.circleLocationBind(scene);primaryStage.setScene(scene);primaryStage.setTitle("Hello");primaryStage.show();}
}
多线程问题
javafx是不允许除主线程以外的其他线程去刷新或更改ui的,
需要主线程Application的静态方法Platform.runlater()
实际上是通过runlater将里面的操作放在队列里,当主方法空闲时去执行
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;public class thread0 extends Application {public static void main(String[] args) {launch(args);}@Overridepublic void start(Stage primaryStage) {Label label = new Label("名字是?");label.setLayoutX(150);label.setLayoutY(250);Button button = new Button("获取");button.setLayoutX(150);button.setLayoutY(300);button.setOnAction(event -> {Thread thread = new Thread(()->{String newValue ="ycc";//javafx是不允许除主线程以外的线程去刷新或更改ui的//这一步无法更改页面为新数据
// label.setText(newValue);//Platfor之前还在设置关闭界面管理上Platform.runLater(()->{//需要使用Platform的runlaterlabel.setText(newValue);});});thread.start();});AnchorPane root = new AnchorPane();root.getChildren().addAll(label,button);Scene scene = new Scene(root,500,500);primaryStage.setScene(scene);primaryStage.setTitle("thread使用");primaryStage.show();}
}
在fx很多控件的事件里 内部是调用runlater的
(把事件的监听器 里的change 放在runlater里的) 因此不用自己调用
总结常用的Javafx功能及用法(下)相关推荐
- 总结常用的Javafx功能及用法(上)
总结常用的Javafx功能及用法 什么是Javafx 一个窗口都有哪些内容 制作一个简单的窗口 一些方法 Stage scene Pane node(一般node同用的方法,这里用label举例) 关 ...
- mysql 存储引擎作用_MySQL常用存储引擎功能与用法详解
MySQL存储引擎主要有两大类: 1. 事务安全表:InnoDB.BDB. 2. 非事务安全表:MyISAM.MEMORY.MERGE.EXAMPLE.NDB Cluster.ARCHIVE.CSV. ...
- Android学习笔记 2.5.3 实例——使用SimpleAdapter创建ListView 2.5.4 自动完成文本框(AutoCompleteTextView)的功能与用法
Android学习笔记 疯狂Android讲义 文章目录 Android学习笔记 疯狂Android讲义 第2章 Android 应用的界面编程 2.5 第4组 UI组件:AdapterView及其子 ...
- AR单片机编程软件的菜单栏功能及用法
<转载>IAR单片机编程软件的菜单栏功能及用法全面介绍 原网站 原网站 原网站 网站内介绍如下内容 选取部分 Ⅴ.View视图菜单 这个菜单的意思就是打开或关闭视图窗口,比如我们的工作空间 ...
- 网络工具nc的常见功能和用法
文章目录 前言 nc netcat ncat nc的用法 测试udp端口是否可用 端口扫描 一对一聊天 传输文件 端口转发 总结 前言 nc 是一个Linux环境下常用的工具命令,可以用来帮助开发者查 ...
- 鸿蒙应用开发 | 按钮(Button)组件 的功能与用法
大家好,我是你们的朋友 朋哥,今天开始朋哥开始研究鸿蒙了,定时会写一些文章分享给大家,希望多多提意见. 上一篇原创文章 解读了 文本框(Text)和编辑框(TextField)的功能与用法. 没有跟上 ...
- 数值选择器(NumberPicker)的功能与用法
数值选择器用于让用户输入数值,用户既可以通过键盘输入数值,也可以通过拖动来选择数值.使用该组件常用如下三个方法. setMinValue(int minVal):设置该组件支持的最小值. set ...
- Javascript自定义事件功能与用法实例分析
原文地址:https://www.jb51.net/article/127776.htm 本文实例讲述了javascript自定义事件功能与用法.分享给大家供大家参考,具体如下: 概述 自定义事件很难 ...
- Delphi Format函数功能及用法详解
DELPHI中Format函数功能及用法详解 DELPHI中Format函数功能及用法详解function Format(const Format: string; const Args: array ...
最新文章
- CentOS 7.8下安装完美安装配置Rosetta
- 转:iPhone之后,思考下一个科技突破
- 【arduino】童芯派彩屏显示图片,图片取模后在TFT液晶显示
- java回调函数_PHP回调函数及匿名函数概念与用法详解
- 用802.11n 加速,将android手机屏幕投影到win7电脑上
- mybatis----#与$区别
- Django(part24)--查询数据
- 基于JAVA+Spring+MYSQL的美食网站系统
- html网页中获取vf数据到mysql_怎样从HTML网页中获取SQL数据库里的数据
- 更适合私有云的网络部署模式-动态路由
- (省赛系列——团队第三场)
- R语言第四次作业(股票、债券收益率计算)
- 模糊综合评价在实际问题中的应用(案例)
- vba 发送邮件 html,使用VBA实现发邮件功能
- 小样本学习(few-shot learning)之——原形网络(Prototypical Networks)
- 玩转NVIDIA Jetson AGX Xavier(3)--- 使用JetPack 4.1为Xavier刷机
- alexa排名的作用
- 综合治理GIS方案(综治)
- ListView的分割线相关属性
- python编程基础知识点总结_【转载】Python编程中常用的12种基础知识总结
热门文章
- 02pysal距离权重矩阵
- 软件工程(速成)——第三章 需求分析
- 解决Android接入服务器NanoHttpd响应慢的问题
- 如何使用dSYM符号化crash日志。解析线上crash
- wordpress大前端博客主题DUX7.1
- swift 解决SDWebImage同时加载大量高分辨率图片导致的内存爆炸问题
- 超实用的音频控制工具:SoundSource for Mac
- 物联网展-2019北京国际物联网展览会-北京物联网展-北京物联网大会
- 在 Python 中使用蒙特卡罗方法预测股票价格,使用蒙特卡罗模拟确定明年 SPY 最有可能的价格
- android 7.1.2源码定制自动开关机功能