GWT Drag and Drop File Upload not working

元气小坏坏 提交于 2020-01-05 13:43:30

问题


So I have implemented a very simple drag and drop file upload widget. Basically my widget is a vertical panel with a couple of labels and a button inside. The user can either drag file into vertical panel or click button and browse for file.

My problem is that when I drag a file into the vertical panel it fires the DragLeaveEvent every time I drag the item over the space that the labels or button occupies. I want it to know that the item is in the vertical panel even when it is on top of the label or button. Im sure I am missing something simple. I provide the drag functionality by adding these dom handlers to the vertical panel:

addDomHandler(new DragEnterHandler() {
            @Override
            public void onDragEnter(DragEnterEvent event) {
                System.out.println("drag enter");
                highlight(true);
            }
        }, DragEnterEvent.getType());

addDomHandler(new DragLeaveHandler() {
            @Override
            public void onDragLeave(DragLeaveEvent event) {
                System.out.println("drag leave");
                highlight(false);
            }
        }, DragLeaveEvent.getType());

addDomHandler(new DragOverHandler() {
            @Override
            public void onDragOver(DragOverEvent event) {
            }
        }, DragOverEvent.getType());

addDomHandler(new DropHandler() {
            @Override
            public void onDrop(DropEvent event) {
                System.out.println("drop");
                // stop default behaviour
                event.preventDefault();
                event.stopPropagation();

                // starts the fetching, reading and callbacks
                if (fileUploadHandler != null) {
                    handleFiles(event.getDataTransfer(), fileUploadHandler);
                }
                highlight(false);
            }
        }, DropEvent.getType());    

回答1:


Check that the event target is a child (or grand child) of your panel, or in this case maybe rather whether the event target is exactly your panel's element:

if (verticalPanel.getElement().isOrHasChild(Node.as(event.getNativeEvent().getEventTarget()))) {
   // within the panel (possibly on a child)
}

if (verticalPanel.getElement() == Node.as(event.getNativeEvent().getEventTarget())) {
   // targetting exactly the panel (e.g. leaving the panel, not one of its children)
}



回答2:


Through lots of research I have come to the only solution I could find. I set highlight to true in the dragover handler instead of drag enter.

    panel.addDomHandler(new DragEnterHandler() {
        @Override
        public void onDragEnter(DragEnterEvent event) {
        }
    }, DragEnterEvent.getType());

    panel.addDomHandler(new DragLeaveHandler() {
        @Override
        public void onDragLeave(DragLeaveEvent event) {
            highlight(false);
        }
    }, DragLeaveEvent.getType());

    panel.addDomHandler(new DragOverHandler() {
        @Override
        public void onDragOver(DragOverEvent event) {
            highlight(true);
        }
    }, DragOverEvent.getType());

    panel.addDomHandler(new DropHandler() {
        @Override
        public void onDrop(DropEvent event) {
            // stop default behaviour
            event.preventDefault();
            event.stopPropagation();

            // starts the fetching, reading and callbacks
            handleFiles(event.getDataTransfer());
            highlight(false);
        }
    }, DropEvent.getType());



回答3:


I copy pasted your code, but also added a:

RootPanel.get().addHandler(dropHandler, DropEvent.getType());

My drophandler looks like this:

DropHandler dropHandler = new DropHandler() {

        @Override
        public void onDrop(DropEvent event) {
            handleFiles(event.getDataTransfer(), new FileUploadHandler() {
                @Override
                public TYPE specifyFileType() {
                    return TYPE.BINARY;
                }

                @Override
                public void handleFileContent(String fileName, String fileContent) {
                    // do stuff with filename and content
                }

                @Override
                public boolean checkFileName(String fileName) {
                    return true;
                }
            });
            event.preventDefault();
            event.stopPropagation();
        }
    };

and the file-upload interface:

public interface FileUploadHandler {

    static public enum TYPE {
         TEXT, BINARY, DATAURL
    };

    // check the filename and extension and return true if you are happy with
    // proceeding
    // returnning false will prevent the file from being read
    boolean checkFileName(String fileName);

    // tell the method to use to read this file
    TYPE specifyFileType();

    // do your stuff here, eg upload to a server
    void handleFileContent(String fileName, String fileContent);
}

and the handle files func: (note you will have to change classpath to the FileUploadHandler-interface)

// native method to make use of the HTML5 file API functionality
private final native void handleFiles(JavaScriptObject dataTransfer, FileUploadHandler fileUploadHandler) /*-{
    var files = dataTransfer.files;
    var i;
    var file;
    var reader = new FileReader();
    for (i = 0; i < files.length; i++) {
        file = files[i];
        if (fileUploadHandler.@<classpath_to>.FileUploadHandler::checkFileName(Ljava/lang/String;)(file.name)) {
            var type = fileUploadHandler.@<classpath_to>.FileUploadHandler::specifyFileType()();
            reader.onload = function(e) {
                fileUploadHandler.@<classpath_to>.FileUploadHandler::handleFileContent(Ljava/lang/String;Ljava/lang/String;)(file.name, e.target.result);
            }
            if (type == "TEXT") {
                reader.readAsText(file);
            } else if (type == "BINARY") {
                reader.readAsBinaryString(file);
            } else if (type == "DATAURL") {
                reader.readAsDataURL(file);
                // not supported
            } else if (type == "ARRAYBUFFER") {
                reader.readAsArrayBuffer(file);
            } else {
            }
        }
    }
}-*/;


来源:https://stackoverflow.com/questions/17728129/gwt-drag-and-drop-file-upload-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!