Handle links and page loads - fakeivchenko/lwjwae GitHub Wiki

A window shows the pages of the application, but pages link elsewhere: to web sites, to e-mail addresses, to new windows. lwjwae sends those links to the browser of the system and keeps the window on the application. This guide changes where they go, has Java follow the loading of the page and read from it, and points the window at a development server with hot reload.

Links that left the application, and the title that Java read, on Linux and on Windows 11

Links that leave the application

A link to another site, a mailto: link, a link with target="_blank", and window.open of such a URL go to the browser, or to the mail application, by default. externalLinkHandler decides instead:

public class Links {
  public static void main(String[] args) {
    Application.launch(
        WindowParameters.of("Links", 600, 440),
        window -> {
          // Instead of the browser of the system, which is the default: show where a link went.
          window.externalLinkHandler(url -> window.emit("left", url));
          window.onLoad(
              event -> {
                if (event.state() == LoadState.FINISHED) {
                  window.eval("document.title").thenAccept(title -> window.emit("loaded", title));
                }
              });
          window.devToolsEnabled(true);
          window.loadResource("links/index.html");
        });
  }
}

The page needs nothing special: its links are plain links.

<ul>
  <li><a href="https://github.com/fakeivchenko/lwjwae">A link to another site</a></li>
  <li><a href="mailto:[email protected]">An e-mail address</a></li>
  <li><a href="#" id="open">window.open from a script</a></li>
</ul>
<script>
  document.querySelector("#open").addEventListener("click", (event) => {
    event.preventDefault();
    window.open("https://example.com/docs");
  });
</script>

To open a URL from Java, as a link would, call application.openExternal(url).

Follow the page from Java

  • onLoad hears every stage of a navigation: STARTED, REDIRECTED, COMMITTED, FINISHED, and FAILED, with the URL and, for a failure, the message.
  • eval(script) runs a script in the page and resolves to its result as text, or fails with the error of the script. Prefer a binding or an event for anything that the page does on purpose; eval is for a look from outside.
  • devToolsEnabled(true) adds Inspect to the context menu of the page. Leave it off in a release.

Develop the page with hot reload

During development, a window can load the page from a development server, such as the one of Vite or webpack, instead of from the resources: every change to the page shows at once, without a restart. Set LWJWAE_DEV_SERVER_URL, or the system property lwjwae.devServerUrl, to the address of the server:

LWJWAE_DEV_SERVER_URL=http://localhost:5173 ./gradlew run

Every loadResource then loads that address instead, and the page there keeps the bridge: its bindings, events, and calls work as they do from the resources. Without the variable, the application loads its resources as it ships, so the code stays the same in both modes. For a Vite project, set base: "./" in vite.config.js, so that its build loads from the resources with relative paths.

With the Gradle plugin and a frontend in frontend/, ./gradlew runDev starts the server, sets the variable, and stops the server when the window closes.

⚠️ **GitHub.com Fallback** ⚠️