GoXr3Plus GoXr3Plus - 5 months ago 59
Java Question

JavaFX Drag and Drop: accept only some file extensions

What i want to do:
when the user tries to drag and drop something into the window,he can do it only if the drag has file with extensions (.mp3,.ogg,.wav).If the files have not this extension the drop can't be done.I don't want links,etc...to be dropped.

For example accept only html is so easy as:

controller.setOnDragOver((over) -> {
Dragboard board = over.getDragboard();
if (board.hasHtml())
over.acceptTransferModes(TransferMode.LINK);

});


How can i add a filter for that?

Answer

You can use the getFiles method of DragBoard returned by getDragboard method of DragEvent in the event handler set in setOnDragOver of your Node or Scene to get the list of files currently dragged.

You can check the extensions in this list either using for example getExtension of Apache Commons IO or by implementing your own function to get the extension of a file. If the extension(s) of the file(s) of the dragboard does not match with the predefined extensions you can simply consume the DragEvent.

Example

In this example I have created a Stage with a VBox inside which accepts only files with extension of "jpg" and "png" to be dropped on it. If the drop was succesful it prints the absolute file path of the files.

public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            VBox root = new VBox();
            Scene scene = new Scene(root,400,400);

            // Extensions that are valid to be drag-n-dropped
            List<String> validExtensions = new ArrayList<String>();
            validExtensions.add("jpg");
            validExtensions.add("png");

            root.setOnDragOver(new EventHandler<DragEvent>() {

                @Override
                public void handle(DragEvent event) {
                    // On drag over if the DragBoard has files
                    if (event.getGestureSource() != root && event.getDragboard().hasFiles()) {

                        // Collect the files and check the extensions
                        List<File> files = event.getDragboard().getFiles();
                        for(int i = 0; i< files.size(); i++){
                            String ext = getExtension(files.get(i).getName());
                            if(!validExtensions.contains(ext)){
                                event.consume();
                                return;
                            }
                        }


                        // Allow for both copying and moving
                        event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
                    }
                    event.consume();
                }
            });

            root.setOnDragDropped(new EventHandler<DragEvent>() {

                @Override
                public void handle(DragEvent event) {
                    boolean success = false;
                    if (event.getGestureSource() != root && event.getDragboard().hasFiles()) {

                        // Print files
                        List<File> files = event.getDragboard().getFiles();
                        for(int i = 0; i< files.size(); i++){
                            System.out.println(files.get(i).getAbsolutePath());
                        }
                        success = true;
                    }
                    event.setDropCompleted(success);

                    event.consume();
                }
            });



            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    // Methodto to get extension of a file
    private String getExtension(String fileName){
        String extension = "";

        int i = fileName.lastIndexOf('.');
        if (i > 0) {
            extension = fileName.substring(i+1);
        }
        return extension;
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Comments