Как я ограничиваю JFileChooser каталогом?

Вы создаете экземпляр контроллера «вручную» с помощью

MainController mc = new MainController();

@FXML -но заданные поля инициализируются FXMLLoader, когда он создает контроллер для вас как часть процесса загружая файл FXML. Поскольку созданный вами контроллер не является экземпляром контроллера, созданным FXMLLoader, его @FXML -занятые поля неинициализируются (т. Е. Они являются нулевыми), и, следовательно, вы получаете исключение нулевого указателя.

Вы может получить ссылку на контроллер, созданный FXMLLoader, вызвав getController() в экземпляре FXMLLoader после вызова load().

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

public class ConnectionErrorController implements Initializable {

    private MainController mainController ;

    public void setMainController(MainController mainController) {
        this.mainController = mainController ;
    }

    // ...

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        infoLabel.setText("Connection lost, please try again");
        tryButton.setText("try again");
        exitButton.setText("exit");

        tryButton.setOnAction(new EventHandler() {
            @Override
            public void handle(ActionEvent event) {

                WebEngine webEngine = mainController.getContentPaneController().getVideoWebView().getEngine(); // 1
                ToggleButton playButton = mainController.getControlPaneController().getPlayButton(); // 2
                if (mainController.testInet()) {
                    mainController.play(webEngine, playButton);
                } else {
                    // obviously you can now do something better than the "public static field hack" here:
                    MainController.exist = false;
                }
                tryButton.getScene().getWindow().hide();
            }
        });

        // ...
    }
}    

Предполагая, что вы загружаете второй файл fxml в методе в MainController, вы можете просто сделать что-то например:

public class MainController {

    // ...

    public void showConnectionErrorWindow(String fileName) {

        FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/ConnectionError.fxml"));
        Parent root = loader.load();
        ConnectionErrorController connectionErrorController = loader.getController();
        connectionErrorController.setMainController(this);

        Scene scene = new Scene(root);
        Stage stage = new Stage();
        // etc...
    }

    // ...
}

Обратите внимание, что есть гораздо более элегантные способы решения этой проблемы, такие как передача функции ConnectionErrorController обратного вызова (в форме лямбда-выражения) для обработки вызова play(...), которые избегают жесткой связи между ConnectionErrorController и MainController. Однако, поскольку вы, кажется, новичок в Java, этот более простой подход может быть более подходящим.

См. Параметры передачи JavaFX FXML для получения дополнительной информации о передаче значений контроллерам.

22
задан Cœur 19 February 2017 в 13:54
поделиться

2 ответа

Можно, вероятно, сделать это путем установки собственного FileSystemView.

12
ответ дан Everlight 29 November 2019 в 04:54
поделиться

Упакуйте кому-либо еще нужно это в будущем:

class DirectoryRestrictedFileSystemView extends FileSystemView
{
    private final File[] rootDirectories;

    DirectoryRestrictedFileSystemView(File rootDirectory)
    {
        this.rootDirectories = new File[] {rootDirectory};
    }

    DirectoryRestrictedFileSystemView(File[] rootDirectories)
    {
        this.rootDirectories = rootDirectories;
    }

    @Override
    public File createNewFolder(File containingDir) throws IOException
    {       
        throw new UnsupportedOperationException("Unable to create directory");
    }

    @Override
    public File[] getRoots()
    {
        return rootDirectories;
    }

    @Override
    public boolean isRoot(File file)
    {
        for (File root : rootDirectories) {
            if (root.equals(file)) {
                return true;
            }
        }
        return false;
    }
}

необходимо будет, очевидно, сделать лучший "createNewFolder" метод, но это действительно ограничивает пользователя одним из большего количества каталогов.

И использование это как это:

FileSystemView fsv = new DirectoryRestrictedFileSystemView(new File("X:\\"));
JFileChooser fileChooser = new JFileChooser(fsv);

или как это:

FileSystemView fsv = new DirectoryRestrictedFileSystemView( new File[] {
    new File("X:\\"),
    new File("Y:\\")
});
JFileChooser fileChooser = new JFileChooser(fsv);
22
ответ дан Allain Lalonde 29 November 2019 в 04:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: