Можно ли обновлять программные файлы в JavaFX во время работы экземпляра?

Я создаю систему управления запасами и создал кнопку, которая открывает новый FXML для ввода нового элемента в базу данных. Я создал возможность добавлять изображение, и оно обновляет столбец изображений в базе данных с помощью URL-адреса, и когда я нажимаю «Сохранить», оно сохраняет копии изображения из исходного местоположения в целевое местоположение (которое является пакетом в программе). Если я сохраню и закрою программу, я смогу обновить проект в eclipse, снова войти в программу, и вновь добавленный элемент будет отображаться в таблице, заполненной из базы данных, без каких-либо проблем.

У меня проблема в том, что когда я нажимаю кнопку «Сохранить», я хотел бы, чтобы она «обновляла» файлы и пакеты программ, поэтому, когда я запрашиваю базу данных деталей, она будет отображать недавно добавленные детали, а не выдавать мне ошибку из-за отсутствия изображения. в пакете изображения, который я создал (он отображается там, когда программа закрыта и обновлена). Можно ли обновить эти пакеты изображений с помощью кода? Должны ли изображения храниться во внешнем файле? Если нет, то можно ли сохранять изображения в пакеты программ без использования абсолютного пути?

Код, который у меня есть до сих пор:

// Event Listener on Button[#saveItemBtn].onAction
@FXML
public void saveNewItemClicked(ActionEvent event) {
    try{
        this.dbState = (String) databaseChoiceBox.getValue();

        DBConnection dBC = new DBConnection();
        con = dBC.getDBConnection();
        String maxSQL = "SELECT MAX(id) FROM " + dbState + "_parts_list";
        ResultSet rs = con.createStatement().executeQuery(maxSQL);

        int idNumber = rs.getInt(1);
        idNumber++;

        quantity = Integer.parseInt(quantityTxt.getText());
        min = Integer.parseInt(minTxt.getText());
        max = Integer.parseInt(maxTxt.getText());


        double price = Double.parseDouble(priceTxt.getText());
        SelectedItem selectedItem = new SelectedItem();
        selectedItem.setId(idNumber);
        selectedItem.setQuantity(quantity);
        selectedItem.setMin(min);
        selectedItem.setMax(max);
        selectedItem.setEquipment_id(equipmentIDTxt.getText());
        selectedItem.setEquipment_group(equipmentGroupTxt.getText());
        selectedItem.setPrice(price);
        selectedItem.setManufacturer_name(manufacturerNameTxt.getText());
        selectedItem.setModel_number(modelNumberTxt.getText());
        selectedItem.setVendor_name(vendorNameTxt.getText());
        selectedItem.setVendor_part_number(vendorPartNumberTxt.getText());
        selectedItem.setTolmar_part_number(tolmarPartNumberTxt.getText());
        selectedItem.setDescription(descriptionTxt.getText());
        selectedItem.setAdditional_notes(additionalNotesTxt.getText());
        selectedItem.setPart_location(locationTxt.getText());
        if (img != null) {
            selectedItem.setImage("/" + dbState + "Images/" + imagePath);   
        } else {
            selectedItem.setImage("/img/NoImageFound.png");
        }
        selectedItem.setDepartment(databaseChoiceBox.getValue().toLowerCase());

        String sql = "INSERT INTO " + dbState + "_parts_list VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

        PreparedStatement myStmt = con.prepareStatement(sql);
        myStmt.setInt(1, idNumber);
        myStmt.setString(2, selectedItem.getManufacturer_name());
        myStmt.setString(3, selectedItem.getModel_number());
        myStmt.setString(4, selectedItem.getVendor_name());
        myStmt.setString(5, selectedItem.getVendor_part_number());
        myStmt.setString(6, selectedItem.getTolmar_part_number());
        myStmt.setString(7, selectedItem.getPart_location());
        myStmt.setDouble(8, selectedItem.getPrice());
        myStmt.setInt(9, selectedItem.getQuantity());
        myStmt.setInt(10, selectedItem.getMin());
        myStmt.setInt(11, selectedItem.getMax());
        myStmt.setString(12, selectedItem.getImage());
        myStmt.setString(13, selectedItem.getEquipment_group());
        myStmt.setString(14, selectedItem.getEquipment_id());
        myStmt.setString(15, selectedItem.getAdditional_notes());
        myStmt.setString(16, selectedItem.getDescription());
        myStmt.setString(17, selectedItem.getDepartment());
        myStmt.executeUpdate();
        saveStatusLbl.setText("New Item Saved");
        Path source = Paths.get(img);
        Path target = Paths.get("E:/Programming/workspace/Inventory Management System 4/src/" + dbState + "Images/", file.getName());
        try {
            //replace existing file using java nio package
            Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
        } catch (IOException e) {
            e.printStackTrace();
        }

        con.close();
        PauseTransition delay = new PauseTransition(Duration.seconds(2));
        delay.setOnFinished( e -> window.close() );
        delay.play();

        }catch(Exception exc){
            System.out.println(exc);
            exc.printStackTrace();
        }       
}

person dubski    schedule 17.03.2016    source источник
comment
технически мне не нужно закрывать программу. Я смог нажать на свою IDE и F5, чтобы обновить, и я вижу, как сохраненное изображение всплывает в моем пакете, возвращаюсь к программе, и она не выдает ошибок и показывает новый элемент в tableView. Мне просто интересно, есть ли код для этого, когда я нажимаю кнопку «Сохранить».   -  person dubski    schedule 17.03.2016


Ответы (2)


Вы определенно не должны хранить свои файлы данных среди ваших файлов классов. В реальном сценарии, когда вы связали свое приложение, это все равно не сработает.

person mipa    schedule 17.03.2016
comment
Спасибо за ваш ответ, знаете ли вы какие-нибудь хорошие ресурсы о том, как это обычно делается? Мне не очень повезло искать в Интернете, и, вероятно, я задаю неправильный вопрос, спасибо! - person dubski; 17.03.2016

Вам следует избегать изменения ресурсов приложения во время его работы.

Конечно, вы можете попытаться заставить его работать, поигравшись с ClassLoaders, например. используйте URLClassLoader, но ИМХО гораздо проще не хранить файлы как ресурсы, а хранить их в каталоге не внутри пути к классу и вместо этого получать доступ к этим файлам. Вы можете получить строку URL из Path p, используя:

p.toUri().toURL().toExternalForm()
person fabian    schedule 17.03.2016
comment
спасибо за ответ, мне нужно будет провести больше исследований по хранению файлов для программы. В базе данных у меня есть URL-адрес, указывающий, где находятся изображения. Я не совсем уверен, как каждый раз указывать на изображения одинаково, если программу можно сохранить в любом месте на любом диске, и мне пришлось бы хранить изображения в определенном месте на рабочем диске и иметь жесткий код, записанный на указать туда? Как это обычно делается? у вас есть ссылка, которая могла бы указать мне правильное направление того, как лучше всего хранить подобную информацию, мне не очень повезло искать себя. Спасибо! - person dubski; 17.03.2016