LWJGUI - Application GUI Solution for LWJGL3

This is a project I’ve been working on off-and-on for the last couple months. I wanted to create a simple user-interface system that worked with LWJGL3 for my projects, but none existed. I wanted to keep it simple and designed similarly to JavaFX to reduce the overhead of learning another UI system.

Repository (Contains source, compiled version, and examples)

Images:
NfH3uUB
image
image

Simple use-case example:


package lwjgui;

import lwjgui.LWJGUIApplication;
import lwjgui.scene.*;
import lwjgui.scene.layout.*;
import lwjgui.scene.control.*;

public class HelloWorld extends LWJGUIApplication {
	public static final int WIDTH   = 320;
	public static final int HEIGHT  = 240;

	public static void main(String[] args) {
		launch(args);
	}
	
	@Override
	public void start(String[] args, Window window) {		
		// Create a simple root pane
		StackPane pane = new StackPane();
		
		// Put a label in the pane
		pane.getChildren().add(new Label("Hello World!"));
		
		// Create a new scene
		window.setScene(new Scene(pane, WIDTH, HEIGHT));
		
		// Make window visible
		window.show();
	}
}

More complex use-case example:


package test;

import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwTerminate;

import java.io.IOException;

import org.lwjgl.glfw.GLFW;

import lwjgui.LWJGUI;
import lwjgui.LWJGUIUtil;
import lwjgui.scene.Scene;
import lwjgui.scene.Window;
import lwjgui.scene.control.Label;
import lwjgui.scene.layout.StackPane;

public class HelloWorld {
	public static final int WIDTH   = 320;
	public static final int HEIGHT  = 240;

	public static void main(String[] args) throws IOException {
		if ( !glfwInit() )
			throw new IllegalStateException("Unable to initialize GLFW");

		// Create a standard opengl 3.2 window. You can do this yourself.
		long window = LWJGUIUtil.createOpenGLCoreWindow("Hello World", WIDTH, HEIGHT, true, false);
		
		// Initialize lwjgui for this window
		Window lwjguiWindow = LWJGUI.initialize(window);
		
		// Add some components
		addComponents(lwjguiWindow.getScene());

		// Show window
		lwjguiWindow.show()
		
		// Game Loop
		while (!GLFW.glfwWindowShouldClose(window)) {
			// Render GUI
			LWJGUI.render();
		}
		
		// Stop GLFW
		glfwTerminate();
	}

	private static void addComponents(Scene scene) {
		// Create a simple pane
		StackPane pane = new StackPane();
		
		// Set the pane as the scenes root
		scene.setRoot(pane);
		
		// Put a label in the pane
		pane.getChildren().add(new Label("Hello World!"));
	}
}

If there’s any questions on how to use this I will gladly answer them.

CSS Styling is not yet supported. It is planned for the future, but I want to work on core functionality first.

Caveats:

  • Deprecated OpenGL (OpenGL 2) is not fully supported
  • This is designed to work with a standard render-loop setup. LWJGUI does not handle your render loop for you.
  • LWJGUI’s render method will loop through every initialized window, set the current context to it, and begin drawing it’s UI elements. There is a convenience method to hook your own manual drawing at the start of a window draw inside the Window class. See OpenGLExample.java. After drawing it will swap the buffers unless you set the flag to false.

It’d be absolutely fantastic if it was API-compatible with Swing (modulo package names) so that one could use WindowBuilder to design the GUI graphically and then just change some package names (so that your classes will be used instead of Swing’s) and voilà.

That’s what I was going for, but with JavaFX. I preserved the same package and class names.

@KaiHH But what is wrong with Gluon Scene Builder? I think it is more easy to use than the Swing GUI Builder.

Yep, the Gluon scene builder is a nice tool. But it is rather geared towards JavaFX.

Cas :slight_smile:

Really cool project. I’m gonna clone and take a deeper look at it but from what I’ve seen it looks really interesting. I’ve been working on a UI on my own but I’d rather contribute to an existing UI library if you need any help.

I made a topic here of what I worked on: http://www.java-gaming.org/topics/abstract-user-interface-implementation-with-lwjgl/38729/view.html
There’s also LEGUI which I think might interest you: http://www.java-gaming.org/topics/legui-gui-library-for-lwjgl/38565/view.html

Update log of the last few days:

  • Fixed issue where text of length 0 would crash under the new version of LWJGL
  • Added ability to set whether LWJGUI will automatically call swap buffers after drawing (default is true)
  • Added setGraphic() method to MenuItem
  • Implemented Toolbar
  • Increased Performance of node positioning (especially SplitPane)

Thanks, this has been fixed in 3.1.7 snapshot 10.

Updates from the last few days:

  • Linked icon sizes in Labeled Objects to the text size
  • Text Boxes will force their size to a tab pane if they are too large
  • Rewrote event system to be lambda friendly (All old event code you wrote must be updated)
  • Implemented MouseClick event
  • Implemented Mouse icon for Split Pane Dividers
  • Implemented editable field in TextInputControl objects
  • Implemented a setFlipY() method in OpenGLPane

Also started using this library to work on another one of my projects:

http://magaimg.net/img/5sxl.png

Here’s a laundry list of updates over the months:

  • Added disabled property to button objects
  • Fixed issue with text next to checkboxes not positioning correctly
  • Improved font loading time (makes new window loading almost instant)
  • Fixed issue with context menus not being properly sized
  • Better listener handling when removing nodes

Updates since December…

  • Lots of improvements to node positioning code
  • Created JavaFX styled application system (LWJGUIApplication)
  • Changed default button rendering (much prettier)
  • Added Animation system - Thanks to @SkyAphid
  • Added color picker
  • Added syntax highlighting in text areas
  • Added comboboxes
  • Added slider

Thanks to @Guerra2442 LWJGUI now runs with no leaked memory left behind. This also comes with some performance benefits as well without any change to the public facing API.

Also, we’ve added CSS support. It works with element tag, id, and class based selectors just like in the normal CSS specification. Pseudo Classes also work, but only a handful of them… (hover, focus, select, active, disabled)