'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 1:[1]

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:

  • add the pictures plugin to the list of services in DownConfig (build.gradle)
  • add to the Desktop/Java Packages folder the following package: com.gluonhq.charm.down.plugins.desktop
  • add the class DesktopPicturesService to that package, that implements PicturesService, and implement the required methods:

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.");
    }

}
  • Now add the FileChooser:

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();
  • Finally, use your service in your application.

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...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 José Pereda