【问题标题】:How to make your java application restarts itself [duplicate]如何使您的Java应用程序自行重启[重复]
【发布时间】:2018-10-13 05:44:10
【问题描述】:

我想在我的应用程序中实现reset 功能,它会清理一些目录、复制文件等,然后为了完成该过程,我需要重新启动它。

如何让应用程序自行重新运行?我认为打开第二个实例并关闭这个就足够了,尽管它不是真正的重启。

我的应用程序的核心是类扩展JFrame,但是有很多静态块在程序执行时读取类的扩展。我需要以编程方式重新启动我的应用程序,以便再次创建/执行所有静态集合和块。

就这样开始了。

SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            new Window().createGUI();
        }
    });

这似乎工作正常:

public void restart() {
    /*  dispose();
    Window.main(null);*/
    StringBuilder cmd = new StringBuilder();
    cmd.append(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java ");
    for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
        cmd.append(jvmArg + " ");
    }
    cmd.append("-cp ").append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(" ");
    cmd.append(Window.class.getName()).append(" ");

    try {
        Runtime.getRuntime().exec(cmd.toString());
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.exit(0);
}

【问题讨论】:

  • @DNA 之前尝试过对我不起作用。
  • 非常不完整,我担心你的问题是。为我们考虑澄清它。非常好。是的,嗯。 GUI,是吗?摇摆,是吗?
  • @Brandon:我认为你的力量很强。他专注于他的代码解决方案,可能会错过更好的整体问题解决方案。

标签: java application-restart


【解决方案1】:

这是来自另一个主题,但与另一个主题中接受的问题相反,这个问题确实有效。

public void restart() {
          StringBuilder cmd = new StringBuilder();
            cmd.append(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java ");
            for (String jvmArg : ManagementFactory.getRuntimeMXBean().getInputArguments()) {
                cmd.append(jvmArg + " ");
            }
            cmd.append("-cp ").append(ManagementFactory.getRuntimeMXBean().getClassPath()).append(" ");
            cmd.append(Window.class.getName()).append(" ");

            try {
                Runtime.getRuntime().exec(cmd.toString());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.exit(0);
    }

27/02/2018:我相信 Mark 发布了更好的解决方案:https://stackoverflow.com/a/48992863/1123020

【讨论】:

  • 关闭应用程序不起作用。
  • @ralphspoon 几年后我尝试了这种方法,但它停止了工作,但当时我发布了它正在执行和正确执行的代码。只是告知。也许它取决于环境。我同时更换了操作系统。
  • 这会累积 JAVA_TOOL_OPTIONS,如果全局设置的话。
【解决方案2】:

你的问题/我的 cmets:

我想在我的应用程序中实现重置功能,它会清理一些目录、复制文件等,然后为了完成该过程,我需要重新启动它。如何让应用程序自行重新运行?

这是许多应用程序的共同特征/需求,而不仅仅是学术作业。不幸的是,没有一种万能的解决方案,这完全取决于您的程序的具体情况。如果您的程序非常模块化并且使用智能的 M-V-C 关注点分离编写,那么执行此操作会变得容易得多,通常只需将模型重置为其初始状态,或者将新模型加载到 GUI 中。

我认为打开第二个实例并关闭这个就足够了,尽管它不是真正的重启。

我认为这是一个非常糟糕的主意。最好简单地将文本组件、按钮、复选框等的状态重置为原始状态。同样,您的代码越模块化,就越容易做到。每个单独的模块都可以有自己的 reset() 方法来负责初始化它。

就我而言,我想重新加载由许多 JPanel 组成的 JFrame。我已经这样做了:

再次,我敦促你不要走这条路。

您可以将一些 JTextComponents 放入 ArrayList 以便于重置。例如,您可以在 reset 中重置 GUI 字段。比如:

public void reset() {
  // assuming you have an ArrayList of JTextComponents called textComponents
  for (JTextComponent textComponent : textComponents) {
    textComponent.setText("");
  }

  // same if you had a bunch of comboboxes in a List called comboBoxes
  for (JComboBox comboBox : comboBoxes) {
    comboBox.setSelection(-1); // consider removing listeners first, then re-adding them

  //   etc for other components
  }
}

编辑

我发现我的解决方案 -> 处理 JFrame 不太好。我有很多静态块,加载序列化文件等。我需要重新启动它。也许有一种简单的方法可以让应用程序自行执行。

抱歉,这仅表明您的程序可能会改进其组织结构。它应该是可重置的,如果不是,请考虑更改它以使其可以重置。它遵循模型-视图-控制结构吗?如果没有,请考虑这样做。

【讨论】:

  • 我发现我的解决方案 -> 处理 JFrame 不太好。我有很多静态块,加载序列化文件等。我需要重新启动它。也许有一种简单的方法可以让应用程序自行执行。
  • @Yoda:请参阅编辑回答。
  • @Yoda 从内部重新启动 Java 进程可能会很复杂。您需要考虑类路径、确切的命令行、系统属性,谁知道还有什么。气垫船是正确的。最简单/最可靠的解决方案是将应用程序的状态对象设计为可重置,以便您可以重置它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
相关资源
最近更新 更多