javagluonjavafxports

How to use FileChooser in gluon when platform is Desktop?


I know that Gluon mobile can not use FileChooser. But my question is that when I try to use PicturesService to loadImageFromGallery in Desktop and it is not working. So I wonder to detect when platform is Desktop then use FileChooser. But just can't get stage? Can you help to how to solve it?

FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(stage);
                                       ^^^^^

Solution

  • If you check the source code for the Pictures service in Charm Down, there is no DesktopPicturesService implemented (yet).

    This means that the call to service.loadImageFromGallery():

    Services.get(PicturesService.class).ifPresent(service -> service.loadImageFromGallery());
    

    won't be done if you are running on Desktop.

    A quick solution is detecting that you are running on Desktop, and call the FileChooser directly, else use the pictures service:

    if (Platform.isDesktop()) {
        FileChooser...
    } else {
        Services.get(PicturesService.class).ifPresent(service -> service.loadImageFromGallery());
    } 
    

    For a better integration, nothing prevents you from adding the missing DesktopPicturesService implementation to your project, and include a FileChooser, to be able to load a picture in your application.

    For that you just need to:

    DesktopPicturesService.java

    public class DesktopPicturesService implements PicturesService {
    
        @Override
        public Optional<Image> takePhoto(boolean savePhoto) {
            throw new UnsupportedOperationException("Not supported yet."); 
        }
    
        @Override
        public Optional<Image> loadImageFromGallery() {
            throw new UnsupportedOperationException("Not supported yet.");
        }
    
    }
    

    This is a simple implementation:

    @Override
    public Optional<Image> loadImageFromGallery() {
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter extFilterJPG = new FileChooser.ExtensionFilter("JPG files (*.jpg)", "*.JPG");
        fileChooser.getExtensionFilters().addAll(extFilterJPG);
    
        try {
            File file = fileChooser.showOpenDialog(null);
            if (file != null) {
                Image image = new Image(new FileInputStream(file));
                return Optional.ofNullable(image);
            }
        } catch (FileNotFoundException ex) {}
        return Optional.empty();
    }
    

    About the stage argument, you can set it to null, or get it from the MobileApplication instance:

    Stage stage = MobileApplication.getInstance().getView().getScene().getWindow();
    

    Add an ImageView and call the service:

    ImageView imageView = new ImageView();
    Services.get(PicturesService.class).ifPresent(pictures -> {
        pictures.loadImageFromGallery().ifPresent(imageView::setImage);
    });
    

    This will work now on both desktop and mobile devices.

    As an extra, you could also implement the takePhoto method, accessing the webCam of your desktop machine, if exists...