JavaFx开发笔记

最近想倒腾一下JavaFx技术,利用掌握的相关知识,进行一些学习开发一些工作中需要用到的小工具岂不是美滋滋。于是花了几天的学习和研究,空闲时开发了一款adb工具,将adb命令进行窗口化。效果如下

工具下载地址点击这里

源码预览及下载点击这里

开发过程中有一些代码需要进行总结

1.Main.java入口函数调用Controller
我们有这样的需求,view中有一些东西需要初始化,想把这些方法写在Controller中,但是是无法在Controller构造函数中进行实现的。所以我们需要在Main中进行Controller的调用
Main.java

        FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
        Parent root = loader.load();
        primaryStage.setTitle("adb窗口工具");
        primaryStage.setScene(new Scene(root, 900, 550));
        primaryStage.setResizable(false);
        primaryStage.show();
        mController = loader.getController();
        mController.initView();//调用initView方法
        mController.setOwnerWindow(primaryStage);

2.从界面中匹配view
基于安卓应用的开发经验,我们需要从sample.fxml上findViewById,获得view。但是JavaFx没有提供类似方法但是提供了以下形式。
sample.fxml

 <TextField fx:id="textInput" maxWidth="250" GridPane.columnIndex="1" GridPane.rowIndex="10"/>

Controller.java

import javafx.fxml.FXML;
public class Controller {
    @FXML
    private TextField textInput;
}

Java文件中变量名需要与fxml文件中fx:id对应

3.fxml中绑定Controller

<!--xxx为最外层布局-->
<xxx xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1"
      fx:controller="top.foxhome.top.adbutil.Controller">
      </xxx>

依据fx:controller属性进行绑定。

5.线程切换
开发过程中使用了new Thread(()->..).start();然后调用Platform.runLater(()->...);进行线程切换结果还是引起了阻塞。后续的研究中使用了以下方法方可进行正常的线程切换。

        new Thread(new Task<E>() {
            @Override
            protected E call() throws Exception {//耗时任务,在自线程中运行
                for (int index=0;index<100;index++){
                    updateMessage("msg:"+index);//发送Message
                    updateProgress(index,100);//发送进度
                }

                return new E();
            }
            @Override
            protected void succeeded() {//UI线程,运行未除错
                super.succeeded();
                E obj=getValue();//获取call的return值
            }

            @Override
            protected void failed() {//UI线程,运行出错
                super.failed();
            }

            @Override
            protected void updateMessage(String message) {//UI线程,接收Message
                super.updateMessage(message);
            }

            @Override
            protected void updateProgress(long workDone, long max) {//UI线程,接收进度
                super.updateProgress(workDone, max);
            }
        }).start();

6.绑定点击事件
我们需要一个按钮或者view能够接收到用户的交互,需要进行事件的绑定,列如一个按钮的点击事件
sample.fxml

<Button fx:id="installApk" mnemonicParsing="false" onAction="#installApk" text="安装APK"/>

当我们输入onAction="#installApk"IDE即可进行代码提示,我们依据提示在与之绑定的controller创建对应的方法即可。
Controller.java

    public void installApk(ActionEvent actionEvent) {
    }

另外推荐使用IDE提示点击进行自动创建,手动创建比较麻烦。

7.按钮的禁用和启用
与安卓开发不同的是,安卓的设计思路是设置是否可用JavaFX的设计思路是设置是否禁用

installApk.setDisable(true);//禁用
installApk.setDisable(false);//启用

8.应用的退出
如果直接点击窗口上的退出键,JVM并没有进行回收,导致jar文件依旧处于运行之中。所以我们需要监听界面的退出进行jvm回收。

//Stage primaryStage
primaryStage.setOnCloseRequest(event -> {
            event.consume();
            System.exit(0);
        });
        primaryStage.show();

9.支持文件拖动到输入框
我们使用应用是通常有拖动文件到输入框的需求,拖动文件后将文件绝对路径输入到输入框。
sample.fxml

<TextArea onDragExited="#getFilePath" fx:id="cmdIput" maxWidth="430" GridPane.columnIndex="1" GridPane.rowIndex="2"/>

通过onDragExited进行事件绑定。
Controller.java

    public void getFilePath(DragEvent event) {
        List<File> files = event.getDragboard().getFiles();
    }

10.Controller初始化回调
除使用1中提到的方式进行初始化以外你还可以在Controller进行初始化

    @FXML
    private void initialize() {
        System.out.println("initialize");
    }

发表回复

CAPTCHAis initialing...