JavaFX程序自动更新主程序功能开发

查看是否能连接上服务器

  if (UpdateUtil.isOnline("www.baidu.com",1,150)){
            ConfirmWin confirmWin = new ConfirmWin();
            if(ConfirmWin.isOk){
               //如果更新需要结束debug服务
                DevToolsDebuggerServer.stopDebugServer();
                RuntimeUtil.restartApp();
            }else {
                LocalServer.startLocalServer();
            }
        }

Confirm询问框实现

package elements;

import javafx.scene.control.Alert;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.ButtonType;

import java.util.Optional;

/**
 * @author: Administrator
 * @date: 2021/05/11 16:57
 * @description:
 */
public class ConfirmWin {
    public static boolean isOk = false;
    public ConfirmWin(){
        // 创建一个确认对话框
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        // 设置对话框的头部文本
        alert.setHeaderText("提示");
        // 设置对话框的内容文本
        alert.setContentText("发现新版本,是否需要在线更新?");
        // 显示对话框,并等待按钮返回
        Optional<ButtonType> buttonType = alert.showAndWait();
        // 判断返回的按钮类型是确定还是取消,再据此分别进一步处理
        // 单击了取消按钮CANCEL_CLOSE
        // 单击了确定按钮OK_DONE
        if (buttonType.get().getButtonData().equals(ButtonBar.ButtonData.OK_DONE)) {
            isOk = true;
        } else {
            isOk = false;
        }
    }
}

效果
在这里插入图片描述

连接服务器状态测试工具

public class UpdateUtil {

    private static final Pattern PING_PATTERN = Pattern.compile("(\\d+ms)(\\s+)(TTL=\\d+)",    Pattern.CASE_INSENSITIVE);

    /**
     * 功能描述: <br>
     * 〈ping命令封装〉
     * @Param: [ipAddress, pingTimes, timeOut]
     * @Return: boolean
     * @Author: Administrator
     * @Date: 2021/05/11 10:01
     */
    public static boolean isOnline(String ipAddress,int pingTimes,int timeOut){
        String pingCommand = "ping " + ipAddress + " -n " + pingTimes    + " -w " + timeOut;
        String result = "";
        InputStream inputStream = null;
        Runtime runtime = Runtime.getRuntime();

        try {
            Process exec = runtime.exec(pingCommand);
            if(exec==null){
                return false;
            }
            inputStream = exec.getInputStream();
            result = CommonUtil.getStringFromInputStream(inputStream,Charset.forName("GB2312"));
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        if(getCheckResult(result)==1){
            return true;
        }
        return false;
    }


    /**
     * 功能描述: <br>
     * 〈若line含有=18ms TTL=16字样,说明已经ping通,返回1,否則返回0.〉
     * @Param: [line]
     * @Return: int
     * @Author: Administrator
     * @Date: 2021/05/11 10:02
     */
    private  static  int getCheckResult(String line) {
        Matcher matcher = PING_PATTERN.matcher(line);
        while (matcher.find()) {
            return 1;
        }
        return 0;
    }
}

应用重启运行时工具

重启程序使用外部命令行重启,需要创建restart.bat文件,内容为 java -jar javafx-web-app.jar

import org.apache.commons.lang3.concurrent.BasicThreadFactory;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.lang.management.ManagementFactory;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class RuntimeUtil {


    public static String exec(String command) {
        StringBuilder sb = new StringBuilder();
        try {
            Process process = Runtime.getRuntime().exec(command);
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            process.getOutputStream().close();
            reader.close();
            process.destroy();
        } catch (Exception e) {
            System.out.println("执行外部命令错误,命令行:" + command+e);
        }
        return sb.toString();
    }

    private static String jps() {
        return exec("jps -l");
    }
    private static String getPid(){
        String name = ManagementFactory.getRuntimeMXBean().getName();
        System.out.println(name);
        return name.split("@")[0];
    }


    public static void restartApp(){
        long period = 1500;
        long initialDelay = 1000;
        String jpsPre = RuntimeUtil.jps();
        System.out.println(jpsPre);
        ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1,
                new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build());
        executorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                if (!jpsPre.equals(RuntimeUtil.jps())){
                    System.out.println("关闭程序");
                    System.exit(0);
                }
            }
        },initialDelay,period, TimeUnit.MILLISECONDS);
        String restartBat = CommonUtil.getFilePath()+ File.separator+"restart.bat";
        String strcmd = "cmd /c start  "+restartBat;
        RuntimeUtil.exec(strcmd);
    }
}

总结
以上已经完成对应用的升级工作,增加了版本升级提示功能。https://gitee.com/lcpsky1991/javafx-web-app.git
后续功能将陆续添加。

### 回答1: JavaFX中的jar包不需要主清单属性,因为其打包方式不同于传统的Java应用程序。传统的Java程序需要在MANIFEST.MF文件中指定主类,而JavaFX应用程序则是通过打包工具(例如Maven或Gradle)来指定主类。 在JavaFX应用程序中,打包器会自动在META-INF/MANIFEST.MF文件中添加必需的清单属性,以确保应用程序能够被正确地启动。这些清单属性包括应用程序的名称、版本号、依赖项和主类信息等。 因此,开发者在打包JavaFX应用程序时不需要手动指定主清单属性,只需在app或plugin.xml文件中指定主类即可。这种打包方式不仅更加简便,而且也使得JavaFX应用程序更易于开发和部署。 ### 回答2: JavaFX是一个开源的客户端应用程序开发框架,它允许开发人员使用Java语言来创建富客户端应用程序以及嵌入式应用程序JavaFX开发大型应用程序时有很多优点,但是有时会遇到一些问题,其中一个问题就是在JavaFX jar中没有主清单属性。 JavaFX jar是在JavaFX中常用的可执行文件,由于JavaFX jar中没有主清单属性,所以在某些情况下就无法正常运行。主清单属性是指在jar文件中指定客户端应用程序主类的属性。如果没有指定主类,就无法启动客户端应用程序。 那么为什么JavaFX jar中没有主清单属性呢? 这是因为JavaFX框架将主类信息保存在一个独立的配置文件中,而不是在jar文件中的清单属性中。这个配置文件称为“JavaFX-Application-Class”文件,它包含客户端应用程序的主类信息。在JavaFX jar文件中,只需要包含这个配置文件即可,而不需要包含主清单属性。 解决这个问题的方法是,将“JavaFX-Application-Class”文件添加到jar文件中,并在打包时指定主类。这样就可以解决JavaFX jar中没有主清单属性的问题。 总之,JavaFX是非常流行的一种开发框架,但也会遇到一些问题,如JavaFX jar中没有主清单属性。理解这个问题的原因,添加配置文件并正确指定主类可以解决这个问题。 ### 回答3: 在Java中,JAR文件是Java存档文件的一种形式。它类似于ZIP文件,但它专为Java类文件和相关资源而设计,并且可以将这些文件打包在一个单独的文件中。JavaFX是一个用于构建富客户端Java应用程序的平台,它也可以将应用程序打包为JAR文件。然而,有时会出现“没有主清单属性”(No main manifest attribute)的错误。 主清单属性是一个包含所有JAR文件必须具有的清单属性的对象。它允许JAR文件被识别为可执行文件,并指定应运行的主类。通常,在打包JAR文件时,必须指定一个包含这些属性的清单文件。如果缺少这些清单属性,运行JAR文件将导致“没有主清单属性”错误。 Javafx jar中没有主清单属性的原因是构建Javafx应用程序时,构建工具(如Maven或Gradle)会自动生成清单文件,并在其中包含主类和其他属性。它们将这些信息添加到JAR文件的META-INF/MANIFEST.MF文件中,以便Javafx应用程序可以被正确识别为可执行文件。因此,Javafx JAR文件无需手动指定主清单属性,因为它已经被包含在JAR文件中了。 但是,如果您手动为Javafx JAR文件编写了清单文件,并且忘记了为其指定主清单属性,则可能会导致“没有主清单属性”错误。在这种情况下,您需要在清单文件中添加Main-Class属性,并将其设置为包含您的主类的完全限定名称。例如: Main-Class: com.example.MainClass 使用这个属性指定主类后,重新打包JAR文件,错误就会消失。 综上所述,Javafx jar中没有主清单属性通常不是问题,因为构建工具会自动为您生成正确的清单文件。但是,如果您手动编写清单文件,请确保包含Main-Class属性,以便能够正确识别JAR文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NewTech精选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值