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)
Features:
[tr][td]Layouts[/td][td]Controls[/td][td]Panes[/td][td]Misc[/td][/tr]
[tr][td]VBox[/td][td]Button[/td][td]StackPane[/td][td]Label[/td][/tr]
[tr][td]HBox[/td][td]CheckBox[/td][td]SplitPane[/td][td]Font[/td][/tr]
[tr][td]BorderPane[/td][td]RadioButton[/td][td]ScrollPane[/td][td]Image[/td][/tr]
[tr][td]GridPane[/td][td]SegmentedButton[/td][td]TabPane[/td][td]ImageView[/td][/tr]
[tr][td][/td][td]MenuBar[/td][td]OpenGLPane[/td][td][/td][/tr]
[tr][td][/td][td]ContextMenu[/td][td]BlurPane[/td][td][/td][/tr]
[tr][td][/td][td]TextArea[/td][td]FloatingPane[/td][td][/td][/tr]
[tr][td][/td][td]CodeArea[/td][td]TreePane[/td][td][/td][/tr]
[tr][td][/td][td]ToolBar[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]TextField[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]PasswordField[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]SearchField[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]ColorPicker[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]Slider[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]Combobox[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]ToggleButton[/td][td][/td][td][/td][/tr]
[tr][td][/td][td]ToggleSwitch[/td][td][/td][td][/td][/tr]
Images:
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.