Groovy/Java — Средство выбора файлов не использует потоки JavaFX или Event?

Я разрабатываю приложение, которое в течение некоторого времени, вероятно, будет использовать только командную строку. Возможно, когда-нибудь будет уместно дать ему всю визуальную обработку JavaFX: окна, диалоги и т. д.

В настоящее время мне нужно разрешить пользователям выбирать файлы/каталоги из любой точки файловой системы. То, как я это сделал, состоит в том, чтобы сделать мой основной класс ConsoleHandler подклассом из JavaFX Application и запустить start() в начале прогона, так что фактически приложение работает в потоке JavaFX. Это означает, среди прочего, что поток позволяет отображать JavaFX FileChooser, а также ожидает, пока пользователь выбирает файл(ы)/каталоги...

Но это кажется таким НЕПРАВИЛЬНЫМ! Это не (по крайней мере пока) «визуальное» приложение. Я бы предпочел обработать «ожидание пользовательского ввода» чем-то простым, например ExecutorService, и использовать обычные Threads.

Я ценю, что средство выбора файлов действительно является «визуальной» функцией само по себе, и, очевидно, задействовано «событие», такое как нажатие кнопки «Выбрать»: но необходимость использовать всю инфраструктуру JavaFX для этой цели кажется глупый. Мне интересно, может ли существовать что-то более основанное на типизации.

NB У меня нет желания использовать Swing JFileChooser: применимы аналогичные мысли, и Swing - это прошлое.

В настоящее время я планирую обойти это, выделив всю функциональность FileChooser в изолированный модуль... но я просто подумал, что хотел бы спросить, знает ли кто-нибудь способ полностью избежать JavaFX для этого варианта использования.


person mike rodent    schedule 12.04.2018    source источник
comment
Невозможно избежать запуска набора инструментов JavaFX, если вы хотите использовать средство выбора файлов JavaFX. Я бы переместил вашу логику приложения, не относящегося к пользовательскому интерфейсу, в отдельный класс и запустил его из фонового потока, который вы можете запустить из метода Application.start(). Если вам нужно показать средство выбора файлов из фонового потока, оберните вызовы к нему в Platform.runLater(). Это должно дать вам больше гибкости для перехода на приложение с полным пользовательским интерфейсом (или даже на приложение, полностью не связанное с пользовательским интерфейсом) позже.   -  person James_D    schedule 13.04.2018


Ответы (2)


Вы можете попытаться воспроизвести консоль, такую ​​как CMD или консоль Linux; где вы начинаете с папки, а затем можете переходить к папкам внутри нее или к родительской папке с помощью команды, очень похожей на cd в CMD. Вы можете сделать это, просто создав объект File с начальным путем, а затем вернуться назад, если будет введена определенная команда, или перейти в папку, если она существует.

File currDir = new File("starting path");
String input = //INPUT FROM CONSOLE
if(input.equals("back")){
    //GO BACK TO PARENT FOLDER
    currDir = currDir.getParentFile();
}else{
    for(File file : currDir.listFiles()){
        if(file.isDirectory()){
            if(file.getName().equals(input)){
                //GO INTO SELECTED FOLDER
                currDir = file;
            }
        }else if(file.isFile()){
            /*SINCE file.getName() INCLUDES THE FILE EXTENSION YOU'D HAVE TO 
            EITHER PROVIDE THE FILE EXTENSION ALONG THE NAME OF THE FILE 
            WHEN YOU INPUT IT OR SPLIT THE FILE NAME AND EXTENSION FROM 
            THE INPUT BEFORE COMPARING*/
            if(file.getName().equals(input)){
                //THIS IS THE SELECTED FILE, DO WHAT YOU WANT WITH IT
            }
        }
    }
}

Хотя по прошлому опыту я искренне считаю, что использование по умолчанию FileChooser или JFileChooser будет работать лучше всего.

person PabloJ    schedule 12.04.2018
comment
Спасибо... да, мне пришла в голову идея воспроизвести навигацию BASH, выбор файлов и так далее. Я думаю, что вместо того, чтобы внедрять мои собственные функции, можно надеяться, что где-то там будет загружаемая библиотека ... или что каким-то образом можно будет использовать ограниченный набор команд BASH из самого приложения (ну, есть Runtime.exec, из курс...). Похоже, что отдельный модуль JavaFX - это, вероятно, путь. - person mike rodent; 13.04.2018

Ответ PabloJ заставил меня немного задуматься.

Особенно с Groovy вариант использования Runtime становится весьма практичным:

def process = Runtime.runtime.exec( userInputLine )
println "system response: $process.inputStream.text"

NB для тех, кто не использует Groovy, runtime происходит от getRuntime(), inputStream происходит от getInputStream(), а text происходит от расширенной (GDK) версии Groovy InputStream, в которой очень удобно добавлен метод getText() к InputStream. Используя чистую Java, вы должны быть связаны с StringBuffer, проверенным Exceptions и т. д.

... единственная проблема сейчас заключается в том, что, по-видимому, этот userInputLine должен быть командой в стиле DOS в Windoze (dir и т. д.), но командой BASH в Linux (ls и т. д.) (или есть способ заставить Runtime использовать Cygwin на W10? Хммм... 2 минуты спустя: да)

... так что, очевидно, вы можете затем реализовать свой собственный разрешенный, ограниченный набор команд BASH, которые разрешены, включая cd ... а затем добавить несколько «удобных» навигационных ярлыков и свою собственную команду «выбрать», которая говорит «пропылесосить все файлы/каталоги, перечисленные в этом шаблоне выбора, и обработайте их..."

Наконец, здесь есть проблема, связанная с тем, что кажется невозможным изменить рабочий каталог Java/Groovy... так как же запустить cd? Вы сохраняете «синтетический» рабочий каталог File и вместо exec( command ) переходите к exec( command, null, synthWD ). cd команды должны быть перехвачены и соответствующим образом обработаны (т.е. изменены synthWD).

person mike rodent    schedule 13.04.2018