Ваш подход (который, насколько я понимаю, заключается в попытке программно изменить исходный файл, который создает файл свойств) не будет работать во время развертывания по ряду причин.
Во-первых, исходные файлы, как правило, недоступны во время выполнения: ваш файл jar содержит файлы классов и другие ресурсы, необходимые для запуска приложения, но обычно это не исходный код (и нежелательно включать его в приложение, в общем).
Во-вторых, вы пытаетесь найти этот файл с относительного пути, пройденного до Paths.get(..)
. Это будет разрешено относительно рабочего каталога, который по существу произволен (в основном «где приложение было запущено»). Поэтому, даже если исходный код был доступен во время выполнения, это не был бы надежный способ его найти. (Мое предположение заключается в том, что ваш отладчик работает с рабочим каталогом, случайно установленным в родительский каталог src
, но при запуске файла jar наиболее вероятным расположением рабочего каталога является каталог, в котором находится файл jar. просто угадайте: это действительно зависит от конфигурации вашей IDE, отладчика и т. д.)
В-третьих, и, возможно, самое главное, даже если код действительно находит исходный файл и переписывает его, это все, что он сделает. В следующий раз, когда вы запустите приложение из файла jar, он не будет волшебно знать, что есть новая версия исходного кода, который должен быть скомпилирован, а затем результирующий файл (ы) класса, встроенный в файл jar. Поэтому вам нужно будет также включить код для компиляции новой версии вашего исходного кода (где вы получите компилятор: AFAIK не все Java-среды будут включать компилятор), а затем программно вставить новые файлы классов в файл jar (как вы можете понять, где находится файл jar: это, конечно, нетривиально, и я не думаю, что это можно сделать надежным образом). Что делать, если текущий пользователь не имеет прав на запись каталога, содержащего банку (что довольно распространенный сценарий?)?
Обычный способ загрузки и сохранения значений конфигурации запуска заключается в использовании java.util.Properties
API. Для хранения файла свойств вам нужно иметь внешнее местоположение, которое может быть определен на компьютере пользователя: удобным способом это создать каталог, предназначенный для приложения, в домашнем каталоге пользователя. Доступ к домашнему каталогу пользователя можно получить через System.getProperty("user.home");
(Системное свойство user.home
является одним из тех, что является guaranteed to exist.).
Я бы рекомендовал использовать отдельный класс для управления свойствами конфигурации. Например:
И теперь вы можете использовать его в своем приложении.Просто загрузите свойства в методе init()
и сохраните их обратно в методе stop()
. Обратите внимание, что при выполнении этого будет создан каталог с именем .myApp
в вашем домашнем каталоге и файл с именем startup.properties
внутри него.
import java.io.IOException;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class StartupPropertiesExample extends Application {
private PropertiesAccessor config ;
private CheckBox value1 ;
private CheckBox value2 ;
@Override
public void init() {
config = new PropertiesAccessor(".myApp/startup.properties");
}
@Override
public void start(Stage primaryStage) {
value1 = new CheckBox("Value 1");
value2 = new CheckBox("Value 2");
value1.setSelected(config.getBooleanValue("config.value1"));
value2.setSelected(config.getBooleanValue("config.value2"));
Button exit = new Button("Exit");
exit.setOnAction(e -> Platform.exit());
VBox root = new VBox(10, value1, value2, exit);
root.setPadding(new Insets(10));
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
@Override
public void stop() {
config.updateBooleanValue("config.value1", value1.isSelected());
config.updateBooleanValue("config.value2", value2.isSelected());
try {
config.writeProperties();
} catch (IOException exc) {
System.err.println("Warning: could not save properties");
exc.printStackTrace(System.err);
}
}
public static void main(String[] args) {
launch(args);
}
}
Что вы здесь делаете? Похоже, вы пытаетесь манипулировать * исходным * файлом и для него иметь эффект во время выполнения. Как вы компилируете файл, создаете банку и динамически загружаете класс во время выполнения? Помимо всего прочего, вы не можете ожидать, что каталог 'src' будет доступен во время выполнения. Вы знаете, что Java компилируется, правильно? –
У меня есть ряд флажков, которые должны помнить, что их состояния выбраны (или нет) каждый раз, когда я ЗАКРЫВАЮ и ПЕРЕПУСКАЮ программу. Когда я закрываю приложение при изменении состояния флажка, оно должно начинаться так, как оно было закрыто. Я создал файл настроек, и указанная выше функция должна подавать файл настроек, который в свою очередь передает исходное состояние флажков. Я знаю, что расположение файла настроек не является идеальным. Но изменение папки для попытки не помогло. Является ли местоположение файла важным для работы функции? Он работает все правильно от отладчика – rainer
Если это файл настроек, то почему у него есть расширение '.java'? Вы должны использовать текстовый файл, возможно, в формате, совместимом с ['java.util.Properties'] (http://docs.oracle.com/javase/8/docs/api/java/util/Properties.html). Что касается расположения файлов, папка 'src', очевидно, недоступна во время выполнения, а' Paths.get (...) 'будет разрешаться относительно рабочего каталога. Я бы рекомендовал использовать домашний каталог пользователей ('System.getProperty (« user.home »)) и создать в нем каталог и файл. –