Java просит перезаписать jfilechooser

У меня есть функция, которая должна получить путь к файлу, введенному в текстовый ввод jfilechooser, и передать его String. Проблема в том, что я хочу проверить перезапись, если файл уже существует. У меня есть представление о том, как это сделать, однако моя проблема заключается в том, что если ответить нет на JOptionPane, JFileChooser все равно закроется, потому что кнопка сохранения уже была нажата. Теперь мне нужно, чтобы при ответе нет программа возвращалась к JFileChooser, по-прежнему запрашивая имя.

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

Вот код моей функции, еще не завершенный, потому что я не знаю, как с ним обращаться.

`public String FileSavePath()throws NullPointerException
    {
        File f=null;
        String theFilepath=null;
        JFileChooser FileChooser = new JFileChooser();
        if(FileChooser.showSaveDialog(null)==JFileChooser.APPROVE_OPTION)
        {
            theFilepath=FileChooser.getSelectedFile().getAbsolutePath();
            f=FileChooser.getSelectedFile();
            //System.out.println(theFile);
            if(f.exists())
            {
                int result = JOptionPane.showConfirmDialog(this,"The file exists, overwrite?",
                        "Existing file",JOptionPane.YES_NO_CANCEL_OPTION);
                if(result==JOptionPane.YES_OPTION)
                           {
                   return theFilepath;

                  }
          else // here is what I should do if the user answers 'no' or cancels/closes the JOptionPane
        }
        else return null;
        return theFilepath;

    }`

person Mihai Bujanca    schedule 25.11.2012    source источник
comment
Это старый вопрос, но он был первым в результатах поиска. Довольно красивое решение можно найти по адресу: stackoverflow.com/a/3729157/589525.   -  person Jaap D    schedule 13.09.2019


Ответы (1)


Вам нужно поместить свой запрос в цикл до тех пор, пока пользователь не сможет предоставить вам приемлемый ответ...

public String FileSavePath() throws NullPointerException {

    boolean acceptable = false;
    String theFilepath = null;

    do {
        theFilepath = null
        File f = null;
        JFileChooser FileChooser = new JFileChooser();
        if (FileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
            theFilepath = FileChooser.getSelectedFile().getAbsolutePath();
            f = FileChooser.getSelectedFile();
            //System.out.println(theFile);
            if (f.exists()) {
                int result = JOptionPane.showConfirmDialog(this, "The file exists, overwrite?",
                        "Existing file", JOptionPane.YES_NO_CANCEL_OPTION);
                if (result == JOptionPane.YES_OPTION) {
                    acceptable = true;
                }
            } else {
                acceptable = true;
            }
        } else {
            acceptable = true;
        }
    } while (!acceptable);

    return theFilepath;

}
person MadProgrammer    schedule 25.11.2012
comment
Да, но это также будет выполняться снова через поток FileChooser.showSaveDialog. Моя идея заключалась в том, чтобы каким-то образом остановить закрытие FileChooser, если файл ничего не перезаписывает или пользователь не одобряет перезапись. Ваша идея очень похожа на повторный запуск всей функции, но выполняется итеративно, а не рекурсивным FileSavePath(), если (!acceptable) истинно. Спасибо за ваш ответ, но я ищу что-то более эффективное, я очень отчаянно нуждаюсь в эффективности :) - person Mihai Bujanca; 26.11.2012
comment
Насколько мне известно, JFileChooser не предоставляет никакого способа перехватить событие утверждения. Единственный способ узнать, что пользователь сделал выбор, - это когда средство выбора возвращается (и модальное диалоговое окно, используемое средством выбора, закрывается) - person MadProgrammer; 26.11.2012
comment
На данный момент, я полагаю, я оставлю все как есть, но мне все еще нужен способ сделать это более эффективным, моему приложению это очень нужно, пока что оно слишком медленное (со многими другими открытыми процессами, заняло до 30 секунд для jfilechooser, чтобы открыть) С меньшим количеством процессов, но затмение все еще открыто, в любом случае до 7-10 секунд, так что у меня будет раздраженный пользователь. Также заметил, что во второй раз, когда я открываю jfilechooser, это занимает намного меньше времени (до 5 секунд со многими процессами, до 1,5 секунд с меньшим количеством). Я обдумываю идею попробовать поток, который будет происходить где-то во время выполнения showConfirmDialog. - person Mihai Bujanca; 26.11.2012
comment
Где-то там перед тем, как избавиться от jfilechooser - person Mihai Bujanca; 26.11.2012
comment
Помните, что Swing НЕ является потокобезопасным. Вы должны взаимодействовать с компонентами пользовательского интерфейса только в контексте потока диспетчеризации событий. В вашем случае я бы создал фабрику или служебный класс, который будет лениво загружать JFileChooser и поддерживать активную ссылку на него в течение всего времени работы приложения (или какого-либо другого события), это ускорит вызов метода в будущем. - person MadProgrammer; 26.11.2012
comment
Может быть, я могу сделать как-то обработчик кнопки сохранения, чтобы я еще мог получить имя файла и проверить его существование, но JFileChooser не должен распоряжаться, пока работа с ним не будет выполнена. Стоит попробовать, хотя вряд ли это сработает. Я рассматриваю возможность сохранения активной ссылки, так как пользователь, вероятно, сохранит свою работу в конце сеанса, поэтому ссылка вряд ли замедлит работу каких-либо других функций приложения. Или поддерживать ссылку на короткий промежуток времени, учитывая, что пользователь может передумать, так как он не сохраняет окончательно через 5 минут :) - person Mihai Bujanca; 26.11.2012