ImGui Java

repository·main·Indexed 21 days ago

https://github.com/spair/imgui-java

A JNI-based binding for the Dear ImGui C++ library to create immediate-mode graphical user interfaces in Java. It provides three levels of abstraction: imgui-java-app for a high-level 'one-jar' solution with bundled GLFW and OpenGL, imgui-java-binding for core low-level bindings, and imgui-java-lwjgl3 for a ready-made LWJGL3 backend. The library includes support for FreeType font rendering and various extensions such as ImNodes, ImGuizmo, and implot.

Tokens
2.9K
Snippets
9
Records
18
Agent score
24%

What's inside imgui-java

  1. Overview of ImGui Java artifacts

    main

    ImGui Java provides JNI-based bindings for Dear ImGui. The project is distributed via three main Maven artifacts, allowing you to choose the level of abstraction you need:

    • imgui-java-app: A high-level, "one-jar" solution. It includes the binding, native libraries, and a bundled GLFW + OpenGL backend. Best for users who only care about the GUI.
    • imgui-java-binding: The core binding itself. It contains no backend and requires you to manually manage the application lifecycle and native libraries.
    • imgui-java-lwjgl3: A ready-made GLFW/OpenGL backend built on top of LWJGL3, intended to be used alongside imgui-java-binding.
  2. Enable the FreeType font renderer

    main

    By default, the binding uses stb-truetype. FreeType is statically pre-compiled into the published native libraries and is included by default.

    To use FreeType, you must call ImFontAtlas#setFreeTypeRenderer(true) before generating the fonts atlas. Once enabled, you can use ImGuiFreeTypeBuilderFlags in your font configuration.

    // Must be called before fonts atlas generation
    ImFontAtlas atlas = ImGui.getIO().getFontAtlas();
    atlas.setFreeTypeRenderer(true);
  3. Understand ImGui Java API conventions

    main

    The binding adapts the C++ API for Java using two primary patterns:

    1. Out-parameters: Instead of C++ references, Java uses primitive wrappers like ImInt, ImFloat, and ImBoolean to handle values passed by reference.
    2. Native structs: Every wrapper holds a public pointer to its native memory. While usually ignored, you can reassign this pointer to allow a single Java instance to address different native structs (e.g., when iterating over native arrays).

    For general usage, refer to the upstream Dear ImGui documentation.

  4. Native library features and architecture support

    main

    The provided native libraries include the following characteristics:

    • FreeType: All libraries include statically compiled FreeType for font rendering.
    • macOS Architecture: The macOS library is a universal binary, supporting both x86_64 and arm64 architectures.
  5. How to use the imgui-java-app module

    main

    The imgui-java-app module is a batteries-included setup. To use it, subclass Application, override the configure(Configuration config) method for setup, and the process() method for your UI logic.

    It handles GLFW, OpenGL, and native library loading automatically. You do not need to add separate dependencies for LWJGL or native libraries if you use the all classifier jar.

    import imgui.ImGui;
    import imgui.app.Application;
    import imgui.app.Configuration;
    
    public class Main extends Application {
        @Override
        protected void configure(Configuration config) {
            config.setTitle("Dear ImGui is Awesome!");
        }
    
        @Override
        public void process() {
            ImGui.text("Hello, World!");
        }
    
        public static void main(String[] args) {
            launch(new Main());
        }
    }
  6. Install imgui-java-binding with LWJGL3

    main

    If you want to bring your own backend wiring (e.g., integrating into an existing render loop), you must use imgui-java-binding along with imgui-java-lwjgl3 and the appropriate native binaries for your OS. You also need to include the necessary LWJGL3 dependencies.

    // Gradle example for Windows
    repositories {
        mavenCentral()
    }
    ext {
        lwjglVersion = '3.4.1'
        imguiVersion = "${version}"
    }
    
    dependencies {
        implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
    
        ['', '-opengl', '-glfw'].each {
            implementation "org.lwjgl:lwjgl$it:$lwjglVersion"
            implementation "org.lwjgl:lwjgl$it::natives-windows"
        }
        
        implementation "io.github.spair:imgui-java-binding:$imguiVersion"
        implementation "io.github.spair:imgui-java-lwjgl3:$imguiVersion"
        
        implementation "io.github.spair:imgui-java-natives-windows:$imguiVersion"
    }
  7. Install imgui-java-app via Gradle or Maven

    main

    To use the high-level application layer, add the imgui-java-app dependency to your project.

    // Gradle
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation "io.github.spair:imgui-java-app:${version}"
    }
    <!-- Maven -->
    <dependency>
        <groupId>io.github.spair</groupId>
        <artifactId>imgui-java-app</artifactId>
        <version>${version}</version>
    </dependency>
  8. Use included ImGui extensions

    main

    All extensions are included in the binding and can be used without additional setup. You can find runnable demos for each in example/src/main/java/.

    Supported extensions include:

    • ImNodes: A dependency-free node editor.
    • imgui-node-editor: A more feature-rich node editor.
    • ImGuizmo: 3D gizmos for scene editing.
    • implot: Advanced 2D plotting.
    • ImGuiColorTextEdit: Syntax highlighting text editor.
    • ImGuiFileDialog: File selection dialog.
    • ImGui Club MemoryEditor: Memory editor and viewer.
    • imgui-knobs: A collection of knob widgets.
  9. Build native libraries via Gradle

    main

    You can invoke generateLibs directly via Gradle. This is useful if you want a stock build under the project tree or do not need FreeType.

    Windows

    • Requirements: Ant and Mingw-w64 (e.g., via MSYS2) must be on your PATH.
    • Build: ./gradlew imgui-binding:generateLibs -Denvs=windows -Dlocal
    • Run Example: ./gradlew example:run -PlibPath="../imgui-binding/build/libsNative/windows64"

    Linux

    • Requirements: mingw-w64-gcc and ant.
    • Build: ./gradlew imgui-binding:generateLibs -Denvs=linux -Dlocal
    • Run Example: ./gradlew example:run -PlibPath=../imgui-binding/build/libsNative/linux64

    macOS

    • Build (Universal): ./gradlew imgui-binding:generateLibs -Denvs=macos,macosarm64 -Dlocal
    • Build (Single Slice): Pass -Denvs=macos or -Denvs=macosarm64.
    • Run Example (Intel): ./gradlew example:run -PlibPath=../imgui-binding/build/libsNative/macosx64
  10. Build native libraries manually

    main

    You only need to build native libraries yourself if you are bumping submodules, hacking the JNI layer, or producing a binary without FreeType.

    Prerequisites

    Ensure git submodules are initialized:

    git submodule update --init --recursive

    The Gradle toolchain uses JDK 17. You only need a JVM capable of running gradlew.

    Use the script provided in buildSrc/scripts/build.sh to vendor FreeType and run generateLibs. This script outputs binaries to /tmp/imgui/dst/.

    buildSrc/scripts/build.sh <windows|linux|macos>

    To run the example with a custom-built binary:

    cp /tmp/imgui/dst/libimgui-java64.<so|dylib|dll> bin/
    ./gradlew :example:run -PlibPath=$PWD/bin
  11. Workflow for contributing to the binding

    main

    The Java binding is codegen-driven.

    1. Do not edit files in imgui-binding/src/generated/. They are automatically regenerated.
    2. Edit the annotated stubs in imgui-binding/src/main/java/.
    3. Regenerate the API using the following command:
    ./gradlew :imgui-binding:generateApi
    1. Commit both src/main/java and src/generated/java in a single commit.
    # edit imgui-binding/src/main/java/...
    ./gradlew :imgui-binding:generateApi
    # commit both src/main/java and src/generated/java in one commit
  12. Specify the native library path

    main

    To tell the JVM where to find the native ImGui libraries, use the imgui.library.path or the standard java.library.path VM option. This is necessary if the libraries are not in the default system library path or the application's working directory.

    -Dimgui.library.path=./folder/path