JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。

1. 整体方案

JavaFX.应用版本检测、自动更新主要涉及一下步骤:

  1. 读取本地应用版本
  2. 拉取远程版本并比较两个版本
  3. 如果需要升级,那么拉取更新历史
  4. 弹出升级控制窗口
  5. 用户选择升级时,拉取升级包解压,重启应用
  6. 用户选择忽略时,本地版本标志为忽略版本
  7. 用户选择取消时,隐藏升级控制窗口

2. 版本检测

版本检测功能最好采用JavaFX的Task异步进行,下面是一个实现方案:

class UpgradeTask extends Task<Void> {

    private final UpgradeBinding binding;
    private final Properties config;
    private final String currentVersion;

    public UpgradeTask(UpgradeBinding binding, String currentVersion) {
        this.binding = binding;
        this.currentVersion = currentVersion;
        config = new Properties();
        try (InputStream is = this.getClass().getResourceAsStream("/upgrade.properties")) {
            config.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @Override
    protected Void call() {
        String versionAPI = config.getProperty("version.api");
        String remoteVersion = HTTP.get(versionAPI);
        if (!Objects.equals(currentVersion, remoteVersion)) {
            Platform.runLater(() -> {
                binding.upgrade.set(true);
                binding.version.set(remoteVersion);
            });

            String changelogAPI = config.getProperty("changelog.api");
            String changelog = HTTP.get(changelogAPI);

            Platform.runLater(() -> binding.changelog.set(changelog));
        }
        return null;
    }
}

升级服务器信息配置在upgrade.properties配置文件中,在主应用打包的时候一起打包。

3. UI.设计

这里只是简单的开发了一个控制窗口,具体可以根据需要进一步完善:

class UpgradeUI {

    private final UpgradeBinding binding;
    private final Stage stage;

    public UpgradeUI(UpgradeBinding binding, Stage owner) {
        this.stage = new Stage();
        this.stage.initOwner(owner);
        this.binding = binding;
    }

    public void show() {
        Label version = new Label();
        version.textProperty().bind(binding.version);

        TextArea textArea = new TextArea();
        textArea.textProperty().bind(binding.changelog);
        textArea.setDisable(false);

        Button cancel = new Button("取消");
        cancel.setOnMouseClicked(event -> stage.close());

        VBox root = new VBox();
        root.setPadding(new Insets(20));
        root.setSpacing(20);

        HBox vContainer = new HBox();
        vContainer.setSpacing(10);
        vContainer.setAlignment(Pos.CENTER_LEFT);
        vContainer.getChildren().addAll(new Label("最新版本:"), version);

        VBox cContainer = new VBox();
        cContainer.setSpacing(10);
        cContainer.getChildren().addAll(new Label("更新内容:"), textArea);

        HBox bContainer = new HBox();
        bContainer.setSpacing(20);
        bContainer.setAlignment(Pos.CENTER);
        bContainer.getChildren().addAll(new Button("更新"), new Button("跳过"), cancel);

        root.getChildren().addAll(vContainer, cContainer, bContainer);

        stage.setScene(new Scene((root)));
        stage.setWidth(320);
        stage.setHeight(240);
        stage.setResizable(false);
        stage.getIcons().clear();
        stage.getIcons().add(new Image("logo.jpg"));
        stage.show();
    }
}

注意上面仅实现了取消功能,如果需要实现更新和跳过功能需要进一步完善,即整体方案中提到的第5点和第6点。

4. 流程控制

在主进程中异步启动升级检测线程:

public class Sample03 extends Application {

    @Override
    public void start(Stage stage) {
        StackPane root = new StackPane();
        root.getChildren().add(new Label("版本:0.1"));

        stage.setScene(new Scene(root));
        stage.setWidth(640);
        stage.setHeight(480);
        stage.setTitle("版本检测 + 自动更新");
        stage.getIcons().clear();
        stage.getIcons().add(new Image("logo.jpg"));
        stage.show();

        UpgradeBinding binding = new UpgradeBinding();
        UpgradeUI ui = new UpgradeUI(binding, stage);
        UpgradeTask task = new UpgradeTask(binding, "0.1");
        task.setOnSucceeded(e -> {
            if (binding.upgrade.get()) {
                ui.show();
            }
        });
        Thread t = new Thread(task);
        t.setDaemon(true);
        t.start();
    }
}

最终效果:

本文转自 https://www.cnblogs.com/michong2022/p/17034796.html,如有侵权,请联系删除。在这里插入代码片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/874315.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

手机TF卡格式化后数据恢复:方法、挑战与预防措施

在现代生活中&#xff0c;‌手机已经成为我们不可或缺的一部分&#xff0c;‌而TF卡&#xff08;‌即MicroSD卡&#xff09;‌作为手机存储的扩展&#xff0c;‌更是承载了我们大量的重要数据。‌然而&#xff0c;‌不慎的格式化操作往往导致数据丢失&#xff0c;‌给用户带来不…

【重学 MySQL】五、MySQL 的卸载

【重学 MySQL】五、MySQL 的卸载 停止MySQL服务卸载MySQL程序删除残余文件清理注册表删除环境变量配置重启电脑 MySQL的卸载过程需要仔细操作&#xff0c;以确保彻底卸载并清理所有相关文件和配置。 停止MySQL服务 打开任务管理器&#xff1a;右键点击任务栏空白处&#xff0…

C++笔记---list

1. list的介绍 list其实就是就是我们所熟知的链表&#xff08;双向循环带头结点&#xff09;&#xff0c;但其是作为STL中的一个类模板而存在。 也就是说&#xff0c;list是可以用来存储任意类型数据的顺序表&#xff0c;既可以是内置类型&#xff0c;也可以是自定义类型&…

单词排序C++实现

代码如下&#xff1a; #include<iostream> #include<string> #include<fstream> #include<map> #include<iomanip> #include<algorithm> #include<vector>int read_file(std::map<std::string,int> &map_words) {std::st…

大牛直播SDK最经典的一句

搜索引擎搜大牛直播SDK&#xff0c;居然提示我搜“大牛直播SDK最经典的一句”&#xff0c;闲来无事&#xff0c;点开看看&#xff0c;AI智能问答&#xff0c;给出了答案&#xff1a; ‌大牛直播SDK最经典的一句是&#xff1a;"我们只做最擅长的部分,我们不做的,提供对接接…

[进阶]面向对象之多态(二)

文章目录 多态调用成员的特点多态的优势和弊端 多态调用成员的特点 变量调用:编译看左边,运行也看左边方法调用:编译看左边,运行看右边 多态的优势和弊端 优势&#xff1a; 在多态形式下&#xff0c;右边对象可以实现解耦合&#xff0c;便于扩展和维护定义方法的时候&…

mysql高级sql

文章目录 一&#xff0c;查询1.按关键字排序1.1按关键字排序操作(1)按分数排序查询&#xff08;不加asc默认为升序&#xff09;(2)按分数降序查询&#xff08;DESC&#xff09;(3)使用where进行条件查询(4)使用ORDER BY语句对多个字段排序 1.2使用区间判断查询&#xff08;and/…

ESP32 TCP通信交换数据Mixly Arduino编程

TCP通信交换数据 在ESP32与ESP32或其它局域网络内主机间传输数据时&#xff0c;TCP是很方便的&#xff0c;特别当我们连接互联网后ESPnow不能用&#xff0c;MQTT又不稳定发送大量的数据&#xff0c;同时蓝牙有其它用途时&#xff0c;那么学会TCP通信协议就变得十分重要。 一、…

【开源分享】vsomeip 安装、编译、运行步骤笔记

文章目录 1. 摘要2. 安装、编译2.1 开发环境说明2.2 安装依赖2.3 获取代码2.4 编译代码2.5 安装 3. 测试验证参考 1. 摘要 本文主要描述 vsomeip 的安装、编译与运行步骤。下载源码&#xff0c;安装必要依赖&#xff0c;如Boost和CMake。通过CMake配置编译 vsomeip 库&#xf…

2024年10款好用的图纸加密软件推荐|企业图纸的守护神

在数字化时代&#xff0c;图纸数据的安全性是企业不可忽视的重要任务。随着技术的不断进步&#xff0c;图纸加密软件成为了保护企业知识产权和敏感数据的关键工具。以下是2024年推荐的10款好用的图纸加密软件&#xff0c;它们各具特色&#xff0c;能够满足不同企业的需求。 1.…

Java数组的定义及遍历

数组的声明 长度不能超过定义的长度。超过则会报错通过下标来访问 数组的遍历 最常用最简单的方法是增强for循环。

【解决bug之路】npm install node-sass(^4.14.1)连环报错解决!!!(Windows)

有关node-sass的深入分析可参考&#xff1a;又报gyp ERR&#xff01;为什么有那么多人被node-sass 坑过&#xff1f; 主要有如下三方面错误&#xff0c;请自查&#xff1a; 1.node&#xff0c;npm版本需与node-sass版本匹配&#xff0c;像node-sass&#xff08;^4.14.1&#x…

第三部分:4---进程地址空间

目录 数组的空间分配解析&#xff1a; 物理地址和虚拟地址&#xff1a; 虚拟地址空间&#xff1a; 进程地址空间的本质&#xff1a; 为什么要有进程地址空间&#xff1f; 页表对进程访问内存的检查&#xff1a; 进程地址空间和页表如何关联起来&#xff1f; 进程的独立…

保姆级离线+windows环境+私有化部署大模型

基于gis数据的高敏感高保密性要求&#xff0c;相信gis的小伙伴都有如下的需求&#xff1a;在内网&#xff0c;无外网环境下&#xff0c;部署自己的私有化大模型。 1.环境背景&#xff1a; 没有Linux环境&#xff0c;只是windows 无外网&#xff0c;内网环境 2.安装部署过程…

数据结构与算法1: 链表

基础知识 链表可以被想象为一系列的节点&#xff0c;每个节点至少有一个指针指向下一个节点&#xff0c;在最后一个节点&#xff0c;用null pointer来表示链表的结束。 链表的创建速度通常很快&#xff0c;在表头和表尾的插入也很快&#xff08;O(1)&#xff09;&#xff0c;…

HCIA--实验十三:VLAN间通信子接口实验/双单臂路由实验

一、实验内容 1.需求/要求&#xff1a; 将两个单臂路由通过两台交换机连接起来&#xff0c;成为双臂路由&#xff0c;并探讨这么做的原因。实现全网通&#xff0c;让任何一台主机之间都可以通信。 二、实验过程 1.拓扑图&#xff1a; 2.步骤&#xff1a; 1.给PC配置ip地址…

Oceanbase Restore Point实践

官网链接&#xff1a;Restore Point-V3.2.4-OceanBase 数据库文档-分布式数据库使用文档 在很多应用系统中&#xff0c;用户需要查询数据库中的某个时间点&#xff0c;或者特定版本的数据来完成一些数据分析或汇总之类的操作。 OceanBase 数据库在 V2.2.7x 版本中提供了 Restor…

大学生租房平台:SpringBoot框架的设计与实现

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专业…

5.第二阶段x86游戏实战2-认识内存

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 工具下载&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd6tw3 提…

分享从零开始学习网络设备配置--任务6.3 使用基本ACL限制网络访问

任务描述 某公司构建了互联互通的办公网&#xff0c;为保护公司内网用户数据的安全&#xff0c;该公司实施内网安全防范措施。公司分为经理部、财务部和销售部&#xff0c;分属3个不同的网段&#xff0c;3个部门之间用路由器进行信息传递。为了安全起见&#xff0c;公司领导要求…