Tiny renderer-agnostic UI toolkit in pure Java. No dependencies — drop-in usable in Minecraft mods, JavaFX, Swing, AWT, headless tests, or any project that can implement a 6-method URenderer interface.
Extracted from the OpenFriend mod where it powers the in-game Friends List overlay across 30 Minecraft versions (1.16.5 → 1.21.11) without depending on any single MC rendering API. The mod implements URenderer differently for each MC version (PoseStack era, GuiGraphics era, Matrix3x2fStack era) — the UI code itself never changes.
9 source files, ~1500 lines total. No transitive dependencies, no reflection, no resource loading.
| Class | Role |
|---|---|
URenderer | The single rendering interface to implement — fillRect, drawText, drawHead, pushClip/popClip, etc. |
UComponent | Base class — bounds, mouse-event plumbing, hover state |
UPanel | Container with padding, optional background, child layout |
UButton | Click handler, hover style, enabled / disabled state, primary / subtle / danger styles |
UInput | Single-line text input with placeholder, max length, focus, IME-friendly char handling |
UTabBar | Horizontal tab strip with optional badges, equal-slice or natural-width layout |
UScrollPane | Vertical scrolling viewport with mouse-wheel + click-drag scrollbar |
UDivider | Single horizontal pixel rule with optional label |
UTheme | Color constants (background, text, accent, danger, etc.) |
Most UI toolkits are tightly bound to one rendering backend. OpenMix flips it — components describe what to draw via URenderer, the host application decides how. The same UPanel tree drives Minecraft 1.16.5 PoseStack, Minecraft 1.21.11 Matrix3x2fStack, or a software canvas in a unit test, just by swapping the URenderer implementation.
publicfinalclassMyRendererimplementsURenderer {
@OverridepublicvoidfillRect(intx, inty, intw, inth, intargb) { /* ... */ }
@OverridepublicvoiddrawText(intx, inty, Stringtext, intargb) { /* ... */ }
@OverridepublicinttextWidth(Stringtext) { return/* ... */; }
@OverridepublicinttextHeight() { return/* ... */; }
@OverridepublicvoidpushClip(intx, inty, intw, inth) { /* ... */ }
@OverridepublicvoidpopClip() { /* ... */ }
// (full interface in URenderer.java)
}
UPanelroot = newUPanel();
root.setBounds(0, 0, 320, 240);
root.addChild(newUButton("Click me", () -> System.out.println("hi")));
root.layout();
MyRendererr = newMyRenderer();
root.render(r); // draws via your backendroot.mouseClick(160, 120, 0); // dispatch inputSee how OpenFriend implements URenderer for each Minecraft version:
- Minecraft 1.20.4 / GuiGraphics —
MCRenderer.java - The mod's 1.16.5 source tree ships with the OpenFriend release if you want a PoseStack-era reference
jp.zpw.openfriend.common.ui — kept on the OpenFriend namespace because the released mod jars already ship classes from this package. A future v2 may move to jp.zpw.openmix.
MIT. See LICENSE.