Как сделать так, чтобы ваше java-приложение само перезагружалось

Я хочу реализовать 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);
}

2 ответа

Решение

Это из другой темы, но в отличие от принятого вопроса в этой другой теме, этот действительно работает.

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: я считаю, что Марк выложил лучшее решение: /questions/1023919/kak-ya-mogu-perezapustit-prilozhenie-java/1023938#1023938

Ваш вопрос / мои комментарии:

Я хочу реализовать функцию сброса в моем приложении, которая очищает некоторые каталоги, копирует файлы и т. Д., А затем, чтобы завершить процесс, мне нужно перезапустить его. Как сделать так, чтобы приложение запускалось заново?

Это общая особенность / необходимость многих приложений, а не только академических заданий. К сожалению, не существует универсального решения для этого, и все будет зависеть от специфики вашей программы. Если ваша программа очень модульная и написана с умным разделением задач MVC, это становится гораздо проще сделать, часто просто сбрасывая модель в исходное состояние или загружая новую модель в графический интерфейс.

Я думаю, что открытия второго экземпляра и закрытия этого будет достаточно, хотя это не настоящий перезапуск.

Я думаю, что это очень плохая идея. Лучше просто сбросить состояние ваших текстовых компонентов, кнопок, флажков и т. Д. В их исходное состояние. Опять же, чем модульнее ваш код, тем проще это сделать. Каждый отдельный модуль может иметь свой собственный reset() метод, который заботится о его инициализации.

В моем случае я хочу перезагрузить JFrame, состоящий из множества JPanels. Я сделал это:

Опять же, я призываю вас не идти по этому пути.

Вы можете поместить некоторые из ваших JTextComponents в ArrayList для простоты сброса. Например, вы можете сбросить поля GUI внутри reset. Что-то вроде:

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 не очень хорошо. У меня много статических блоков, загрузка сериализованных файлов и т. Д. Мне нужно перезапустить его. Может быть, есть простой способ выполнения приложения.

Извините, но это только наводит меня на мысль, что ваша программа может улучшить свою организацию. Он должен быть сбрасываемым, а если нет, подумайте об изменении его, чтобы это могло быть так. Следует ли оно структуре Model-View-Control? Если нет, подумайте об этом.

Другие вопросы по тегам