java-native-access/jna · error · java.lang.IllegalStateException

Component must be displayable

Error message

Component must be displayable

What it means

Thrown by JNA's Native.getWindow(Component) when the given AWT Component is not displayable. A component becomes displayable only once it is connected to a native screen resource (added to a visible window hierarchy). JNA needs a real native window handle, so it refuses lightweight components and non-displayable ones.

Source

Thrown at src/com/sun/jna/Native.java:2549

    /** Provides separation of JAWT functionality for the sake of J2ME
     * ports which do not include AWT support.
     */
    private static class AWT {
        static long getWindowID(Window w) throws HeadlessException {
            return getComponentID(w);
        }
        // Declaring the argument as Object rather than Component avoids class not
        // found errors on phoneME foundation profile.
        static long getComponentID(Object o) throws HeadlessException {
            if (GraphicsEnvironment.isHeadless()) {
                throw new HeadlessException("No native windows when headless");
            }
            Component c = (Component)o;
            if (c.isLightweight()) {
                throw new IllegalArgumentException("Component must be heavyweight");
            }
            if (!c.isDisplayable())
                throw new IllegalStateException("Component must be displayable");
            // On X11 VMs prior to 1.5, the window must be visible
            if (Platform.isX11()
                && System.getProperty("java.version").startsWith("1.4")) {
                if (!c.isVisible()) {
                    throw new IllegalStateException("Component must be visible");
                }
            }
            // By this point, we're certain that Toolkit.loadLibraries() has
            // been called, thus avoiding AWT/JAWT link errors
            // (see http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6539705).
            return Native.getWindowHandle0(c);
        }
    }
}

View on GitHub (pinned to d036ad9781)

Solutions

  1. Ensure the component's window hierarchy is realized before calling Native.getWindow: call frame.pack() and frame.setVisible(true) first
  2. Verify the component is actually added to a top-level container
  3. Check that the component has not been disposed; recreate it if necessary
  4. Wrap the call in a check: javax.swing.SwingUtilities.getWindowAncestor(c) != null and c.isDisplayable()

Example fix

// before
long hwnd = Native.getWindow(myPanel);
// after
frame.pack();
frame.setVisible(true);
if (myPanel.isDisplayable()) {
    long hwnd = Native.getWindow(myPanel);
}
Defensive patterns

Strategy: validation

Validate before calling

if (c == null || c.isLightweight() || !c.isDisplayable()) {
    throw new IllegalArgumentException("Component must be a displayable heavyweight");
}
long hwnd = Native.getWindow(c);

Prevention

When it happens

Trigger: Calling Native.getWindow(c) before the component has been realized (frame.pack() not called or frame not shown), or calling it on a component that has been disposed.

Common situations: Querying the window handle during UI construction before setVisible(true)/pack(); calling after frame.dispose(); capturing window IDs in headless or early-init code.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/b3a58daa75a64c78. Report an issue: GitHub.