Repository navigation
Handle dropped files
Users drag files onto applications: a photo into an editor, a PDF into a reader, a folder into a project window. A page can read the names and the bytes of the files that a drop gives it, but never their paths, and the path is what a desktop application needs to open, move, or watch a file. lwjwae reads the paths natively and tells Java and the page. In this guide, a page has a drop zone that lists what lands on it, and Java counts the files.

window.onFileDrop calls a listener with a FileDropEvent when the user drops files from the file
manager onto the page:
public class Drops {
public static void main(String[] args) {
Application.launch(
WindowParameters.of("Drop", 560, 400),
window -> {
window.onFileDrop(
event ->
window.emit(
"heard",
"Java heard %d files at %d, %d"
.formatted(event.paths().size(), event.x(), event.y())));
window.loadResource("drop/index.html");
});
}
}| Component | What it is |
|---|---|
paths() |
The files and folders, as absolute Paths, in the order that the file manager gave them. Never empty |
window() |
The window that the files landed on |
x(), y()
|
Where the pointer was when the user let go, from the top left of the page |
The listener runs on a virtual thread, so it may read the files, or wait for something, without
blocking the window. onFileDrop returns an EventSubscription, and unlisten() stops it.
The page has no paths in the files of a drop event, so it asks lwjwae.files:
const zone = document.querySelector("#zone");
lwjwae.files.listen(({ paths, x, y }) => {
document.querySelector("#list").replaceChildren(...paths.map((path) => {
const item = document.createElement("li");
item.textContent = path;
return item;
}));
zone.textContent = paths.length + " files dropped";
});listen resolves to the function that stops the listener. The payload has the same paths, x,
and y as the Java event. The ordinary events of the page, dragenter, dragover, dragleave,
and drop, still come, and are the place to light up the drop zone:
addEventListener("dragenter", () => zone.classList.add("over"));
addEventListener("dragleave", () => zone.classList.remove("over"));
addEventListener("drop", () => zone.classList.remove("over"));Without help, an engine opens a file that lands on its page, and the application is gone from the
window. lwjwae stops that: it takes a dragover or a drop of files that the page leaves alone,
so the window stays where it is and the file goes to the listeners only.
- A page that handles
dragoveranddropitself, and callspreventDefault(), keeps its way, and Java still hears the drop. - A text field, a text area, or an editable element keeps its own drop, so dragging a link into a field still inserts the text.
- A drop of anything but files, such as selected text, is not a file drop and isn't reported.
| Platform | How the paths come |
|---|---|
| Windows | The script that lwjwae adds to every page posts the files of each drop to the host, and WebView2 gives the host their full paths. The runtime must be 1.0.1264 or later |
| macOS | The web view reads the file URLs on the pasteboard of the drag as it takes the drop, and the place comes from the drop event of the page. Finder hands references to files, which arrive as their paths |
| Linux, GTK 3 | The text/uri-list of the drop. A file that lives only in a remote location, which the file manager mounted, is left out |
| Linux, GTK 4 | The window reads the files that the drag offers as it comes over the page, and the place comes from the drop event of the page. A file that isn't local is left out |
-
xandyare where the pointer was, from the top left of the page. On Windows, macOS, and GTK 4 they are theclientXandclientYof thedropevent, sodocument.elementFromPoint(x, y)finds the element that got the files at any zoom. GTK 3 measures them in the pixels of the window, which are the pixels of the page only at a zoom of 1. - A folder arrives as one path. Walk it in Java, with
Files.walk, to get its files. - Paths with spaces,
#,%, and&arrive the way they are on the disk.
Tutorial
- Set up the project
- Open a window
- Call Java from the page
- Send events from Java to the page
- Draw your own title bar
- Export notes through a native dialog
- Keep the application in the tray
- Show notifications
- Give the application an icon and a name
- Build a native executable
- Package the application
Guides
- Pass objects through the bridge
- Stream bytes between the page and Java
- Open several windows
- Place and control a window
- Make a transparent window
- Add menus
- Register global shortcuts
- Show progress in the taskbar
- Use the clipboard
- Handle dropped files
- Zoom the page
- Set the window icon
- Follow the theme of the desktop
- Use cookies
- Store data in SQLite
- Keep secrets
- Show dialogs
- Run a single instance
- Open your own links and files
- Update the application
- Handle page permissions
- Handle links and page loads
Reference