Skip to content

NGE Simple UI

Nostr Game Engine (NGE) includes a built-in UI module built on top of Lemur, a powerful GUI toolkit for jMonkeyEngine.

Core Concept

The NGE GUI module is designed around a single active window. At any time, only one window is visible on the screen. When a new window is opened, it replaces the previous one, but provides a back button to return.

This design keeps things simple and makes it easy to support touch devices and gamepads. If you need more complex behavior, you can mix and match standard Lemur components with the NGE GUI module, or skip the NGE GUI module entirely and use Lemur directly.

A window can be fullscreen or small, transparent or opaque, centered or aligned differently, depending on your needs.

Example

  • A game HUD might use a fullscreen, transparent window.
  • A settings menu might be a smaller, centered window with an opaque background.

The system is built to cover the vast majority of game UI needs in a simple, scalable way.

Tip

To avoid confusion with Java’s built-in UI classes, all NGE GUI components are prefixed with N (e.g., NWindow, NButton, etc.).

Enabling the Window Manager

Everything in the UI system is managed by the NWindowManagerComponent. To use it, add and enable it like so (as shown in the Getting Started section):

Runnable appBuilder = NGEApplication.createApp(settings, app -> {
    ComponentManager mng = app.getComponentManager();

    // Add the Window Manager Component
    mng.addAndEnableComponent(new NWindowManagerComponent());

    // ... add other components ...
});

Creating a Window

To create a custom window, extend the NWindow class. Here's a simple example:

public class MyWindow extends NWindow<Object> {
    @Override
    protected void compose(Vector3f size, Object args) throws Throwable {
        setTitle("My Window");

        NLabel label = new NLabel("A label");
        label.setTextHAlignment(HAlignment.Center);

        NButton confirmButton = new NButton("Confirm");
        confirmButton.addClickCommands(b -> {
            System.out.println("Confirmed!");
            close();
        });

        NColumn column = new NColumn();
        column.addChild(label);
        column.addChild(confirmButton);

        getContent().addChild(column);
    }
}
  • The compose() method builds the window’s contents.
  • This method may be called multiple times (e.g., when resizing or refreshing), but previous content is cleared automatically.
  • Windows must not have constructors with arguments

Tip

Think of this like an immediate-mode UI: you rebuild the content everytime the compose() method is called, but the engine maintains the state as long as possible

Useful Window Methods

  • setTitle(String title): Set the window title.
  • getContent(): Get the main content panel.
  • setFullScreen(boolean fullScreen): Make the window fullscreen (default: false).
  • setWithTitleBar(boolean withTitleBar): Show/hide the title bar (default: true).
  • setFitContent(boolean fitContent): Resize to fit content (default: true).
  • close(): Close the window.

Opening a Window

To display a window, use the NWindowManagerComponent:

NWindowManagerComponent windowManager = mng.getComponent(NWindowManagerComponent.class);
windowManager.showWindow(MyWindow.class);

With Callback:

windowManager.showWindow(MyWindow.class, (window, err) -> {
    if (err != null) {
        System.err.println("Failed to open window: " + err.getMessage());
    } else {
        System.out.println("Window opened successfully: " + window);
    }
});

With Arguments:

The NWindow class has a generic type for its argument that is passed to the compose() method. This allows you to pass data when opening a window, which can be useful for configuration or state management.

You can pass data like this:

windowManager.showWindow(MyWindow.class, myArgs, optionalCallback);

Closing a Window

To close a window, use the close() method, either from the instance or inside the window logic:

Example

NButton closeButton = new NButton("Close");
closeButton.addClickCommands(b -> close());

Toasts

Toasts are short-lived messages for feedback or notifications. You can show a toast using the NWindowManagerComponent:

windowManager.showToast(ToastType.INFO, "This is a toast message", Duration.ofSeconds(3));

You can also omit the duration and a default duration will be used depending on the toast type:

windowManager.showToast(ToastType.INFO, "This is a toast message");

To display an exception:

windowManager.showToast(new Exception("Something went wrong"));

This will automatically format and show the stack trace in a toast. It’s a good way to log and report non-blocking background errors to the user.

Closing Everything

If you need to completely clear the UI (e.g., when starting gameplay):

windowManager.closeAllWindows(); // Closes all windows
windowManager.closeAllToasts();  // Closes all toasts
windowManager.closeAll();        // Closes both

Showing a Fatal Error

When something unrecoverable happens, show a fatal error message like this:

windowManager.showFatalError(new Exception("This is a fatal error message"));

This will open a modal dialog with:

  • A copy-to-clipboard button for the stack trace
  • A button to exit the game

Perfect for critical crash handling and debugging.