Abstract User Interface - Implementation with LWJGL

I’ve been working on a UI implementation that uses LWJGL. I initially made it so that I can create a level editor or possibly embed UI widgets inside a LWJGL window but then I figured that it can also be a solution for general use-cases for desktop applications in Java.

So with that in mind, I decided to create an Abstract User Interface (AUI). Here are some bullet points to show where I’m coming from:

  • I had problems embedding AWT/Swing with LWJGL in the past (I think there is a solution now)
  • I did not like using event listeners when I used to use Swing. After using Qt I fell in love with signals/slots.
  • AUI should be able to be used to interface with any GUI. A switch in the UI used would require little changes.

So the definition of the API can be found here:

My implementation using LWJGL can be found here:

Tea User Interface

Some of the features of Tea:

  • CSS-like styling
  • Easy to create custom widgets - from scratch or by combining multiple widgets
  • File choosers and message dialogs from Swing
  • Can be used with in LWJGL applications



Example with output:

package ax.examples.tea;

import ax.aui.*;
import ax.commons.io.Console;
import ax.tea.TUIManager;

public class TeaSimpleMain {

    public static void main(String[]args) {
        new TeaSimpleMain().run();

    void run() {

        TUIManager ui = TUIManager.instance();

        Window window = ui.window();

        ArrayLayout layout = ui.arrayLayout();
        Panel panel = ui.panel(layout);

        Button button0 = ui.button("Click me");
        Button button1 = ui.button("Button 1");
        Button button2 = ui.button("Button 2");
        Slider slider = ui.slider(Align.HORIZONTAL);
        LineEdit lineEdit = ui.lineEdit("Initial line edit text");
        RadioButton radioButton0 = ui.radioButton("Radio Button 0");
        RadioButton radioButton1 = ui.radioButton("Radio Button 1");
        Dial dial = ui.dial();

        button0.clicked().connect(() -> {
            Console.log("Hello World!");
            Console.log("Slider value:", slider.value());
            Console.log("Line Edit text:", lineEdit.text());
            Console.log("Radio Button #0 checked:", radioButton0.checked());
            Console.log("Radio Button #1 checked:", radioButton1.checked());
            Console.log("Dial value:", dial.value());

            Console.log("Slider value was changed:", value);

        int row = 0;
        layout.add(ui.label("Button:"), row, 0);
        layout.add(button0, row++, 1);
        layout.add(ui.label("Button:"), row, 0);
        layout.add(button1, row++, 1);
        layout.add(ui.label("Button:"), row, 0);
        layout.add(button2, row++, 1);
        layout.add(ui.label("Slider:"), row, 0);
        layout.add(slider, row++, 1);
        layout.add(ui.label("LineEdit:"), row, 0);
        layout.add(lineEdit, row++, 1);
        layout.add(ui.label("RadioButton:"), row, 0);
        layout.add(radioButton0, row++, 1);
        layout.add(ui.label("RadioButton:"), row, 0);
        layout.add(radioButton1, row++, 1);
        layout.add(ui.label("Dial:"), row, 0);
        layout.add(dial, row++, 1);





I decided to make this post after seeing other similar projects:
LWJUI - http://www.java-gaming.org/topics/lwjgui-application-gui-solution-for-lwjgl3/38726/view.html
LEGUI - http://www.java-gaming.org/topics/legui-gui-library-for-lwjgl/38565/view.html

I don’t have any intention of continuing my own implementation of the API because I’d rather contribute to an existing UI library but I like the AUI api. There’s a lot of things that need to be fixed with the internal Layout and Event handler so I’d figure I’d just scrap the project and try to implement AUI with other existing UI libraries. Also those two projects seem to be using NanoVG and I think LEGUI uses Yoga. Both libraries seem very robust and I didn’t know they existed while working on this project. :o