Skip to content

Place and control a window

fakeivchenko edited this page Sep 29, 2026 · 1 revision

A window can be moved, resized, minimized, maximized, put in full screen, and kept on top, from Java and from its page, and it reports every change as an event. It can also remember where it was from one run to the next, on a screen that is still there. In this guide, a window shows its own state as it changes, lists the screens, and moves itself into the corner of its screen.

The window after "Always on top" and "To the corner", on Linux and on Windows 11

Open a window that remembers its place

public class WindowControl {
  public static void main(String[] args) {
    // The name gives the application a place to remember its windows in.
    ApplicationParameters parameters = ApplicationParameters.builder().name("Window Control").build();
    try (Application application = Application.create(parameters)) {
      Window window =
          application.show(
              WindowParameters.builder()
                  .title("Window Control")
                  .size(new WindowSize(620, 560))
                  .minimumSize(new WindowSize(480, 400))
                  .stateKey("main")
                  .resource("control/index.html")
                  .build());
      window.onWindowEvent(event -> System.out.println(event.type() + " " + event.size()));
      window.bind("screens", Void.class, _ -> application.screens());
      window.bind("onTop", Boolean.class, onTop -> WindowControl.onTop(window, onTop));
      window.bind("toCorner", Void.class, _ -> WindowControl.toCorner(window));
      application.run();
    }
  }

  private static Boolean onTop(Window window, boolean onTop) {
    window.alwaysOnTop(onTop);
    return window.isAlwaysOnTop();
  }

  /** Puts the window in the bottom right corner of the work area of its screen. */
  private static Void toCorner(Window window) {
    ScreenArea area = window.screen().workArea();
    WindowSize size = window.size();
    window.position(area.x() + area.width() - size.width(), area.y() + area.height() - size.height());
    return null;
  }
}
  • stateKey("main") makes the window remember its size, its place, and whether it was maximized, in the data directory of the application: ~/.config/Window Control on Linux, ~/Library/Application Support/Window Control on macOS, %APPDATA%\Window Control on Windows. What it remembers wins over the size and the position of the parameters. It needs the name of the application.
  • minimumSize and maximumSize limit what the user can resize the content area to.
  • onWindowEvent hears every change: RESIZED, MOVED, FOCUSED, BLURRED, MINIMIZED, UNMINIMIZED, MAXIMIZED, UNMAXIMIZED, FULLSCREEN_ENTERED, and FULLSCREEN_EXITED.
  • application.screens() lists the screens, the primary one first, each with its bounds, its workArea without the taskbar or the panels, and its scale. window.screen() is the one that the window is on.

Control the window from its page

lwjwae.window controls the window of the page, and hears its changes:

const controls = lwjwae.window;

document.querySelector("#minimize").addEventListener("click", () => controls.minimize());
document.querySelector("#maximize").addEventListener("click", () => controls.toggleMaximize());
document.querySelector("#fullscreen").addEventListener("click", async () => {
  const { fullscreen } = await controls.state();
  controls.fullscreen(!fullscreen);
});

// The state on demand, and every change as an event.
async function showState() {
  const state = await controls.state(); // { width, height, x, y, minimized, maximized, fullscreen, focused, resizable }
  document.querySelector("#size").textContent = `${state.width} × ${state.height}`;
}
controls.listen(() => showState());
showState();

lwjwae.window also has maximize, restore, close, which closes the way the close button does, and startMove and startResize for a title bar of the page's own, as in Draw your own title bar.

Platforms

Windows macOS Linux, GTK 3 Linux, GTK 4
Position Pixels Points, from the top left of the primary screen Pixels on X11; always 0, 0 on Wayland, where the compositor places windows Always 0, 0: GTK 4 can't tell or set it
Full screen Drops the frame and covers the monitor A space of its own, with an animation As described As described
Always on top Only for the application in front; the parameter works from the background too Above the windows of every application A hint that the window manager may ignore Does nothing
window.screen() As described As described On Wayland, as the compositor tells The primary screen until the window was first shown

Clone this wiki locally