JavaFX-Plus框架
1.1 弁言
1.1.1 为什么要出这个框架
记得从刚开头学习Java就开头交往JavaFX,从一开头的代码编写图形到厥后经过FXML编写界面,一步步的学习之中渐渐意会JavaFX的强壮与机动,我对JavaFX这弟子不逢时的武艺有了共同的情感,可以说JavaFX的强壮不被很多人了解。
随着不休深化,我也徐徐发觉JavaFx的计划头脑在很多时分是无法满意今世步骤开发头脑的,并且一些功效并不是特别容易被使用,以是特定开发了一套简化开发JavaFx开发历程的框架供各位使用,渴望可以简化各位的利用将精力专注于主要业务。
底下是我在开发历程中碰到的一些成绩,我也针对这些成绩做了简化利用。
1.1.2 FX缺陷1 : 单一控制器痴肥
JavaFX中仿佛都是一个Controller把一切的利用和控件席卷在内里,一个Controller有几百行乃至几千行,步骤固然不必思索模块之间调用成绩了,但是这几千行的代码却很难被办理。
图1 痴肥的controller
1.1.3 FX缺陷2 : 控制类控制才能弱
JavaFX启动的Stage和Controller之间总是隔着远远的距离,并且由于Controller是由JavaFX注入天生的,以是很多非Controller的东西与Controller交换,招致了不得不得使用静态办法大概静态成员这类小本事来完成交换,招致代码变”丑”
1.1.4 FX缺陷3 : JavaBean无法使用Property
JavaFX的计划哲学是一切的JavaBean的属性都是property典范的,但是很多时分我们的JavaBean都是String,Integer这类基本典范,要重新修正类属性所带来的成绩就足以让人让而却步了。
//平凡JavaBean目标
public class Student {
private String name;
private int age;
private String gender;
private String code;
}
//简便的JavaFX bean目标
class Bill {
// 界说一个变量存储属性
private DoubleProperty amountDue = new SimpleDoubleProperty();
// 界说一个getter办法获取属性值
public final double getAmountDue(){return amountDue.get();}
// 界说一个setter办法设置属性值
public final void setAmountDue(double value){amountDue.set(value);}
// 界说一个getter办法获取属性本身
public DoubleProperty amountDueProperty() {return amountDue;}
}
1.1.5 总结
为了处理上述成绩,我开发了一套加强JavaFX功效的框架,来起到简化JavaFX开发历程的成绩。
1.2 特征一:模块化开发
1.2.1 先容
在Java开发历程中很多界面是相似大概反复的,假如可以将这些界面打包成为一个自界说控件,并且经过Scenebuilder拖动就能产生一个控件那将会大大提高我们的开发听从。以是我们提出将不同地区区分为不同的子模块,已到达变小耦合和增速并行开发。寻常我们常常把界面分为顶部东西栏,右方导航栏,右侧的内容栏,假如全部内容都写在一个Controller那么将会招致十分痴肥,我们渴望将不同的地区划分开来分而治之。
1.2.2 怎样创建模块
只需新建一个类承继自FXBaseController,而FXBaseController是承继于Pane,这就是JavaFX-Plus的计划头脑之统统皆为Pane。在类上标上FXController注解,提供FXML文件的地点。假如设置为FXWindow那么将会把这个Controller以单独的Window体现,这里仅仅几句代码就完成了一个简便的窗口步骤。
图2 Controller设置
图3 体现后果
1.2.3 scenebuilder中导入刚刚天生的外表的控件
图4 模块化利用
1.3 特征2 :信号机制
有两个主要标签一个是FXSender,这个标签作用在办法上,标志这个办法为信号发射办法。可以经过设置name修正这个信号发射办法的称呼,默许是函数名字。
发射信号会被订阅这个发射函数的一切FXReceiver吸收,并且发射函数的前往值会作为参数传进这个函数之中。并且这种发送和承受干系是全局的,只需是注册了的Controller都可以举行承受,不范围于同一个Controller。
我们经过一个简便的代码来了解一下。
@FXController(path = “Main.fxml”)
@FXWindow(title = “demo1”)
public class MainController extends FXBaseController{
@FXML
Button btn;
@FXML
Label label;
/**
鼠标之后,体系经过会发射信号,调用一切订阅这个发射信号函数的办法呼应信号
*/
@FXML //绑定鼠标点击事变
@FXSender //标注为信号发射函数
public String send(){
System.out.println(“before sending”); //输入 before sending
return “sending msg”;
}
/**
承受者必需指定要订阅的发送者类名+办法名
并且发送函数的前往值会注入到承受函数的参数中
*/
@FXReceiver(name = “MainController:send”)
public void read(String msg){
System.out.println(“read ” + msg); //输入 read sending msg
}
}
1.4 特征3 :JavaBean 和 JavaFxBean
寻常我们写的JavaBean都是基本典范的,但是JavaFXBean的计划哲学是这些属性都应该是JavaFX界说的Property典范,这十分拦阻于我们的开发,我们如安在不修正JavaBean的条件下,使用到JavaFX的Property的一些优秀办法呢?答案是我们经过反射取得基本典范对应的Property(现在仅限于boolean,double,integer,long,string,float等基本典范,不支持List等封装目标。)
而本次计划的历程中渴望尽力制止利用界面干系的Property等办法,而是直接利用JavaBean类。比如底下代码。
@FXController(path = “Main.fxml”)
@FXWindow(title = “demo1”)
public class MainController extends FXBaseController{
@FXML
Button btn;
@FXML
Label label;
Student student;
int count = 1;
@Override
public void initialize() {
student = (Student)
FXEntityFactory.getInstance().createJavaBeanProxy(Student.class); //工场产生一个学生
student.setName(“Jack”); //设置学生姓名
FXEntityProxy fxEntityProxy =
FXPlusContext.getProryByBeanObject(student); //获取学生署理
Property nameProperty =
fxEntityProxy.getPropertyByFieldName(“name”); //获取Bean对应的Property
//可以经过
fxEntityProxy.getPropertyByFieldName(“list”); 取得List的Property
label.textProperty().bind(nameProperty); //属性绑定
}
@FXML
@FXSender
public String send(){
student.setName(“Jack :” + count); //利用会主动反响到界面上,无需再手动利用界面元素,专心业务局部。
count++;
return “sending msg”;
}
}
@FXEntity
public class Student {
@FXField
private String name; //标志这个类要天生property目标
private int age;
private String gender;
private String code;
@FXField
private List<String> list = new ArrayList<>(); //标志这个List要天生Property目标
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public void addList(String word){
list.add(word);
}
public void delList(String word){
list.remove(word);
}
}
完成后果是:
直接利用JavaBean类,就会经过动态绑定修正界面,不必要讲JavaBean转换为JavaFX Bean可以变小开发中的典范转换。
2.1 怎样使用这个框架
2.1.1 了解内置注解
名字作用参数要求@FXScan扫描@FXEntity和@FXController注解标志的类要扫描的目次默许如今目次之下一切@FXController标志这个类为控件fxml文件地点无@FXWindow标志这个控件要以单独窗口体现title是窗口名字,也可以设置窗口长度宽度无@FXEntity标志JavaBean体系会主动识别@FXField然后包装JavaBean为JavaFXBean重定名@FXField代表这个属性要映射为Property属性@FXSender信号发送者name可以重定名信号@FXReceiver信号吸收函数name是订阅的发射者函数名不成空
2.1.2 两个工场和一个context
在JavaFX-Plus中一切Controller目标和FXEnity目标都必需经过工场创建。
student = (Student) FXEntityFactory.getInstance().createJavaBeanProxy(Student.class); //工场产生一个学生
经过工场创建JavaBean,在创建同时工场会对JavaBean署理并且包装对应的Property属性。
MainController mainController = (MainController)FXFactory.getFXController(MainController.class);
3.1 第一个Demo怎样使用框架创建第一个步骤
@FXScan(base = {“cn.edu.scau.biubiusuisui.example”}) //会扫描带FXController和FXEntity的类举行初始化
public class Demo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXPlusApplication.start(Demo.class); //其他设置和JavaFX相反,这里要调用FXPlusAppcalition的start办法,开头FX-plus加强
}
}
接下去我们天生FXML和Controller
@FXController(path = “Main.fxml”)
@FXWindow(title = “demo1”)
public class MainController extends FXBaseController{
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private Button addBtn;
@FXML
private Button delBtn;
@FXML
private ListView<String> list;
Student student;
@FXML
void addWord(ActionEvent event) {
student.addList(“hello” );
}
@FXML
void delWord(ActionEvent event) {
student.delList(“hello”);
}
@Override
public void initialize() {
student = (Student) FXEntityFactory.createJavaBeanProxy(Student.class);
Property property = FXPlusContext.getEntityPropertyByName(student, “list”);
list.itemsProperty().bind(property);
}
}
Studen类的界说如下
@FXEntity
public class Student {
@FXField
private String name;
@FXField
private List<String> list = new ArrayList<>();
public void addList(String word){
list.add(word);
}
public void delList(String word){
list.remove(word);
}
}
<?xml version=”1.0″ encoding=”UTF-8″?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.layout.Pane?>
<fx:root prefHeight=”400.0″ prefWidth=”600.0″ type=”Pane” xmlns=”http://javafx.com/javafx/8.0.171″ xmlns:fx=”http://javafx.com/fxml/1″ fx:controller=”cn.edu.scau.biubiusuisui.example.MainController”>
<children>
<Button fx:id=”addBtn” layoutX=”432.0″ layoutY=”83.0″ mnemonicParsing=”false” onAction=”#addWord” text=”add” />
<Button fx:id=”delBtn” layoutX=”432.0″ layoutY=”151.0″ mnemonicParsing=”false” onAction=”#delWord” text=”del” />
<ListView fx:id=”list” layoutX=”42.0″ layoutY=”51.0″ prefHeight=”275.0″ prefWidth=”334.0″ />
</children>
</fx:root>
从我们代码可以看出,我们很少有利用界面的利用,并且我们利用的目标都是基本典范的目标,如此的利用十分有利于我们将平凡的项目转换为JavaFX项目,终极运转起来将会是如此
3.2 可拖动窗口和可伸缩窗口
在Javafx中假如一个窗口隐蔽了标题栏那么这个窗口也就没办法拖动和伸缩了,在JavaFX-Plus中你就不需有这种懊恼,只必要在@FXWindow中设置
@FXWindow(title = “demo1”,dragable = true,style = StageStyle.UNDECORATED)
就可以让这个没有标题的窗口可以被拖动并且能拉伸(默许掀开,可以关闭)
Spring支持(未测试)
只必要在在调用Star办法的时分传入重写的getBean办法,如此就可以将bean的产生交给Spring容器办理。
EL表达式绑定 (待开发)
在JavaFX控件的字段外表添加@FXbind可以绑定属性,简化代码利用 例子:
@Inject
Student student;
@FXBind(“test=${student.name”)
Label label;
外表代码可以直接将属性和实体字段绑定
git地点:
https://gitee.com/Biubiuyuyu/JavaFX-Plus

















