How It Works

The Fluent API — writing code like a sentence

You might have noticed the code looks like a chain of dot-separated words:

Example of fluent API
new Button(100, 100, 200, 40)
    .text("Save")
    .colorScheme(Button.Style.GREEN)
    .cornerRadius(8)
    .onClick(() -> save());

This is called a Fluent API. It works because every method (like .text(), .colorScheme()) returns this — meaning "the same object I'm configuring". So you can keep chaining. Think of it like building a sentence: "Create a button, with text 'Save', colored green, with rounded corners, that calls save() when clicked."

You don't have to chain everything. This is exactly equivalent:

Without chaining — same result
Button myButton = new Button(100, 100, 200, 40);
myButton.text("Save");
myButton.colorScheme(Button.Style.GREEN);
myButton.cornerRadius(8);
myButton.onClick(() -> save());
addComponent(myButton);

Coordinates — where things go

Every component takes 4 numbers when you create it: (x, y, width, height).

  • x — how far from the left edge of the screen
  • y — how far from the top of the screen
  • width — how wide the component is
  • height — how tall the component is

These numbers are in design pixels — they assume a screen that is 1920 pixels wide and 1080 pixels tall. So x=960, y=540 is exactly the center of the screen, regardless of what resolution the player is actually running.

Automatic scaling

EriAPI automatically converts your design-pixel coordinates to real screen coordinates. If a player runs at 1280x720, EriAPI scales everything down so it still looks correct. You never have to think about this — just design for 1920x1080 and the framework handles the rest.

The component hierarchy

Everything you put on screen is a "component". Components can contain other components (like a panel containing buttons). There are three base types you should know about:

Class What it is When to use
Component abstract The root of everything — all components extend this
InteractiveComponent abstract Extends Component — adds onClick, onHover, onRelease
ContainerComponent abstract Extends Component — can hold child components (e.g. ScrollPanel)

As a beginner, you don't need to worry about extending these yourself. Just use the ready-made components described in the next sections.

EriGuiScreen

EriGuiScreen
fr.eri.eriapi.gui
Base class

EriGuiScreen is the base class for every screen you create with EriAPI. Think of it as the blank canvas onto which you place your components. By extending it, you get automatic event handling, rendering, scaling, and keyboard shortcuts (like Escape to close) for free.

What you need to do

There is only one method you must implement: buildComponents(). This is called once when the screen opens. Inside it, you call addComponent() for each thing you want to display.

Minimal EriGuiScreen
public class MyScreen extends EriGuiScreen {

    @Override
    protected void buildComponents() {
        // Add your components here
        addComponent(new Label(760, 500, 400, 30)
            .text("Hello, Minecraft!")
            .color(Colors.CYAN)
            .align(Label.Align.CENTER)
        );
    }

}

Available methods you can override

  • buildComponents()
    REQUIRED — called when the screen opens. Add all your components here.
    ABSTRACT
  • onScreenClosed()
    Optional — called when the player closes the screen (e.g. presses Escape). Use to save data, play sounds, etc.
    EVENT
  • addComponent(Component c)
    Registers a component so it gets drawn and receives events. Call this inside buildComponents() for every component you create.
    FLUENT

Automatic ItemSlot integration

EriGuiScreen automatically manages the complete lifecycle of ItemSlot components present in the component tree. No extra configuration is needed.

EriGuiScreen event ItemSlot action triggered
drawScreen(mouseX, mouseY, pt) ItemSlot.renderCursorItem(mouseX, mouseY) after all components and notifications
mouseReleased(x, y, btn) ItemSlot.onDragEnd() before propagating to components
mouseClickMove(x, y, btn, dt) slot.checkDragHover(x, y) on every ItemSlot in the tree
onGuiClosed() ItemSlot.clearCursor() to reset the global state

Components Overview

A "component" is any visual element you place on screen — a button, a piece of text, a rectangle, an input field, etc. Here is a quick summary of all available components. Each one is documented in detail in the sections that follow.

Component Category What it does
ButtonInteractionA clickable button with 7 color styles
TexturedButtonInteractionA button that shows an image/texture
LabelDisplayA piece of text, with alignment and scaling
RectangleShapeA colored box, optionally with rounded corners
CircleShapeA circle drawn on screen
TriangleShapeA triangle pointing up, down, left, or right
TextFieldInputA text input box the player can type in
NumericFieldInputA text input that only accepts numbers
PasswordFieldInputA text input that hides the typed text
GridLayoutLayoutAutomatically arranges components in a grid
ScrollListLayoutA scrollable list of items with optional search
ScrollPanelLayoutA scrollable container for any components
ProgressBarControlShows progress (0% to 100%)
SliderControlA draggable slider for picking a value
CheckboxControlA checkbox the player can tick on/off
RadioButtonControlA single selectable option
RadioGroupControlA group of RadioButtons where only one can be selected

Background Texture (all components)

All components inherit these texture methods from the base Component class. When a background image is set, it replaces the color rendering. If no image is set, the classic color behavior applies unchanged.

  • backgroundImage(ResourceLocation image)
    Background image for the component. Replaces the background color when set. Works on Button, TextField, Panel, ScrollList, ScrollPanel, ContainerComponent, ProgressBar, etc.
    Fluent
  • scaleMode(ScaleMode mode)
    Texture scaling mode: STRETCH, FIT, FILL, TILE, NINE_SLICE.
    Fluent
  • imageTint(int argb)
    ARGB tint applied to the texture. 0xFFFFFFFF = no tint (default).
    Fluent
  • nineSliceBorder(int pixels)
    Border size for NINE_SLICE mode (in texture pixels). Corners are preserved, edges are stretched.
    Fluent
  • imageUV(int u, int v, int uW, int vH, int texW, int texH)
    Sub-region of a spritesheet. Allows using a single image containing multiple textures.
    Fluent
Java — Background texture on any component
ResourceLocation panelTex = new ResourceLocation("mymod", "textures/gui/panel.png");

// Works on ScrollPanel, ScrollList, ContainerComponent, Panel...
ScrollPanel panel = new ScrollPanel()
    .originalPos(100, 50)
    .originalSize(300, 200)
    .backgroundColor(Colors.PANEL_BG);  // fallback if no texture
panel.backgroundImage(panelTex);
panel.scaleMode(ScaleMode.NINE_SLICE);
panel.nineSliceBorder(8);

// Also works on TextField, Button, etc.
TextField tf = new TextField()
    .originalPos(100, 260)
    .originalSize(200, 20)
    .placeholder("Textured input...");
tf.backgroundImage(new ResourceLocation("mymod", "textures/gui/input.png"));
tf.scaleMode(ScaleMode.NINE_SLICE);
tf.nineSliceBorder(4);
Full backwards compatibility

If backgroundImage is not set, the component behaves exactly as before (color rendering). No existing code is broken by the texture support addition.

Button

Button
fr.eri.eriapi.gui.components
Interactive

A Button is exactly like a button in any app — the player clicks it and something happens. You decide what happens by passing a function to .onClick(). EriAPI handles everything else: drawing, hover effects, press animation, and disabled states.

Preview
Cyan
Purple
Green
Red
Orange
Gray
White
Outlined
Outlined
Pill Shape
Disabled

Basic example

Button — basic usage
// new Button(x, y, width, height)
// x=760, y=400 means: 760 pixels from the left, 400 from the top (in design space)
addComponent(new Button(760, 400, 400, 40)
    .text("Click Me")                // Text shown on the button
    .colorScheme(Button.Style.CYAN)  // Color style (see the 7 styles below)
    .onClick(() -> {                 // Code that runs when clicked
        System.out.println("Button was clicked!");
    })
);

The 7 color styles

Pass one of these to .colorScheme() to change the button's look. All styles automatically handle hover and pressed states.

Style constantColor
Button.Style.CYANCyan / light blue
Button.Style.PURPLEPurple / violet
Button.Style.GREENGreen
Button.Style.REDRed
Button.Style.ORANGEOrange
Button.Style.GRAYDark gray (neutral)
Button.Style.WHITEWhite / light

All methods

  • text(String text)
    Sets the text displayed on the button.
    FLUENT
  • colorScheme(Button.Style style)
    Sets the color style. Default is CYAN.
    FLUENT
  • outlined(boolean outlined)
    If true, the button is transparent with a colored border instead of a filled background. Great for secondary actions.
    FLUENT
  • cornerRadius(int radius)
    Rounds the corners of the button. 0 = sharp corners, 8 = nicely rounded. Default is 4.
    FLUENT
  • onClick(Runnable action)
    The code that runs when the button is clicked. Use a lambda: () -> doSomething().
    EVENT
  • enabled(boolean enabled)
    If false, the button is grayed out and cannot be clicked. Useful for preventing actions until a condition is met.
    FLUENT
  • visible(boolean visible)
    If false, the button is completely hidden (not drawn, not clickable).
    FLUENT
  • textScale(float scale)
    Changes the size of the text inside the button. Default is 1.0.
    FLUENT

Advanced example — multiple buttons

Button — advanced
// A primary "Save" button, filled cyan with rounded corners
addComponent(new Button(760, 500, 180, 44)
    .text("Save")
    .colorScheme(Button.Style.GREEN)
    .cornerRadius(10)
    .onClick(() -> savePlayerData())
);

// A secondary "Cancel" button, outlined style
addComponent(new Button(960, 500, 180, 44)
    .text("Cancel")
    .colorScheme(Button.Style.GRAY)
    .outlined(true)         // Transparent background, just a border
    .cornerRadius(10)
    .onClick(() -> mc.displayGuiScreen(null))  // null closes the screen
);

// A "Delete" button that starts disabled
// (you'd enable it later based on game logic)
addComponent(new Button(1160, 500, 180, 44)
    .text("Delete")
    .colorScheme(Button.Style.RED)
    .cornerRadius(10)
    .enabled(false)        // Grayed out — player can't click yet
    .onClick(() -> deleteItem())
);
Tip: enable/disable based on conditions

You can store the button in a variable and call myButton.enabled(false) later in your code to disable it dynamically. For example, disable "Buy" if the player doesn't have enough gold.

Texture Support (per-state)

Button supports different textures for each visual state. The backgroundImage inherited from Component serves as the default texture (normal state). hoverImage and pressedImage change the appearance on hover and click.

  • hoverImage(ResourceLocation image)
    Texture displayed when the mouse hovers over the button. Falls back to backgroundImage if not set.
    Fluent
  • pressedImage(ResourceLocation image)
    Texture displayed when the button is clicked/pressed. Falls back to hoverImage or backgroundImage.
    Fluent
Java — Button with per-state textures
ResourceLocation btnNormal  = new ResourceLocation("mymod", "textures/gui/btn.png");
ResourceLocation btnHover   = new ResourceLocation("mymod", "textures/gui/btn_hover.png");
ResourceLocation btnPressed = new ResourceLocation("mymod", "textures/gui/btn_pressed.png");

Button btn = new Button("Buy")
    .originalPos(100, 200)
    .originalSize(200, 40)
    .hoverImage(btnHover)
    .pressedImage(btnPressed)
    .textColor(Colors.WHITE);
btn.backgroundImage(btnNormal);
btn.scaleMode(ScaleMode.NINE_SLICE);
btn.nineSliceBorder(6);
Texture priority

Priority order: pressedImage > hoverImage > backgroundImage. If no texture is set, the classic color rendering applies (full backwards compatibility).

TexturedButton

TexturedButton
fr.eri.eriapi.gui.components
Interactive

A TexturedButton is a button that shows an image (a texture from your mod's resource pack) instead of a colored box. Think of icon buttons in games — a gear icon for settings, an X icon to close a panel, etc. You can also add an optional text label on top of the texture.

Preview
Play
Hover: cyan tint

Basic example

TexturedButton — basic usage
// First, create the ResourceLocation that points to your image file.
// The image must be in: src/main/resources/assets/yourmod/textures/gui/mybutton.png
ResourceLocation myIcon = new ResourceLocation("yourmod", "textures/gui/mybutton.png");

addComponent(new TexturedButton(900, 400, 64, 64)  // 64x64 button
    .texture(myIcon)                 // The image to display
    .hoverTint(0x44FFFFFF)           // A slight white tint when hovered (ARGB)
    .pressedTint(0x66000000)         // A dark tint when pressed (ARGB)
    .onClick(() -> openSettings())   // Action when clicked
);

All methods

  • texture(ResourceLocation texture)
    The image to draw as the button background. Must be a valid resource location pointing to a PNG file in your mod's assets.
    FLUENT
  • hoverTint(int argbColor)
    A color overlay applied when the mouse hovers over the button. Use a semi-transparent color like 0x44FFFFFF (44 = alpha, white tint).
    FLUENT
  • pressedTint(int argbColor)
    A color overlay applied when the button is being pressed/clicked. Typically a dark tint like 0x66000000.
    FLUENT
  • label(String text)
    Optional text drawn on top of the texture. Useful for labeled icon buttons.
    FLUENT
  • onClick(Runnable action)
    Code that runs when the button is clicked.
    EVENT
About ARGB color format

Colors in EriAPI use the format 0xAARRGGBB where AA is the alpha (transparency: 00 = fully transparent, FF = fully opaque), RR is red, GG is green, and BB is blue. Example: 0x80FF0000 is semi-transparent red.

Label

Label
fr.eri.eriapi.gui.components
Display

A Label displays text on screen. It supports alignment (left, center, right), scaling (making text bigger or smaller), drop shadows, and clipping (trimming text with "..." if it's too long to fit). Labels can also scroll their text when hovered.

Preview
Menu Title
Align LEFT
Left aligned
Align CENTER
Centered text
Align RIGHT
Right aligned
Cyan colored text

Basic example

Label — basic usage
// new Label(x, y, width, height)
addComponent(new Label(400, 200, 600, 30)
    .text("Welcome to my mod!")      // The text to show
    .color(Colors.WHITE)             // Text color
    .align(Label.Align.CENTER)       // Center-align within the width
    .scale(1.5f)                     // 1.5x bigger than default text
    .shadow(true)                    // Draw a drop shadow behind the text
);

All methods

  • text(String text)
    The text to display. You can update this at any time by calling it again.
    FLUENT
  • color(int argbColor)
    The text color. Use a constant from Colors (e.g. Colors.WHITE) or write an ARGB hex like 0xFFFF0000 for red.
    FLUENT
  • align(Label.Align alignment)
    Text alignment: Label.Align.LEFT, Label.Align.CENTER, or Label.Align.RIGHT.
    FLUENT
  • scale(float scale)
    Text size multiplier. 1.0 = normal, 2.0 = double size, 0.5 = half size.
    FLUENT
  • shadow(boolean shadow)
    If true, a drop shadow is drawn behind the text, improving readability.
    FLUENT
  • clip(boolean clip)
    If true and the text is too long to fit in the label's width, it is clipped with "..." at the end.
    FLUENT
  • scrollOnHover(boolean scroll)
    If true, when the player hovers over the label, the text scrolls horizontally to reveal the full content.
    FLUENT
  • scaleToFit(boolean enabled)
    If true, instead of truncating text with "...", automatically reduces the text scale so it fits exactly within the component width. Mutually exclusive with wrapped() at render time — if both are active, wrapped takes priority.
    FLUENT
  • wrapped(boolean enabled)
    If true, text wraps to multiple lines at word boundaries instead of being truncated. If the wrapped content exceeds the component height, vertical mouse scroll is enabled (scissor clipped). Mutually exclusive with scaleToFit()wrapped wins if both are active.
    FLUENT

Advanced example

Label — advanced
// A big title, centered, with a shadow
addComponent(new Label(400, 100, 1120, 60)
    .text("Player Statistics")
    .color(0xFFFFFFFF)               // Fully opaque white
    .align(Label.Align.CENTER)
    .scale(2.5f)
    .shadow(true)
);

// A subtitle in muted cyan
addComponent(new Label(400, 170, 1120, 30)
    .text("Your progress so far")
    .color(Colors.CYAN_DIM)
    .align(Label.Align.CENTER)
    .scale(1.2f)
);

// A long description that clips with "..." if too long
addComponent(new Label(400, 300, 500, 24)
    .text("This is a very long text that might not fit in the available space.")
    .color(Colors.LIGHT_GRAY)
    .clip(true)                      // Cut off with "..."
    .scrollOnHover(true)             // Scroll when hovered to show full text
);

// Auto-shrink text to fit within the width (scaleToFit)
addComponent(new Label(400, 340, 200, 24)
    .text("VeryLongPlayerNameThatDoesNotFit")
    .color(Colors.GRAY)
    .scaleToFit(true)                // Reduces font scale to fit in 200px
);

// Multi-line wrapped text with scroll if it overflows
addComponent(new Label(400, 380, 500, 80)
    .text("This is a long description that will automatically wrap at word boundaries when it exceeds the component width. If the wrapped text exceeds the component height, the player can scroll with the mouse wheel.")
    .color(Colors.LIGHT_GRAY)
    .wrapped(true)                   // Word-wrap instead of truncating
);

Rectangle

Rectangle
fr.eri.eriapi.gui.components
Shape

A Rectangle draws a colored box on screen. You can fill it with a solid color, add a border, and optionally round the corners. Rectangles are great for panels, backgrounds, dividers, and decorative elements.

Preview

Basic example

Rectangle — basic usage
// Draw a semi-transparent dark background panel
addComponent(new Rectangle(300, 150, 800, 500)
    .fillColor(0xCC101020)      // Dark blue-ish, 80% opaque (CC = 204/255)
    .borderColor(0xFF2255FF)    // Bright blue border
    .borderThickness(2)         // 2-pixel border
    .cornerRadius(12)           // Nicely rounded corners
);

All methods

  • fillColor(int argbColor)
    The inside color of the rectangle. Use 0x00000000 for transparent (no fill).
    FLUENT
  • borderColor(int argbColor)
    The color of the border around the rectangle. You don't have to set this — by default there is no border.
    FLUENT
  • borderThickness(int thickness)
    How thick (in design pixels) the border is. Ignored if no borderColor is set.
    FLUENT
  • cornerRadius(int radius)
    How round the corners are. 0 = sharp right-angle corners, higher values = rounder. Try values between 4 and 16.
    FLUENT
Tip: layering

Components are drawn in the order you call addComponent(). So add background rectangles first, then labels and buttons on top. Later-added components appear in front of earlier ones.

Circle

Circle
fr.eri.eriapi.gui.components
Shape

Draws a filled circle on screen. Good for status indicators, avatars, decorative dots, or anything that needs to be round. The position is the top-left corner of the bounding box, and width/height should be equal to make a perfect circle.

Preview

Basic example

Circle — basic usage
// Draw a green circle — "online" indicator
// Position: x=850, y=450. Size: 40x40 (equal width and height = perfect circle)
addComponent(new Circle(850, 450, 40, 40)
    .fillColor(0xFF00CC44)      // Bright green, fully opaque
    .borderColor(0xFF009933)    // Darker green border
);

All methods

  • fillColor(int argbColor)
    The color that fills the inside of the circle.
    FLUENT
  • borderColor(int argbColor)
    Optional outline color around the circle.
    FLUENT

Triangle

Triangle
fr.eri.eriapi.gui.components
Shape

Draws a triangle pointing in one of four directions: up, down, left, or right. Useful for arrows, expand/collapse indicators, dropdown arrows, pagination buttons, etc.

Preview
UP
DOWN
LEFT
RIGHT

Basic example

Triangle — basic usage
// A downward-pointing arrow, like a dropdown indicator
addComponent(new Triangle(920, 440, 40, 24)
    .direction(Triangle.Direction.DOWN)   // UP, DOWN, LEFT, or RIGHT
    .fillColor(0xFFCCCCCC)                // Light gray
);

All methods

  • direction(Triangle.Direction dir)
    Which way the triangle points. Options: Triangle.Direction.UP, DOWN, LEFT, RIGHT.
    FLUENT
  • fillColor(int argbColor)
    The color that fills the triangle.
    FLUENT

TextField

TextField
fr.eri.eriapi.gui.components
Input

A TextField is a box the player can click on and type into — like a search bar or a name input. It handles everything automatically: cursor blinking, text scrolling when the text gets long, keyboard shortcuts (Ctrl+C to copy, Ctrl+V to paste, Ctrl+X to cut), and focus management (clicking another text field deselects this one).

Preview
Enter your name...
MyUsername

Basic example

TextField — basic usage
// Keep a reference to read the text later
TextField nameField = new TextField(600, 400, 400, 36)
    .placeholder("Enter your username...")   // Gray hint text shown when empty
    .maxLength(32)                           // Maximum 32 characters allowed
    .onTextChanged(text -> {                 // Called every time the text changes
        System.out.println("Text is now: " + text);
    });

addComponent(nameField);

// Later (e.g. in your save button's onClick), read the text:
// String enteredName = nameField.getText();

All methods

  • placeholder(String hint)
    Gray hint text displayed when the field is empty. Disappears when the player starts typing.
    FLUENT
  • maxLength(int max)
    Maximum number of characters the player can type. The field stops accepting input once this limit is reached.
    FLUENT
  • onTextChanged(Consumer<String> callback)
    A function called every time the text changes. The new text is passed as a parameter.
    EVENT
  • getText()
    Returns the text currently typed in the field. Call this when the player submits a form.
    GETTER
  • setText(String text)
    Programmatically sets the content of the field. Useful to pre-fill with existing data.
    FLUENT
  • setFocused(boolean focused)
    Manually give or remove keyboard focus. When focused, keyboard input goes to this field.
    FLUENT
Keyboard shortcuts (built-in)

TextField automatically supports: Ctrl+C (copy), Ctrl+V (paste), Ctrl+X (cut), Home/End (jump to start/end), Arrow keys (move cursor). You don't need to add any code for these.

NumericField

NumericField
fr.eri.eriapi.gui.components
Input

A NumericField is like a TextField but it only accepts numbers. The player cannot type letters or symbols. You can set a minimum and maximum value, allow or disallow decimal numbers, and allow or disallow negative numbers. Perfect for quantity selectors, price inputs, or any numeric setting.

Preview
-
42
+
min: 0   max: 100

Basic example

NumericField — basic usage
NumericField quantityField = new NumericField(700, 400, 200, 36)
    .placeholder("Quantity")    // Hint text when empty
    .min(1)                     // Minimum allowed value
    .max(64)                    // Maximum allowed value (one stack)
    .decimal(false)             // Only whole numbers (no decimals)
    .negative(false);           // No negative numbers

addComponent(quantityField);

// Later, get the value:
// double qty = quantityField.getValue();

All methods

  • min(double minimum)
    The smallest value the field will accept. The field clamps to this if the player types something lower.
    FLUENT
  • max(double maximum)
    The largest value the field will accept.
    FLUENT
  • decimal(boolean allow)
    If true, decimal numbers (like 3.14) are allowed. If false, only whole numbers.
    FLUENT
  • negative(boolean allow)
    If true, negative numbers are allowed. If false, only zero and positive.
    FLUENT
  • getValue()
    Returns the current numeric value as a double. Cast to int if you need a whole number.
    GETTER

PasswordField

PasswordField
fr.eri.eriapi.gui.components
Input

A PasswordField is a text input where every character is hidden behind a bullet symbol (like ••••••). This prevents someone looking over the player's shoulder from reading the password. It can optionally show a "reveal" toggle button.

Preview
••••••••

Basic example

PasswordField — basic usage
PasswordField passField = new PasswordField(700, 450, 400, 36)
    .placeholder("Enter password...")
    .bulletChar('*')          // The character used to hide each letter. Default is '•'
    .toggleReveal(true);      // Show an eye icon to reveal/hide the password

addComponent(passField);

// Read the actual password (not the bullet characters):
// String password = passField.getText();

All methods

  • bulletChar(char bullet)
    The character shown in place of each typed character. Default is the bullet '•'. You can use '*' for a more classic look.
    FLUENT
  • toggleReveal(boolean show)
    If true, a small eye icon appears at the right of the field. Clicking it toggles between showing and hiding the text.
    FLUENT
  • getText()
    Returns the actual text typed (not the bullet characters). Use this to validate the password.
    GETTER

MultiLineField

A multi-line text input with vertical scrolling, optional line numbers, and full multi-line selection. Ideal for consoles, code editors, or long text areas.

Preview
1
2
3
4
public void hello() {
  System.out.println(
    "Hello EriAPI!"
  );
MultiLineField
fr.eri.eriapi.gui.components.MultiLineField
extends InteractiveComponent
Java — Basic MultiLineField
MultiLineField editor = new MultiLineField()
    .originalPos(50, 50)
    .originalSize(300, 150)
    .placeholder("Enter your code here...")
    .showLineNumbers(true)
    .maxLines(100)
    .tabSize(4)
    .onTextChanged(text -> System.out.println("Text changed"));

Keyboard shortcuts

ShortcutAction
EnterNew line
Backspace (at col 0)Merge with previous line
Delete (at end of line)Merge with next line
↑ / ↓Vertical navigation (column memory)
Home / EndStart / end of line
Ctrl+Home / EndStart / end of document
Shift+arrowsMulti-line selection
Ctrl+A / C / V / XSelect all / Copy / Paste / Cut
TabInsert spaces (configurable via tabSize)

Fluent API

MethodDescription
.placeholder(String)Text shown when field is empty
.maxLength(int)Max total character count
.maxLines(int)Max line count (0 = unlimited)
.showLineNumbers(boolean)Show line numbers
.tabSize(int)Number of spaces for Tab (default: 4)
.lineHeight(int)Line height in pixels
.scrollSpeed(int)Vertical scroll speed
.onTextChanged(Consumer<String>)Callback when text changes
.backgroundColor(int)Background color
.textColor(int)Text color
.cursorColor(int)Cursor color
.selectionColor(int)Selection color
.lineNumberColor(int)Line number color

Useful methods

MethodDescription
getText()Returns all text (lines joined by \n)
setText(String)Replaces all text
getLineCount()Current line count
isFocused()Whether the field has focus

AutoCompleteField

A text input with auto-complete suggestions displayed in a dropdown. Extends TextField — same editing behavior, plus a suggestion dropdown overlay.

Preview
dia
diamond_sword
diamond_pickaxe
diamond_block
AutoCompleteField
fr.eri.eriapi.gui.components.AutoCompleteField
extends TextField
Java — AutoCompleteField with static list
AutoCompleteField field = new AutoCompleteField()
    .originalPos(100, 50)
    .originalSize(200, 16)
    .placeholder("Command...")
    .suggestions("help", "give", "gamemode", "gamerule", "tp", "time")
    .onSuggestionAccepted(s -> System.out.println("Accepted: " + s));
Java — AutoCompleteField with dynamic supplier
AutoCompleteField field = new AutoCompleteField()
    .originalPos(100, 50)
    .originalSize(200, 16)
    .placeholder("Search player...")
    .suggestionSupplier(query -> {
        // Dynamic search based on typed text
        return playerList.stream()
            .filter(p -> p.toLowerCase().startsWith(query.toLowerCase()))
            .collect(Collectors.toList());
    })
    .maxSuggestions(6)
    .filterContains(true);

Dropdown navigation

ShortcutAction
↑ / ↓Navigate suggestions
EnterAccept selected suggestion
TabAccept suggestion (or the only remaining one)
EscapeClose dropdown (keep focus)

Fluent API

MethodDescription
.suggestions(String...)Static suggestion list
.suggestions(List<String>)Static suggestion list
.suggestionSupplier(Function<String, List<String>>)Dynamic suggestion supplier
.maxSuggestions(int)Max displayed suggestions (default: 8)
.caseSensitive(boolean)Case-sensitive filtering (default: false)
.filterContains(boolean)true = contains, false = startsWith (default)
.onSuggestionAccepted(Consumer<String>)Callback when a suggestion is accepted
.dropdownBackground(int)Dropdown background color
.dropdownBorder(int)Dropdown border color
.dropdownHoverColor(int)Dropdown hover color
.dropdownTextColor(int)Dropdown text color
.dropdownItemHeight(int)Dropdown item height
Note: The dropdown uses RenderUtil.pauseScissor() to render on top of parent containers (ScrollPanel, etc.), ensuring visibility even in complex layouts.

GridLayout

GridLayout
fr.eri.eriapi.gui.components
Layout

A GridLayout automatically arranges components into a grid — rows and columns. Instead of calculating x/y coordinates for each button yourself, you just add them to the grid and it places them evenly. Think of a hotbar grid, a 3x3 option panel, or a card layout.

Preview
1
2
3
4
5
6

Basic example

GridLayout — basic usage
// Create a 2-column grid starting at x=400, y=300, total size 800x400
GridLayout grid = new GridLayout(400, 300, 800, 400)
    .columns(2)          // 2 columns side by side
    .spacing(16)         // 16-pixel gap between items
    .padding(24);        // 24-pixel padding inside the grid borders

// Add buttons — they are placed automatically left-to-right, then wrap to next row
grid.add(new Button(0, 0, 0, 44).text("Option 1").colorScheme(Button.Style.CYAN));
grid.add(new Button(0, 0, 0, 44).text("Option 2").colorScheme(Button.Style.PURPLE));
grid.add(new Button(0, 0, 0, 44).text("Option 3").colorScheme(Button.Style.GREEN));
grid.add(new Button(0, 0, 0, 44).text("Option 4").colorScheme(Button.Style.RED));

// Don't forget to add the grid itself to the screen
addComponent(grid);
Position of child components doesn't matter

When adding components to a GridLayout, the x/y coordinates you pass to each component's constructor are ignored — the grid calculates the correct position automatically. Just pass 0, 0 for x and y. The width and height still matter for items that don't auto-fill (like labels), but the grid overrides the cell dimensions.

All methods

  • columns(int count)
    How many columns the grid has. Components wrap to the next row after this many columns.
    FLUENT
  • rows(int count)
    Optional: explicitly set how many rows. Usually you let the grid calculate this from the number of items.
    FLUENT
  • spacing(int pixels)
    Gap (in design pixels) between each cell.
    FLUENT
  • padding(int pixels)
    Empty space around the inside edge of the grid.
    FLUENT
  • add(Component component)
    Adds a component to the next available cell in the grid.
    FLUENT

ScrollList

ScrollList
fr.eri.eriapi.gui.components
Layout

A ScrollList is a list of items that the player can scroll through. Think of a server player list, an item catalog, a friend list, or a list of available quests. It optionally shows a search bar at the top so the player can filter items by name. The list renders a scrollbar automatically when there are more items than fit on screen.

Preview
Diamond Sword
Iron Pickaxe
Enchanted Bow
Golden Apple
Ender Pearl

Basic example

ScrollList — basic usage
// ScrollList(x, y, width, height)
ScrollList myList = new ScrollList(300, 200, 600, 500)
    .showSearch(true)         // Show a search box at the top
    .itemHeight(40)           // Each item is 40 pixels tall
    .showScrollbar(true);     // Show the scrollbar on the right

// Add items to the list (see ListItem section for creating custom items)
myList.addItem(new MyCustomItem("Steve"));
myList.addItem(new MyCustomItem("Alex"));
myList.addItem(new MyCustomItem("Creeper"));

addComponent(myList);

All methods

  • addItem(ListItem item)
    Adds one item to the list. Items are displayed in the order they are added.
    FLUENT
  • showSearch(boolean show)
    If true, a search field appears above the list. Items are filtered in real time as the player types.
    FLUENT
  • showScrollbar(boolean show)
    If true, a scrollbar appears on the side when there are more items than fit.
    FLUENT
  • itemHeight(int pixels)
    How tall each item row is in design pixels.
    FLUENT
  • clearItems()
    Removes all items from the list. Useful when refreshing the list with new data.
    FLUENT

Texture support

The list background uses the inherited backgroundImage from Component. Items and the scrollbar thumb can also receive their own textures.

  • itemBackgroundImage(ResourceLocation texture)
    Background texture for each item (normal state). Replaces itemBackgroundColor when set.
    FLUENT
  • itemHoverImage(ResourceLocation texture)
    Background texture on hover. Falls back to itemBackgroundImage if not set.
    FLUENT
  • itemSelectedImage(ResourceLocation texture)
    Background texture for the selected item. Falls back to itemBackgroundImage if not set.
    FLUENT
  • itemImageScaleMode(ScaleMode mode)
    How the item textures are scaled.
    FLUENT
  • itemImageTint(int argb)
    ARGB tint applied on the item textures.
    FLUENT
  • itemSliceBorder(int pixels)
    9-slice border for item textures (when itemImageScaleMode is NINE_SLICE).
    FLUENT
  • thumbImage(ResourceLocation texture)
    Texture for the scrollbar thumb (the draggable handle).
    FLUENT
  • thumbScaleMode(ScaleMode mode)
    How the thumb texture is scaled.
    FLUENT
  • thumbImageTint(int argb)
    ARGB tint applied on top of the thumb texture.
    FLUENT

ListItem

ListItem
fr.eri.eriapi.gui.components
Abstract

ListItem is an abstract class you extend to create your own custom rows for a ScrollList. Each item has an ID (a unique number), a display name (used for search filtering), and a render() method where you draw whatever you want inside the row.

How to create a custom list item

Custom ListItem — complete example
// Create a file PlayerListItem.java
public class PlayerListItem extends ListItem {

    // The player name this item represents
    private final String playerName;

    // Constructor — takes an ID (unique number) and the player name
    public PlayerListItem(int id, String playerName) {
        super(id, playerName);          // "playerName" is also the search display name
        this.playerName = playerName;
    }

    // This is called by ScrollList to draw your row.
    // x, y = top-left corner of this row on screen
    // width, height = dimensions of the row on screen
    @Override
    public void render(int x, int y, int width, int height, int mouseX, int mouseY) {
        // Draw a simple gray background for each row
        RenderUtil.drawRect(x, y, width, height, 0x33FFFFFF);

        // Draw the player name on the left
        RenderUtil.drawText(playerName, x + 10, y + height / 2 - 4, 0xFFFFFFFF, false);

        // You can draw anything here: icons, health bars, item icons, etc.
    }

    // Optional: called when the player clicks on this row
    @Override
    public void onClick() {
        System.out.println("Player clicked on: " + playerName);
    }

}

Methods to implement

  • render(int x, int y, int width, int height, int mouseX, int mouseY)
    REQUIRED — draw your row content here. x/y is where this row starts on screen. Draw everything relative to x and y.
    ABSTRACT
  • onClick()
    Optional — called when the player clicks on this row. Override it to handle selection.
    EVENT
  • getId()
    Returns the unique ID of this item (set in the constructor).
    GETTER
  • getDisplayName()
    Returns the name used for search filtering.
    GETTER

ListRenderContext

ListRenderContext is a render helper for ListItem rows. It wraps the row coordinates (x, y, width, height) and the mouse position, and exposes ready-to-use methods for drawing design-scaled text, Minecraft item icons, and computing dimensions proportional to the row size.

Without this helper, drawing vertically-centered text inside a row whose height changes with the window quickly becomes painful. With ListRenderContext, you express vertical offsets in permil (1/1000) of the row height — the layout stays correct at every resolution.

ListRenderContext
fr.eri.eriapi.gui.components.ListRenderContext
Render helper
Java — Usage inside a ListItem
import fr.eri.eriapi.gui.components.ListItem;
import fr.eri.eriapi.gui.components.ListRenderContext;

public class RecipeItem extends ListItem {
    private final ItemStack icon;
    private final String name, cost, status;

    public RecipeItem(String id, ItemStack icon, String name, String cost, String status) {
        super(id, name);
        this.icon = icon; this.name = name; this.cost = cost; this.status = status;
    }

    @Override
    public void render(int x, int y, int width, int height, int mouseX, int mouseY, float pt) {
        ListRenderContext ctx = ListRenderContext.of(x, y, width, height, mouseX, mouseY);
        int gap = ctx.gap();

        // Item icon on the left, size auto-proportional to the row height
        int iconSize = ctx.drawItem(icon, gap * 2, 0);
        int textX = gap * 2 + iconSize + gap;

        // Status on the right
        int statusW = ctx.textWidth(status);
        int statusOffsetX = width - gap * 2 - statusW;
        int textMaxW = statusOffsetX - textX - gap;

        // Text with PROPORTIONAL vertical offset (drawTextProp)
        ctx.drawTextProp(name,   textX,         -150, textMaxW,         0xFFFFFFFF);
        ctx.drawTextProp(cost,   textX,         +150, textMaxW,         0xFF4ADE80);
        ctx.drawTextProp(status, statusOffsetX, -150, statusW + gap,    0xFFBB55FF);
    }

    @Override public String getSearchText() { return name; }
}

Public fields

  • final int x, y, width, height
    Row position and size in screen pixels.
    FIELD
  • final int mouseX, mouseY
    Mouse position in screen pixels.
    FIELD

Construction

  • static ListRenderContext of(int x, int y, int width, int height, int mouseX, int mouseY)
    Creates a context from the parameters of ListItem.render().
    STATIC

Proportional sizing

  • int propW(int permil)
    Returns a width proportional to the row width (permil: 1000 = full width). Minimum 1 pixel.
    METHOD
  • int propH(int permil)
    Returns a height proportional to the row height. Minimum 1 pixel.
    METHOD
  • int gap()
    Standard gap proportional to the row width (minimum 2 pixels).
    METHOD

Positioning

  • int midY()
    Vertical center of the row (y + height / 2).
    METHOD
  • int centerY(int elementHeight)
    Y to vertically center an element of the given height.
    METHOD
  • int rightX(int offset)
    X measured from the right edge, inset by offset screen pixels (x + width - offset).
    METHOD
  • boolean isHover(int rx, int ry, int rw, int rh)
    Checks whether the mouse is inside the given screen-pixel rectangle.
    METHOD

Drawing

  • int drawItem(ItemStack stack, int offsetX, int offsetY)
    Draws a Minecraft item icon. Size is proportional to the row height (height - 6 px). When offsetY = 0, the icon is vertically centered. Returns the icon size in screen pixels.
    METHOD
  • void drawText(String text, int offsetX, int offsetY, int maxWidth, int color)
    Draws design-scaled text. offsetY is in raw screen pixels from the row's vertical center. When maxWidth > 0, the text is clipped to fit.
    METHOD
  • void drawTextProp(String text, int offsetX, int offsetYPermil, int maxWidth, int color) v1.6.1
    Variant of drawText where the vertical offset is expressed in permil of the row height (1/1000). Essential for layouts that need to stay correct at any window size. Example: offsetYPermil = -150 places text 15% of the row height above center; +150 places it 15% below.
    METHOD
  • void drawRect(int rx, int ry, int rw, int rh, int color)
    Draws a filled rectangle (badges, inline buttons).
    METHOD
  • void drawCenteredText(String text, int rx, int ry, int rw, int rh, int color)
    Draws text centered inside a rectangle.
    METHOD

Measurement

  • int textWidth(String text)
    Text width in screen pixels (design-scaled).
    METHOD
  • int textHeight()
    Single text line height in screen pixels (design-scaled).
    METHOD

ScrollPanel

ScrollPanel
fr.eri.eriapi.gui.components
Layout

A ScrollPanel is a container that lets you place any EriAPI components inside it and makes the content scrollable. Unlike ScrollList (which requires custom ListItem classes), ScrollPanel works with anything: labels, buttons, shapes, other layouts, etc. Think of it like a div with overflow: scroll in web design.

Preview
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.

Basic example

ScrollPanel — basic usage
// Create a panel that is 600x400 on screen but holds up to 1200px of content
ScrollPanel panel = new ScrollPanel(300, 200, 600, 400);

// Add any components INSIDE the panel
// The y coordinates are relative to the panel's content area, not the screen
panel.addChild(new Label(0, 0, 580, 30).text("Section 1").color(Colors.CYAN));
panel.addChild(new Label(0, 40, 580, 60).text("Long description text...").color(Colors.LIGHT_GRAY));
panel.addChild(new Button(0, 110, 200, 36).text("Action 1").colorScheme(Button.Style.CYAN));
panel.addChild(new Label(0, 170, 580, 30).text("Section 2").color(Colors.CYAN));
// ... add as many as you want, the panel will scroll

addComponent(panel);
Scrolling with the mouse wheel

The player can scroll the panel content using the mouse wheel. A scrollbar is automatically rendered on the right side. The player can also click and drag the scrollbar handle. All of this is handled automatically.

Methods

  • addChild(Component component)
    Adds a component inside the scrollable content area. Position coordinates are relative to the panel's content origin (0, 0 = top-left of content).
    FLUENT

Texture support

The panel background uses the inherited backgroundImage from Component. The scrollbar thumb can also receive its own texture.

  • thumbImage(ResourceLocation texture)
    Texture for the scrollbar thumb.
    FLUENT
  • thumbScaleMode(ScaleMode mode)
    How the thumb texture is scaled.
    FLUENT
  • thumbImageTint(int argb)
    ARGB tint applied on top of the thumb texture.
    FLUENT

TabView

TabView
fr.eri.eriapi.gui.components
Navigation

A TabView is like the tabs in your browser — you click a tab at the top and the content below changes. It lets you pack several distinct "pages" into one compact area of your GUI without the player having to open a second screen. Each tab has a title shown in the header bar, and its own Panel (a simple container) that becomes visible when the tab is selected.

Preview
General
Display
Audio
Content of the "General" tab — other tabs are hidden.
i
Three classes work together

Tab is a tiny data object that holds a title, a reference to its Panel, and whether it is currently active. Panel is a lightweight container you fill with components. TabView is the visible widget that manages them all and handles clicks. You mostly only interact with TabView directly.

Basic example

TabView — basic usage
// 1. Build the content for each tab using Panel
Panel inventory = new Panel()
    .add(new Label("My items").originalPos(110, 90).originalSize(200, 14));

Panel stats = new Panel()
    .add(new ProgressBar().originalPos(110, 90).originalSize(200, 14).progress(0.7f));

// 2. Create the TabView, give it a position and size
TabView tabs = new TabView()
    .originalPos(100, 50)
    .originalSize(300, 200)
    .addTab("Inventory", inventory)   // first tab
    .addTab("Stats", stats)           // second tab
    .selected(0)                      // start on the first tab (index 0)
    .onTabChange(index -> System.out.println("Tab " + index));

// 3. Register it like any other component
addComponent(tabs);
!
Panel vs ScrollPanel

Panel is a plain container with no scrolling. If you need scrollable content inside a tab, add a ScrollPanel as a child of your Panel instead of adding components directly.

Tab — data class

Tab
fr.eri.eriapi.gui.components
Data

A simple record that glues a title string, a Panel, and an active flag together. You will rarely create Tab objects directly — TabView.addTab() creates them for you.

  • Tab(String title, Panel content)
    Creates a Tab. title is what appears on the clickable header button. content is the Panel displayed when this tab is selected.
  • isActive()
    Returns true if this tab is the one currently shown.
    GETTER

Panel — content container

Panel
fr.eri.eriapi.gui.components
Container

A Panel is a ContainerComponent convenience subclass. It has no visual decoration of its own — it is just a transparent box you fill with components. The TabView will show or hide it depending on which tab is selected.

  • add(Component component)
    Adds a child component into this Panel. Coordinates on the child are relative to the Panel's own origin.
    FLUENT

TabView methods

  • addTab(String title, ContainerComponent content)
    Registers a new tab. The title string appears on the clickable header button. content is the Panel (or any ContainerComponent) that will be shown when this tab is selected. Tabs are displayed in the order they are added.
    FLUENT
  • selected(int index)
    Selects a tab by its zero-based index. Calling selected(0) shows the first tab you added, selected(1) the second, and so on.
    FLUENT
  • selectByTitle(String title)
    Selects the tab whose title matches the given string exactly. Useful when you want to jump to a specific tab by name without tracking its index.
    FLUENT
  • onTabChange(Consumer<Integer> callback)
    Registers a callback that fires every time the player switches tabs. The integer passed to the callback is the newly selected tab's index. Use a lambda: .onTabChange(i -> doSomething(i)).
    FLUENT
  • getSelectedIndex()
    Returns the zero-based index of the currently active tab.
    GETTER
  • getSelectedTitle()
    Returns the title string of the currently active tab.
    GETTER
  • tabHeight(int h)
    Sets the height of the tab header bar in design pixels. Increase this if you want larger clickable header buttons.
    FLUENT
  • tabBgColor(int argbColor)
    Background color of inactive tab header buttons.
    FLUENT
  • activeTabBgColor(int argbColor)
    Background color of the currently selected tab header button.
    FLUENT
  • tabTextColor(int argbColor)
    Text color of inactive tab labels.
    FLUENT
  • activeTabTextColor(int argbColor)
    Text color of the active tab label.
    FLUENT
  • highlightColor(int argbColor)
    Color of the thin indicator bar drawn below the active tab button. This accent line helps players see at a glance which tab is selected.
    FLUENT
  • contentBgColor(int argbColor)
    Background color of the content area (the rectangle below the tab headers where the Panel is rendered).
    FLUENT
  • contentBorderColor(int argbColor)
    Border color drawn around the content area. Set to 0x00000000 (fully transparent) to hide the border entirely.
    FLUENT

Texture support

Inactive tab headers, the active tab header, and the content area can each display a texture independently of their background colours.

  • tabImage(ResourceLocation texture)
    Texture for inactive tab header buttons.
    FLUENT
  • activeTabImage(ResourceLocation texture)
    Texture for the currently selected tab header button.
    FLUENT
  • contentImage(ResourceLocation texture)
    Texture for the content area (the rectangle below the tab headers).
    FLUENT
  • tabImageScaleMode(ScaleMode mode)
    Scale mode for both tab (active and inactive) textures.
    FLUENT
  • contentImageScaleMode(ScaleMode mode)
    Scale mode for the content area texture.
    FLUENT
  • tabImageTint(int argb)
    ARGB tint applied on tab textures.
    FLUENT
  • contentImageTint(int argb)
    ARGB tint applied on the content area texture.
    FLUENT
  • contentSliceBorder(int pixels)
    Corner size in pixels for NINE_SLICE mode on the content texture.
    FLUENT

Chart — abstract base class

Chart
fr.eri.eriapi.gui.components
Abstract

Chart is the common foundation that every chart type in EriAPI is built on. You will never create a Chart directly — instead you create a LineChart, BarChart, or PieChart. But all of them share the methods listed here, which control things like the title, axis labels, grid lines, and background color.

Think of it like this: Chart is the "blank canvas and frame" that every chart type inherits. The specific chart type then decides how to draw the data inside that frame.

Preview
LineChart
Players
Mobs
BarChart
PieChart
i
Design pixels, as always

Position and size your chart with the usual .originalPos(x, y) and .originalSize(w, h) methods inherited from Component. EriAPI's scaling system converts them to screen pixels automatically.

Default values

Every chart comes pre-configured with sensible defaults so it looks good out of the box with no extra setup:

  • Background — deep navy 0xFF1A1A2A
  • Grid lines — 5 horizontal guide lines, color 0xFF303045
  • Axes — drawn in 0xFF505070
  • Text — white
  • Border0xFF404060
  • Chart padding — 25 design pixels on each side
  • Title height — 12 design pixels
  • Show grid — true

Shared methods (available on every chart)

  • title(String text)
    Sets the chart title displayed at the very top of the component. Leave it empty if you do not need a title.
    FLUENT
  • xLabel(String text)
    Label drawn below the horizontal axis. Use it to describe what the X axis represents (e.g. "Time (seconds)" or "Player name").
    FLUENT
  • yLabel(String text)
    Label drawn along the vertical axis. Use it to describe what the Y axis represents (e.g. "Score" or "Kills").
    FLUENT
  • chartPadding(int pixels)
    Internal padding between the chart border and the actual data area, in design pixels. Default is 25. Increase it if axis labels are being clipped.
    FLUENT
  • titleHeight(int pixels)
    Height reserved at the top of the chart for the title text, in design pixels. Default is 12.
    FLUENT
  • gridLines(int count)
    Number of horizontal grid lines drawn inside the chart area. Default is 5. Set to 0 to disable them entirely.
    FLUENT
  • showGrid(boolean show)
    Toggles grid line rendering. showGrid(false) hides all grid lines without changing the gridLines count.
    FLUENT
  • backgroundColor(int argbColor)
    Fill color of the chart's background rectangle. Use the 0xAARRGGBB format. Default is 0xFF1A1A2A.
    FLUENT
  • gridColor(int argbColor)
    Color of the horizontal grid lines. Default is 0xFF303045.
    FLUENT
  • axisColor(int argbColor)
    Color of the X and Y axes. Default is 0xFF505070.
    FLUENT
  • textColor(int argbColor)
    Color used for all text drawn on the chart (title, axis labels, tick values). Default is white.
    FLUENT
  • borderColor(int argbColor)
    Color of the thin border drawn around the chart. Default is 0xFF404060. Set alpha to 0 to hide it.
    FLUENT

LineChart

LineChart
fr.eri.eriapi.gui.components
Chart

A LineChart draws one or more lines across a coordinate plane, where the horizontal axis is X and the vertical axis is Y. It is perfect for showing how a value changes over time — for example, a player's ping history, a server's TPS over the last minute, or the progress of a stat as a player levels up.

You can add multiple datasets — each dataset is a named series of (x, y) data points drawn as its own colored line. A legend can be shown so players know which line belongs to which dataset.

i
What is a DataPoint?

LineChart.DataPoint is a tiny helper class that holds exactly two numbers: an x value and a y value. You create one like this: new LineChart.DataPoint(3.0f, 47.5f). The chart figures out the scale automatically based on all the points you provide.

Basic example

LineChart — basic usage
import java.util.Arrays;
import java.util.List;

// 1. Build a list of data points (x, y pairs)
List<LineChart.DataPoint> pingData = Arrays.asList(
    new LineChart.DataPoint(0, 42),
    new LineChart.DataPoint(1, 38),
    new LineChart.DataPoint(2, 55),
    new LineChart.DataPoint(3, 60),
    new LineChart.DataPoint(4, 47)
);

// 2. Create the chart
LineChart ping = new LineChart()
    .originalPos(50, 50)
    .originalSize(300, 180)
    .title("Ping over time")
    .xLabel("Seconds")
    .yLabel("ms")
    .addDataset("My ping", pingData)       // add the dataset with a name
    .datasetColor("My ping", 0xFF00CFFF)   // give it a color
    .showLegend(true)                       // show the legend
    .showDots(true)                         // draw a dot at each data point
    .showGrid(true)
    .gridLines(4);

// 3. Register it
addComponent(ping);

Multiple datasets example

LineChart — multiple datasets
List<LineChart.DataPoint> redTeam = Arrays.asList(
    new LineChart.DataPoint(0, 10),
    new LineChart.DataPoint(1, 15),
    new LineChart.DataPoint(2, 12)
);
List<LineChart.DataPoint> blueTeam = Arrays.asList(
    new LineChart.DataPoint(0, 8),
    new LineChart.DataPoint(1, 20),
    new LineChart.DataPoint(2, 18)
);

LineChart scores = new LineChart()
    .originalPos(50, 50)
    .originalSize(300, 180)
    .title("Team Scores")
    .addDataset("Red Team", redTeam)
    .datasetColor("Red Team", 0xFFFF4455)
    .addDataset("Blue Team", blueTeam)
    .datasetColor("Blue Team", 0xFF4488FF)
    .showLegend(true)
    .showDots(false);   // lines only, no dots

addComponent(scores);

LineChart methods

These are in addition to all the Chart base methods.

  • addDataset(String name, List<DataPoint> data)
    Adds a new line to the chart. name is used as the legend label and as the key for datasetColor() and removeDataset(). data is the list of (x, y) points.
    FLUENT
  • datasetColor(String name, int argbColor)
    Assigns a color to the dataset identified by name. If you do not call this, EriAPI picks a default color automatically.
    FLUENT
  • removeDataset(String name)
    Removes the dataset with the given name from the chart. Useful for dynamically updating which data series are displayed.
    FLUENT
  • clearDatasets()
    Removes all datasets at once. Call this before loading a completely fresh set of data.
    FLUENT
  • showLegend(boolean show)
    Shows or hides the legend box that maps each colored line to its dataset name. Turn it on when you have more than one dataset.
    FLUENT
  • showDots(boolean show)
    When true, a small filled circle is drawn at every data point on the line, making individual values easier to spot. Default is true.
    FLUENT
  • lineWidth(int pixels)
    Thickness of the drawn lines in screen pixels. Default is 1. Use 2 or 3 for bolder, more visible lines.
    FLUENT

DataPoint — inner helper class

LineChart.DataPoint
fr.eri.eriapi.gui.components
Data

A simple object that pairs an X value with a Y value. Both are float numbers, so you can use decimals (e.g. 3.5f). You will always create these inline when building your dataset list.

  • DataPoint(float x, float y)
    Creates a point at coordinate (x, y). The chart automatically determines the min/max range from all points in all datasets.

BarChart

BarChart
fr.eri.eriapi.gui.components
Chart

A BarChart displays data as vertical bars standing side by side. Each bar has a text label below it (shown on the X axis) and a numeric value that controls its height. Bar charts are great for comparing things at a glance — top players on a leaderboard, item counts per category, kills per round, and so on.

You can give every bar its own color, or set one default color for all bars. When the player hovers over a bar, it can highlight with a different color to make the interface feel responsive.

Basic example

BarChart — basic usage
// 1. Create the chart and add bars one by one
BarChart leaderboard = new BarChart()
    .originalPos(50, 50)
    .originalSize(300, 180)
    .title("Top Players")
    .yLabel("Kills")
    .addBar("Alice", 42)
    .addBar("Bob",   37)
    .addBar("Carol", 55)
    .addBar("Dave",  28)
    .barColor(0xFF4488FF)          // default color for all bars
    .hoverBarColor(0xFF66AAFF)     // color when the player hovers a bar
    .showValues(true)              // draw the numeric value above each bar
    .showLabels(true)              // draw the text label below each bar
    .showGrid(true);

// 2. Register it
addComponent(leaderboard);

Per-bar colors example

BarChart — individual bar colors
BarChart stats = new BarChart()
    .originalPos(50, 50)
    .originalSize(300, 180)
    .title("Resource Usage")
    // addBar(label, value, color) — third argument overrides the default color
    .addBar("CPU",    72f, 0xFFFF6644)
    .addBar("RAM",    55f, 0xFF44AAFF)
    .addBar("Disk",   30f, 0xFF44DD88)
    .showValues(true)
    .valueFormat("%.0f%%");   // format: "72%", "55%", etc.

addComponent(stats);

BarChart methods

These are in addition to all the Chart base methods.

  • addBar(String label, float value)
    Adds a bar with the given label and height value. The bar uses the default barColor. Bars are rendered in the order they are added.
    FLUENT
  • addBar(String label, float value, int argbColor)
    Adds a bar with its own individual color, overriding the chart's default barColor for this bar only.
    FLUENT
  • updateBar(String label, float value)
    Updates the value of an existing bar identified by its label. Use this to refresh data without rebuilding the entire chart.
    FLUENT
  • clearBars()
    Removes all bars. Call this before reloading a completely fresh set of data.
    FLUENT
  • barColor(int argbColor)
    Default fill color applied to every bar that does not have its own individual color. Default is a soft blue.
    FLUENT
  • hoverBarColor(int argbColor)
    Color applied to whichever bar the player's mouse is currently hovering over. Gives the chart a responsive feel.
    FLUENT
  • barSpacing(int pixels)
    Gap between adjacent bars in design pixels. Increase this if bar labels overlap each other.
    FLUENT
  • showValues(boolean show)
    When true, the numeric value of each bar is drawn just above its top edge. Formatted with valueFormat.
    FLUENT
  • showLabels(boolean show)
    When true, the text label of each bar is drawn below the bar along the X axis.
    FLUENT
  • valueFormat(String format)
    A String.format pattern used to format the numeric value displayed above each bar when showValues(true) is set. Examples: "%.0f" → whole numbers, "%.1f" → one decimal, "%.0f%%" → percentage sign.
    FLUENT

PieChart

PieChart
fr.eri.eriapi.gui.components
Chart

A PieChart divides a circle into colored slices, where each slice's size is proportional to its value relative to the total. It is ideal for showing how a whole is split into parts — for example, the percentage of players in each team, the breakdown of items in a chest, or how time is distributed across activities.

Each slice has a label and a value. You can optionally show the percentage each slice represents, and display a legend that maps colors to labels.

!
Values are relative, not percentages

You do not need to calculate percentages yourself. You simply provide raw values (e.g. 42, 18, 30) and the chart automatically works out what fraction of the circle each slice occupies. The total can be anything.

Basic example

PieChart — basic usage
// 1. Create the chart and add slices
PieChart distribution = new PieChart()
    .originalPos(50, 50)
    .originalSize(200, 200)   // square looks best for pie charts
    .title("Team Distribution")
    .addSlice("Red Team",   42, 0xFFFF4455)
    .addSlice("Blue Team",  38, 0xFF4488FF)
    .addSlice("Green Team", 20, 0xFF44CC66)
    .showLegend(true)          // show color-to-label legend
    .showPercentage(true)      // draw "42%" inside or near each slice
    .segments(64);             // smoothness of slice edges (higher = smoother circle)

// 2. Register it
addComponent(distribution);

Auto-color example

PieChart — letting EriAPI pick colors
// If you don't provide a color, EriAPI picks one automatically
PieChart inventory = new PieChart()
    .originalPos(50, 50)
    .originalSize(200, 200)
    .title("Inventory Contents")
    .addSlice("Swords", 5)    // no third argument → auto color
    .addSlice("Armor",  12)
    .addSlice("Food",   30)
    .addSlice("Misc",   8)
    .showLegend(true)
    .showPercentage(false);

addComponent(inventory);

PieChart methods

These are in addition to all the Chart base methods.

  • addSlice(String label, float value, int argbColor)
    Adds a slice with an explicit color. The slice occupies a portion of the circle proportional to value relative to the sum of all slice values.
    FLUENT
  • addSlice(String label, float value)
    Adds a slice and lets EriAPI automatically assign a color from a built-in palette. Convenient when you don't need precise color control.
    FLUENT
  • clearSlices()
    Removes all slices. Use this before providing a completely fresh dataset.
    FLUENT
  • showLegend(boolean show)
    Shows or hides a legend alongside the pie that maps each color to its slice label. Recommended when showPercentage is off or when slices are very small.
    FLUENT
  • showPercentage(boolean show)
    When true, the calculated percentage (e.g. "42%") is drawn on or near each slice. Slices that are too small to fit the text are skipped automatically.
    FLUENT
  • segments(int count)
    Number of OpenGL triangle segments used to draw each slice. Higher values produce a smoother circular edge. Default is 64. Values below 16 will look noticeably faceted.
    FLUENT

ProgressBar

ProgressBar
fr.eri.eriapi.gui.components
Control

A ProgressBar shows how much of something is complete — experience points, a loading bar, health remaining, a quest objective. It takes a value between 0.0 (empty) and 1.0 (full) and draws a colored fill accordingly. It can optionally animate the fill and show the percentage as text.

Preview
75%
45%
90%

Basic example

ProgressBar — basic usage
// A health bar: 70% full
addComponent(new ProgressBar(400, 300, 600, 24)
    .progress(0.7f)              // 0.0 = empty, 1.0 = full. 0.7 = 70%
    .fillColor(0xFF22CC44)       // Green fill
    .backgroundColor(0xFF333333) // Dark gray empty part
    .cornerRadius(6)             // Rounded ends
    .showPercentage(true)        // Show "70%" text over the bar
    .animated(true)              // Smoothly animate fill changes
);

All methods

  • progress(float value)
    Sets the fill level. Must be between 0.0 and 1.0. Call this whenever you want to update the bar (e.g. when player gains XP).
    FLUENT
  • fillColor(int argbColor)
    The color of the filled portion of the bar.
    FLUENT
  • backgroundColor(int argbColor)
    The color of the empty (background) portion of the bar.
    FLUENT
  • cornerRadius(int radius)
    Rounds the ends of the progress bar.
    FLUENT
  • showPercentage(boolean show)
    If true, draws the percentage (e.g. "70%") as text centered over the bar.
    FLUENT
  • animated(boolean animate)
    If true, the bar fill transitions smoothly when progress() is called with a new value, instead of jumping instantly.
    FLUENT

Texture support

In addition to flat colours, you can skin the bar with textures. The fill texture (fillImage) is clipped via scissor so it follows the progress level exactly. The inherited backgroundImage from Component covers the empty (background) portion of the bar.

ProgressBar — texture fill
ProgressBar bar = new ProgressBar()
    .originalPos(100, 50)
    .originalSize(200, 16)
    .progress(0.7f)
    .fillImage(new ResourceLocation("mymod", "textures/gui/fill.png"))
    .fillScaleMode(ScaleMode.NINE_SLICE)
    .fillSliceBorder(4);

// Background texture (inherited from Component)
bar.backgroundImage(new ResourceLocation("mymod", "textures/gui/bar_bg.png"));
  • fillImage(ResourceLocation texture)
    Texture for the filled portion of the bar. Clipped by scissor to match the current progress level.
    FLUENT
  • fillScaleMode(ScaleMode mode)
    How the fill texture is stretched: STRETCH, NINE_SLICE, TILE, or FIT.
    FLUENT
  • fillImageTint(int argb)
    ARGB tint applied on top of the fill texture. Defaults to 0xFFFFFFFF (no tint).
    FLUENT
  • fillSliceBorder(int pixels)
    Corner size in pixels for NINE_SLICE mode.
    FLUENT

Slider

Slider
fr.eri.eriapi.gui.components
Control

A Slider lets the player drag a handle along a track to pick a value within a range. Think of a volume slider, a render distance slider, or a brightness control. The player clicks and drags the handle. EriAPI handles all the math and mouse tracking.

Preview
60
0.25

Basic example

Slider — basic usage
Slider volumeSlider = new Slider(400, 400, 500, 32)
    .value(0.5)              // Starting value (range: min to max)
    .range(0.0, 1.0)         // Min and max values
    .step(0.05)              // Snap to increments of 0.05 (5%)
    .showValue(true)         // Display the current value as text
    .onValueChange(v -> {    // Called every time the slider moves
        System.out.println("Volume: " + (int)(v * 100) + "%");
    });

addComponent(volumeSlider);

// Read the current value later:
// double vol = volumeSlider.getValue();

All methods

  • value(double initialValue)
    The starting value of the slider when the screen opens.
    FLUENT
  • range(double min, double max)
    The minimum and maximum values. The slider's handle moves between these two extremes.
    FLUENT
  • step(double step)
    The snap increment. For example, step(1.0) makes the slider jump between whole numbers. Use 0 for continuous (no snapping).
    FLUENT
  • showValue(boolean show)
    If true, the current value is displayed as text next to the slider handle.
    FLUENT
  • onValueChange(Consumer<Double> callback)
    Called every time the slider value changes. The new value is passed as a parameter.
    EVENT
  • getValue()
    Returns the current value of the slider as a double.
    GETTER

Texture support

The track and the thumb (handle) can each receive an independent texture.

  • trackImage(ResourceLocation texture)
    Texture for the track (the rail the handle slides along).
    FLUENT
  • trackScaleMode(ScaleMode mode)
    How the track texture is scaled.
    FLUENT
  • trackImageTint(int argb)
    ARGB tint applied on top of the track texture.
    FLUENT
  • trackSliceBorder(int pixels)
    Corner size for NINE_SLICE mode on the track texture.
    FLUENT
  • thumbImage(ResourceLocation texture)
    Texture for the slider handle (the knob the player drags).
    FLUENT
  • thumbScaleMode(ScaleMode mode)
    How the thumb texture is scaled.
    FLUENT
  • thumbImageTint(int argb)
    ARGB tint applied on top of the thumb texture.
    FLUENT

Checkbox

Checkbox
fr.eri.eriapi.gui.components
Control

A Checkbox is a small square the player can tick on or off. It's for toggling options — like "Enable notifications", "Show online players only", or "Agree to terms". It has a label displayed next to it and fires a callback when toggled.

Preview
Enable notifications
Fullscreen mode
Show HUD

Basic example

Checkbox — basic usage
Checkbox notifCheck = new Checkbox(400, 350, 300, 30)
    .label("Enable notifications")  // Text shown next to the checkbox
    .checked(true)                  // Start as checked (ticked)
    .onToggle(isChecked -> {        // Called when player clicks it
        System.out.println("Notifications enabled: " + isChecked);
    });

addComponent(notifCheck);

// Read the current state later:
// boolean enabled = notifCheck.isChecked();

All methods

  • label(String text)
    The text displayed to the right of the checkbox box.
    FLUENT
  • checked(boolean state)
    The initial checked state. true = ticked, false = unticked.
    FLUENT
  • onToggle(Consumer<Boolean> callback)
    Called when the player clicks the checkbox. The new state (true = checked) is passed as a parameter.
    EVENT
  • isChecked()
    Returns the current checked state as a boolean.
    GETTER

Texture support

The box and the checkmark can each have their own texture. checkImage uses ScaleMode.FIT by default to preserve the icon's aspect ratio.

  • boxImage(ResourceLocation texture)
    Texture for the checkbox square (the box background).
    FLUENT
  • checkImage(ResourceLocation texture)
    Texture for the checkmark shown when the box is ticked. Default scale mode: ScaleMode.FIT.
    FLUENT
  • boxScaleMode(ScaleMode mode)
    How the box texture is scaled.
    FLUENT
  • boxImageTint(int argb)
    ARGB tint applied on top of the box texture.
    FLUENT

RadioButton

RadioButton
fr.eri.eriapi.gui.components
Control

A RadioButton is like a checkbox but part of a group where only one can be selected at a time. Think of a "Difficulty: Easy / Medium / Hard" selection — you can only pick one. On its own, a RadioButton is just a visual element; you put it inside a RadioGroup to enforce the "only one selected" behavior.

Basic example (single, standalone)

RadioButton — standalone
// A single radio button (see RadioGroup for the proper group usage)
RadioButton easyOption = new RadioButton(400, 300, 200, 30)
    .label("Easy")          // Text shown next to the radio button
    .selected(true)         // This one is selected by default
    .onSelect(() -> {       // Called when this option is selected
        System.out.println("Difficulty: Easy");
    });

addComponent(easyOption);

All methods

  • label(String text)
    The text label shown next to the radio circle.
    FLUENT
  • selected(boolean state)
    Whether this button is selected (filled circle) or not (empty circle).
    FLUENT
  • onSelect(Runnable callback)
    Called when the player clicks this radio button to select it.
    EVENT
  • isSelected()
    Returns true if this radio button is currently selected.
    GETTER

RadioGroup

RadioGroup
fr.eri.eriapi.gui.components
Control

A RadioGroup holds multiple RadioButtons and ensures that when you click one, the others are automatically deselected. This is the correct way to create "pick one from a list" selections. Use getSelected() to find out which option the player chose.

Preview
Easy
Normal
Hard

Basic example

RadioGroup — complete example
// Create the group — it manages the selection state
RadioGroup difficultyGroup = new RadioGroup(400, 300, 300, 130)
    .onSelect(selectedId -> {       // Called when any button in the group is clicked
        System.out.println("Selected option ID: " + selectedId);
    });

// Add radio buttons to the group
// The first argument to add() is a unique ID string for that option
difficultyGroup.add("easy",   new RadioButton(0, 0, 280, 36).label("Easy"));
difficultyGroup.add("medium", new RadioButton(0, 0, 280, 36).label("Medium"));
difficultyGroup.add("hard",   new RadioButton(0, 0, 280, 36).label("Hard"));

// Select one as the default
difficultyGroup.select("easy");

// Add the group to the screen — this also adds all its radio buttons
addComponent(difficultyGroup);

// Read the selection on a button click:
// String chosen = difficultyGroup.getSelected(); // returns "easy", "medium", or "hard"

All methods

  • add(String id, RadioButton button)
    Adds a radio button to the group with a unique string ID. The ID is what you get back from getSelected().
    FLUENT
  • select(String id)
    Programmatically selects the option with the given ID (and deselects all others).
    FLUENT
  • onSelect(Consumer<String> callback)
    Called whenever the player changes the selection. The selected option's ID is passed as a parameter.
    EVENT
  • getSelected()
    Returns the ID string of the currently selected option, or null if nothing is selected.
    GETTER

Easing

The Easing enum defines interpolation functions for animations. Each function transforms a linear progression (0→1) into a more natural curve.

ENUM
Easing
fr.eri.eriapi.gui.anim.Easing
Java — Available easing functions
Easing.LINEAR        // t → linear progression
Easing.EASE_IN       // t² → slow start
Easing.EASE_OUT      // t(2-t) → slow end
Easing.EASE_IN_OUT   // smoothstep → slow at both ends
Easing.EASE_IN_CUBIC // t³ → very slow start
Easing.EASE_OUT_CUBIC // (t-1)³+1 → very slow end
Easing.BOUNCE        // bouncing decay
Easing.ELASTIC       // dampened oscillation

float result = Easing.EASE_OUT.apply(0.5f); // → 0.75

Animation

The Animation class represents an active animation. It interpolates a value between from and to over a duration in ticks (20 ticks = 1 second).

CLASS
Animation
fr.eri.eriapi.gui.anim.Animation
Java — Creating an animation
import fr.eri.eriapi.gui.anim.*;

Animation anim = Animation.create(0, 1, 20) // 0 to 1 in 1 second
    .easing(Easing.EASE_OUT)
    .delay(5) // wait 5 ticks before starting
    .onUpdate(value -> myComponent.setOpacity(value))
    .onComplete(() -> System.out.println("Done!"));

AnimationManager.getInstance().play(anim);

anim.pause();
anim.resume();
anim.stop();

AnimationManager

The AnimationManager is a singleton that manages all active animations. It is automatically integrated into EriGuiScreen's render loop — just call play().

CLASS
AnimationManager
fr.eri.eriapi.gui.anim.AnimationManager
Java — Using AnimationManager
AnimationManager manager = AnimationManager.getInstance();
manager.play(Animation.create(0, 100, 20).easing(Easing.BOUNCE));
int count = manager.activeCount();
manager.stopAll();

Built-in Animations

Every Component has built-in animation methods. They automatically create and play the animation — just call the method.

Java — fadeIn / fadeOut
button.fadeIn(10);  // fade in over 0.5 seconds
panel.fadeOut(15);   // fade out over 0.75 seconds
Java — slideIn / slideOut
button.slideIn(Component.Direction.LEFT, 60, 12);
panel.slideIn(Component.Direction.DOWN, 40, 14).easing(Easing.BOUNCE);
label.slideOut(Component.Direction.RIGHT, 80, 10);
Java — scaleIn / scaleOut / shake
button.scaleIn(10);  // scale from 0 to 1
panel.scaleOut(8);    // scale from 1 to 0
button.shake(10);     // horizontal oscillation
Java — Full example in EriGuiScreen
public class MyGui extends EriGuiScreen {
    @Override
    protected void buildGui() {
        GuiFramework.getInstance().setDesignResolution(this.width, this.height);

        ContainerComponent panel = new ContainerComponent()
            .originalPos(100, 100).originalSize(300, 200)
            .backgroundColor(Colors.PANEL_BG);

        Button btn = new Button("Click me!")
            .originalPos(150, 200).originalSize(120, 30)
            .colorScheme(0xFF1A8FA0);

        add(panel, btn);

        // Entry animations
        panel.fadeIn(12);
        btn.slideIn(Component.Direction.DOWN, 40, 15);
    }
}

Tooltip

Any component can display a tooltip by calling .tooltip("text"). Tooltips are rendered automatically by EriGuiScreen — no extra setup required. They appear after a configurable hover delay and reposition themselves to stay within screen edges.

Preview
Diamond Sword
+7 Attack Damage
Click to open menu
FEATURE
Component#tooltip
fr.eri.eriapi.gui.core.Component
Works on every component

.tooltip() is defined on the base Component class, so it is available on Button, Label, TextField, Slider, and every other component in the framework.

Key features

FeatureDetails
Single-line tooltip.tooltip("text")
Multi-line tooltipUse \n in Java strings or literal \\n from .lang files — both work automatically
Configurable delay.tooltipDelay(ticks) — default 15 ticks (0.75 s)
Auto-positioningRepositions automatically to avoid screen edges
Automatic renderingRendered by EriGuiScreen — zero boilerplate
Java — Basic tooltip
new Button("Buy")
    .originalPos(100, 50)
    .originalSize(120, 30)
    .onClick(() -> buyItem())
    .tooltip("Buy the selected item\nPrice: 100 coins");
Java — Tooltip from a .lang file
// In en_US.lang: tooltip.item.info=Line 1\nLine 2\nLine 3
// The literal \\n from .lang files is automatically normalized to real newlines
new Button("Info")
    .originalPos(100, 50)
    .originalSize(120, 30)
    .tooltip(I18n.format("tooltip.item.info")); // Renders as 3 lines
Java — Custom delay
// Custom delay: 40 ticks = 2 seconds
new Label("Info")
    .originalPos(50, 50)
    .originalSize(80, 10)
    .tooltip("Additional details")
    .tooltipDelay(40);

Notification

Notifications are transient messages that slide in from the edge of the screen and automatically disappear after a configurable duration. They come in four types, each with a distinct color and icon.

Preview
Success
Configuration saved!
Warning
Unstable connection
Error
Unable to connect
CLASS
Notification
fr.eri.eriapi.gui.components.Notification

Notification types

TypeColorUse case
Notification.Type.SUCCESSGreenAction completed successfully
Notification.Type.ERRORRedSomething went wrong
Notification.Type.INFOBlueGeneral information
Notification.Type.WARNINGOrange/YellowSomething needs attention

Behaviour

PropertyValue
Default duration60 ticks (3 seconds)
Maximum visible at once5 notifications
Entry / exit animationSlide in / slide out
RenderingAutomatic via EriGuiScreen
Java — Static convenience methods
NotificationManager.success("Purchase complete!");
NotificationManager.error("Insufficient balance.");
NotificationManager.info("Welcome to the server.");
NotificationManager.warning("Low stock!");
Java — Custom duration
// 100 ticks = 5 seconds
NotificationManager.notify(Notification.Type.INFO, "Custom message", 100);

Texture support

The notification background can be replaced by a texture. By default NINE_SLICE with a 4 px border is used so the texture scales gracefully with different message lengths.

Java — Notification with background texture
notification
    .bgImage(new ResourceLocation("mymod", "textures/gui/notif_bg.png"))
    .bgScaleMode(ScaleMode.NINE_SLICE)
    .bgSliceBorder(4);
  • bgImage(ResourceLocation texture)
    Background texture for the notification. Replaces the flat background colour.
    FLUENT
  • bgScaleMode(ScaleMode mode)
    How the background texture is scaled (default: NINE_SLICE).
    FLUENT
  • bgSliceBorder(int pixels)
    Corner size for NINE_SLICE mode (default: 4).
    FLUENT

GradientRectangle

A rectangle component filled with a two-color gradient — either vertical (top to bottom) or horizontal (left to right). The direction and both colors are set via fluent methods.

Package

fr.eri.eriapi.gui.components.GradientRectangle

Constructor

  • GradientRectangle()
    Creates an empty gradient rectangle. Set position and size with originalPos(x, y) and originalSize(w, h) (inherited from Component), then configure the gradient with .vertical() or .horizontal().
    Fluent

API

  • vertical(int topColor, int bottomColor)
    Sets the gradient direction to Direction.VERTICAL with the given top and bottom ARGB colors. Returns this for chaining.
    Fluent
  • horizontal(int leftColor, int rightColor)
    Sets the gradient direction to Direction.HORIZONTAL with the given left and right ARGB colors. Returns this for chaining.
    Fluent
  • cornerRadius(int px)
    Rounds all four corners by px design pixels.
    Fluent

Direction enum

ConstantDescription
GradientRectangle.Direction.VERTICALGradient flows from top color to bottom color
GradientRectangle.Direction.HORIZONTALGradient flows from left color to right color
Java — usage examples
// Dark vertical gradient (header fade)
GradientRectangle header = new GradientRectangle()
    .originalPos(0, 0)
    .originalSize(1920, 120)
    .vertical(0xFF1A1A3E, 0x001A1A3E)  // opaque top, transparent bottom
    .cornerRadius(0);
root.add(header);

// Horizontal color bar
GradientRectangle bar = new GradientRectangle()
    .originalPos(200, 500)
    .originalSize(600, 8)
    .horizontal(0xFF00E5FF, 0xFF9B59FF)
    .cornerRadius(4);
root.add(bar);

Aurora

An animated aurora borealis background effect. You add up to 10 color bands; each band is a sinusoidal ribbon that drifts slowly across the component. Ideal as a full-screen background layer.

Package

fr.eri.eriapi.gui.components.Aurora — maximum 10 bands per instance.

Constructor

  • Aurora()
    Creates an aurora effect with no bands. Configure position and size with originalPos(x, y) and originalSize(w, h), then add bands with addBand().
    Fluent

API

  • addBand(int color, float frequency, float amplitude, int height, int yOffset)
    Adds an aurora band. color: ARGB color (semi-transparent values recommended); frequency: wave frequency — higher = more waves across the width (e.g. 0.02); amplitude: wave height oscillation in design pixels (e.g. 40.0f); height: band thickness in design pixels; yOffset: vertical offset from the top of the component. Maximum 10 bands per instance.
    Fluent
  • speed(float speed)
    Animation speed multiplier. Default is 1.0. Higher values make bands drift faster.
    Fluent
  • segments(int count)
    Number of horizontal segments per wave. Higher values produce smoother curves at higher rendering cost.
    Fluent
Java — full-screen aurora background
Aurora aurora = new Aurora()
    .originalPos(0, 0)
    .originalSize(1920, 1080)
    .addBand(0x440088FF, 0.015f, 60f, 220, 200)   // blue band
    .addBand(0x3300FF88, 0.02f,  45f, 180, 380)   // green band
    .addBand(0x33AA44FF, 0.012f, 80f, 200, 550)   // purple band
    .speed(0.6f)
    .segments(120);
root.add(aurora);

Starfield

An animated field of twinkling background stars with optional shooting stars. Stars are randomly distributed across the component area. Designed as a full-screen background layer.

Package

fr.eri.eriapi.gui.components.Starfield — maximum 3 simultaneous shooting stars.

Constructor

  • Starfield()
    Creates a starfield with default settings. Set position and size with originalPos(x, y) and originalSize(w, h).
    Fluent

API

  • starCount(int count)
    Total number of background stars to render.
    Fluent
  • starColor(int argbColor)
    Base ARGB color for background stars. Individual star brightness varies around this base value.
    Fluent
  • shootingStarChance(float chance)
    Probability per tick that a new shooting star spawns (0.0 to 1.0). A maximum of 3 shooting stars can be active simultaneously. Set to 0.0 to disable shooting stars entirely.
    Fluent
Java — starfield background
Starfield stars = new Starfield()
    .originalPos(0, 0)
    .originalSize(1920, 1080)
    .starCount(200)
    .starColor(0xCCFFFFFF)
    .shootingStarChance(0.003f);  // roughly one shooting star every ~6 seconds
root.add(stars);

ParticleSystem

A 2D particle emitter. Particles are spawned at the component origin (or along its edges) and drift according to speed, spread, and lifecycle parameters. Suitable for magic sparkles, fire embers, confetti, and similar effects.

Package

fr.eri.eriapi.gui.components.ParticleSystem

Constructor

  • ParticleSystem()
    Creates an empty particle system. Configure with the fluent methods below, then set position/size with originalPos(x, y) and originalSize(w, h).
    Fluent

API

  • maxParticles(int max)
    Maximum number of simultaneously active particles.
    Fluent
  • spawnRate(float perTick)
    Particles spawned per tick. Can be fractional (e.g. 0.5 = one every 2 ticks).
    Fluent
  • particleLife(int minMs, int maxMs)
    Lifetime range per particle in milliseconds. Each particle gets a random value in [minMs, maxMs].
    Fluent
  • particleSize(int startPx, int endPx)
    Particle size in design pixels at birth (startPx) and at death (endPx). Linearly interpolated.
    Fluent
  • particleColor(int argbColor)
    Base ARGB color. Alpha is respected and combined with fade-in/fade-out.
    Fluent
  • drift(float dx, float dy)
    Average velocity in design pixels per tick. Positive dy drifts downward.
    Fluent
  • spread(float radius)
    Random velocity spread (pixels/tick radius) added to the base drift direction.
    Fluent
  • fadeIn(float ratio)
    Fraction of the particle lifetime (0.0–1.0) during which it fades in from transparent.
    Fluent
  • fadeOut(float ratio)
    Fraction of the particle lifetime during which it fades out to transparent. E.g. 0.3 = starts fading at 70% of its life.
    Fluent
  • spawnOnEdges(boolean enable)
    If true, particles spawn along the component's edges instead of at the center.
    Fluent
Java — sparkle effect
ParticleSystem sparkles = new ParticleSystem()
    .originalPos(860, 480)
    .originalSize(200, 120)
    .maxParticles(80)
    .spawnRate(1.5f)
    .particleLife(600, 1400)
    .particleSize(3, 1)
    .particleColor(0xFFFFD700)
    .drift(0.0f, -0.8f)   // float upward
    .spread(1.2f)
    .fadeIn(0.15f)
    .fadeOut(0.35f)
    .spawnOnEdges(false);
root.add(sparkles);

SmokeFog

A procedural Perlin-noise fog/smoke overlay rendered in real time. The noise field scrolls continuously and can be given a wind direction. Useful for atmospheric backgrounds, mist over a landscape, or dark smoke layers.

Package

fr.eri.eriapi.gui.components.SmokeFog

Constructor

  • SmokeFog()
    Creates a smoke/fog effect with default parameters. Set position and size with originalPos(x, y) and originalSize(w, h).
    Fluent

API

  • color(int rgb)
    Base RGB color of the fog (no alpha — opacity is controlled by intensity). Example: 0x888888 for grey smoke.
    Fluent
  • intensity(float value)
    Maximum opacity of the fog (0.0 to 1.0). Higher values produce denser, more opaque fog.
    Fluent
  • scale(float value)
    Spatial scale of the noise pattern. Larger values produce bigger, smoother wisps; smaller values produce fine-grained turbulence.
    Fluent
  • speed(float value)
    How fast the noise pattern scrolls over time. Default is 1.0.
    Fluent
  • wind(float wx, float wy)
    Wind direction vector. The fog scrolls in this direction at the configured speed. E.g. wind(1.0f, 0.2f) drifts mostly to the right with a slight downward angle.
    Fluent
  • octaves(int count)
    Number of noise octaves (1–8). More octaves add fine detail at higher rendering cost. Default is 4.
    Fluent
  • persistence(float value)
    Contribution of each successive octave (0.0–1.0). Higher values produce more turbulent, cloud-like patterns.
    Fluent
  • cellSize(int pixels)
    Resolution of the noise sampling grid in design pixels. Larger cells are cheaper to render but produce blockier fog.
    Fluent
Java — atmospheric fog overlay
SmokeFog fog = new SmokeFog()
    .originalPos(0, 600)
    .originalSize(1920, 480)
    .color(0x1A1A2E)
    .intensity(0.55f)
    .scale(2.5f)
    .speed(0.4f)
    .wind(0.8f, 0.15f)
    .octaves(4)
    .persistence(0.5f)
    .cellSize(8);
root.add(fog);

NotificationManager

NotificationManager is a global singleton that manages all active notifications. Its tick() and render() methods are called automatically by EriGuiScreen — you never need to wire them up manually.

CLASS
NotificationManager
fr.eri.eriapi.gui.components.NotificationManager

API

MethodDescription
NotificationManager.success(String)Show a SUCCESS notification
NotificationManager.error(String)Show an ERROR notification
NotificationManager.info(String)Show an INFO notification
NotificationManager.warning(String)Show a WARNING notification
NotificationManager.notify(Type, String, int)Show a notification with a custom duration (ticks)
NotificationManager.clearAll()Dismiss all active notifications immediately
NotificationManager.activeCount()Returns the number of currently visible notifications
tick()Advances all notification timers — called by EriGuiScreen
render(int, int, float)Renders all visible notifications — called by EriGuiScreen
Java — Full usage example
public class MyGui extends EriGuiScreen {
    @Override
    protected void buildGui() {
        GuiFramework.getInstance().setDesignResolution(this.width, this.height);

        Button buyBtn = new Button("Buy")
            .originalPos(100, 50)
            .originalSize(120, 30)
            .tooltip("Buy the selected item\nPrice: 100 coins")
            .onClick(() -> {
                if (hasEnoughBalance()) {
                    processTransaction();
                    NotificationManager.success("Purchase complete!");
                } else {
                    NotificationManager.error("Insufficient balance.");
                }
            });

        add(buyBtn);
    }
}
No extra registration needed

EriGuiScreen already calls NotificationManager.tick() and NotificationManager.render() on every frame. Just call the static methods anywhere in your GUI logic — the notifications will appear automatically.

Network GUI

Client ↔ server communication for EriAPI GUIs — sending actions, receiving data, and opening screens from the server — is covered in the dedicated Network GUI documentation page.

Dedicated page

See network.html for the full reference: GuiNetworkHandler (all static methods), IGuiDataReceiver (onDataUpdate(String, String, String)), packet format tables, and a complete client/server shop example.

Colors

Colors
fr.eri.eriapi.gui.util
Utility

The Colors class is a collection of ready-to-use color constants and helper methods. Instead of memorizing hex codes, you can write Colors.WHITE or Colors.CYAN. All colors are in ARGB format (0xAARRGGBB).

Color palette

WHITE
0xFFFFFFFF
BLACK
0xFF000000
CYAN
0xFF00DDFF
PURPLE
0xFFAA44FF
GREEN
0xFF22CC44
RED
0xFFFF3344
ORANGE
0xFFFF9900
YELLOW
0xFFFFFF00
LIGHT_GRAY
0xFFAAAAAA
DARK_GRAY
0xFF555555

Helper methods

  • Colors.withAlpha(int color, int alpha)
    Takes an existing color and changes its transparency. Alpha: 0 = invisible, 255 = fully opaque. Example: Colors.withAlpha(Colors.RED, 128) = semi-transparent red.
    STATIC
  • Colors.fromHex(String hex)
    Creates a color from a hex string like "#FF0000" (red) or "#80FF0000" (semi-transparent red). The leading # is optional.
    STATIC
  • Colors.lerp(int colorA, int colorB, float t)
    Blends between two colors. t=0.0 returns colorA, t=1.0 returns colorB, t=0.5 returns an equal mix. Great for gradient effects or color transitions.
    STATIC
  • Colors.of(int r, int g, int b)
    Creates an ARGB color from individual red, green, blue values (0-255 each). Automatically sets alpha to 255 (fully opaque).
    STATIC
  • Colors.of(int r, int g, int b, int a)
    Creates an ARGB color with a custom alpha.
    STATIC

Usage examples

Colors — examples
// Use a predefined color constant
label.color(Colors.CYAN);

// Use a raw ARGB hex value
label.color(0xFF00DDFF);   // same as Colors.CYAN

// Semi-transparent red (AA=80 = about 50% opacity)
rectangle.fillColor(0x80FF0000);

// Create a color from RGB components (fully opaque)
int myColor = Colors.of(100, 200, 50);  // a lime green

// Create from a hex string
int fromHex = Colors.fromHex("#FF8800");  // orange

// Blend two colors — useful for hover animations
int blended = Colors.lerp(Colors.GRAY, Colors.CYAN, 0.3f);  // 30% towards cyan

// Make a color semi-transparent
int semiRed = Colors.withAlpha(Colors.RED, 128);  // 128/255 = ~50% opaque

RenderUtil

RenderUtil
fr.eri.eriapi.gui.util
Utility

RenderUtil is a collection of static drawing methods. You use these when you want to draw something custom — for example, inside a ListItem.render() or a component's custom draw code. For most regular use, you don't need to call RenderUtil directly — the built-in components handle their own drawing.

Coordinates inside custom draw methods

When you use RenderUtil inside a ListItem.render(), the x/y coordinates you receive are already in screen pixels (not design pixels). Pass them directly to RenderUtil — no conversion needed.

Drawing methods

  • RenderUtil.drawRect(int x, int y, int w, int h, int color)
    Draws a filled rectangle. All coordinates are in screen pixels. Color is ARGB.
    STATIC
  • RenderUtil.drawRoundRect(int x, int y, int w, int h, int radius, int color)
    Draws a filled rectangle with rounded corners.
    STATIC
  • RenderUtil.drawCircle(int cx, int cy, int radius, int color)
    Draws a filled circle. cx/cy is the center point.
    STATIC
  • RenderUtil.drawGradient(int x, int y, int w, int h, int colorTop, int colorBottom)
    Draws a rectangle with a vertical gradient blending from colorTop at the top to colorBottom at the bottom.
    STATIC
  • RenderUtil.drawText(String text, int x, int y, int color, boolean shadow)
    Draws a string of text at the given position. shadow=true adds a drop shadow.
    STATIC
  • RenderUtil.drawCenteredText(String text, int x, int y, int width, int color, boolean shadow)
    Draws text horizontally centered within the given width, starting at x.
    STATIC
  • RenderUtil.drawScissor(int x, int y, int w, int h)
    Enables a clipping region — anything drawn outside this rectangle will be invisible. Call RenderUtil.stopScissor() when done.
    STATIC
  • RenderUtil.stopScissor()
    Disables the active scissor (clipping) region. Always call this after drawScissor().
    STATIC
  • RenderUtil.drawTexture(ResourceLocation texture, int x, int y, int w, int h)
    Draws an image (texture) from your mod's resources at the given position and size.
    STATIC

Example — custom ListItem using RenderUtil

RenderUtil inside a custom ListItem
@Override
public void render(int x, int y, int width, int height, int mouseX, int mouseY) {
    // Draw a hover highlight if mouse is over this row
    boolean hovered = mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height;
    if (hovered) {
        RenderUtil.drawRect(x, y, width, height, 0x22FFFFFF);  // Subtle white tint
    }

    // Draw a colored dot on the left (status indicator: green = online)
    RenderUtil.drawCircle(x + 16, y + height / 2, 6, 0xFF22CC44);  // Green circle

    // Draw the player name
    RenderUtil.drawText(playerName, x + 32, y + height / 2 - 4, 0xFFFFFFFF, true);

    // Draw the player's level on the right side, right-aligned
    String levelText = "Lv. " + playerLevel;
    // Offset from right edge
    RenderUtil.drawText(levelText, x + width - 60, y + height / 2 - 4, 0xFFCCCCCC, false);
}

SoundManager

SoundManager
fr.eri.eriapi.gui.util
Utility

SoundManager is the UI sound manager for EriAPI. It plays vanilla Minecraft sounds for common interface actions (clicks, hovers, toggles, focus, notifications, etc.) through a simple static API. A global volume and mute flag let you control the audio experience at the application level.

Most sounds are triggered automatically by built-in components — you rarely need to call SoundManager directly unless you want a custom sound or need to silence a specific component.

Pre-made sound methods

  • SoundManager.playClick()
    Plays a standard button-click sound. Vanilla: UI_BUTTON_CLICK. Triggered automatically by InteractiveComponent on click.
    STATIC
  • SoundManager.playHover()
    Plays a subtle hover sound (high pitch, low volume). Vanilla: UI_BUTTON_CLICK. Triggered automatically on mouse enter.
    STATIC
  • SoundManager.playFocus()
    Plays a soft focus sound when a text field gains keyboard focus. Vanilla: UI_BUTTON_CLICK. Triggered automatically by TextField.
    STATIC
  • SoundManager.playTick()
    Plays a tick sound during drag or slide interactions. Vanilla: BLOCK_NOTE_HAT. Useful for Slider step feedback.
    STATIC
  • SoundManager.playSuccess()
    Plays a positive validation sound. Vanilla: ENTITY_EXPERIENCE_ORB_PICKUP. Use after successful form submission or confirmation.
    STATIC
  • SoundManager.playError()
    Plays a low-pitched error sound. Vanilla: BLOCK_NOTE_BASS. Use when an action fails or input validation is rejected.
    STATIC
  • SoundManager.playNotification()
    Plays a notification pop sound. Vanilla: BLOCK_NOTE_PLING. Triggered automatically when a notification component is created.
    STATIC
  • SoundManager.playToggle()
    Plays a toggle sound for on/off state changes. Vanilla: UI_BUTTON_CLICK. Triggered automatically by Checkbox and RadioButton.
    STATIC
  • SoundManager.playOpen()
    Plays a sound when a panel or overlay opens. Vanilla: UI_BUTTON_CLICK.
    STATIC
  • SoundManager.playClose()
    Plays a sound when a panel or overlay closes. Vanilla: UI_BUTTON_CLICK.
    STATIC

Global configuration

  • SoundManager.setMuted(boolean muted)
    Enables or disables all UI sounds globally. When muted, no sound method produces any output.
    STATIC
  • SoundManager.setVolume(float volume)
    Sets the global volume multiplier, between 0.0 (silent) and 1.0 (full volume). Applies to every subsequent sound call.
    STATIC
  • SoundManager.toggleMute()
    Toggles the mute state on/off. Convenient for a settings button that lets the player silence the UI.
    STATIC
  • SoundManager.play(SoundEvent event, float volume, float pitch)
    Plays any vanilla SoundEvent directly with explicit volume and pitch values. The global volume multiplier and mute flag still apply.
    STATIC

Automatic integration with components

Built-in wiring — no setup required

The following components trigger sounds automatically, with no extra code needed on your side:

  • InteractiveComponent — click → playClick(), mouse enter → playHover()
  • Checkbox / RadioButton — toggle → playToggle()
  • TextField — focus gained → playFocus()
  • Notification — on creation → playNotification()

To silence a specific component, call .sound(false) on it.

Usage examples

SoundManager — examples
// Global mute toggle (e.g. settings button)
SoundManager.setMuted(true);      // Disable all UI sounds
SoundManager.setVolume(0.5f);     // Half volume globally
SoundManager.toggleMute();        // Switch mute on/off

// Play a custom vanilla sound with explicit pitch
SoundManager.play(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 0.6f, 1.2f);

// Silence sounds on a specific component only
new Button("Silent Action").sound(false);

// Play feedback sounds manually after server-side validation
if (success) {
    SoundManager.playSuccess();
} else {
    SoundManager.playError();
}

ColorWheel

ColorWheel
fr.eri.eriapi.gui.components
Interactive

A ColorWheel renders an interactive HSB (Hue / Saturation / Brightness) color disc. The player clicks or drags inside the circle to pick a color. The component fires a callback every time the selection changes, giving you the selected color as an ARGB int.

The outer ring represents hue (the color family — red, green, blue…) and the saturation increases towards the edge of each segment. A separate BrightnessSlider is normally placed below the wheel to control the brightness dimension, or you can wire it yourself via brightness(float).

Basic example

ColorWheel — basic usage
ColorWheel wheel = new ColorWheel()
    .originalPos(50, 50)           // Top-left corner in design pixels
    .originalSize(100, 100)        // Width and height (should be equal for a perfect circle)
    .defaultColor(0xFFFF0000)      // Start with red selected
    .onColorChange(color -> {      // Called every time the user moves the selection
        System.out.println("Selected color: #" + Integer.toHexString(color));
    });

addComponent(wheel);

// Read the current selection programmatically at any time:
int currentColor = wheel.getSelectedColor();
float hue        = wheel.getHue();        // 0.0 – 360.0
float saturation = wheel.getSaturation(); // 0.0 – 1.0
float brightness = wheel.getBrightness(); // 0.0 – 1.0

All methods

  • defaultColor(int argb)
    Sets the initially selected color in ARGB format. The wheel converts it to HSB internally and positions the selector accordingly.
    FLUENT
  • onColorChange(Consumer<Integer> callback)
    Called every time the user moves the selection inside the wheel. The new color is passed as an ARGB int.
    EVENT
  • radius(int radius)
    Overrides the radius of the wheel in design pixels. Useful when you want a circular component without specifying equal width/height.
    FLUENT
  • brightness(float value)
    Programmatically sets the brightness dimension (0.0 = black, 1.0 = full color). Used by BrightnessSlider to stay in sync with the wheel.
    FLUENT
  • getSelectedColor()
    Returns the currently selected color as an ARGB int (alpha is always 0xFF).
    GETTER
  • getHue()
    Returns the hue component of the selected color in degrees (0.0 – 360.0).
    GETTER
  • getSaturation()
    Returns the saturation component of the selected color (0.0 – 1.0).
    GETTER
  • getBrightness()
    Returns the brightness component of the selected color (0.0 – 1.0).
    GETTER

BrightnessSlider

BrightnessSlider
fr.eri.eriapi.gui.components
Control

BrightnessSlider extends Slider and is specifically designed to work alongside a ColorWheel. Instead of a plain colored track it renders a gradient that goes from black on the left to the pure hue currently selected in the wheel on the right. Dragging the handle adjusts the brightness of the selected color in real time.

You pass the linked ColorWheel to the constructor — the slider keeps itself in sync automatically. No extra wiring needed.

Pair with ColorPicker for zero-boilerplate setup

If you just need a full color-selection UI, use ColorPicker instead — it bundles a ColorWheel, a BrightnessSlider, a hex input field, and a preview swatch into a single component.

Basic example

BrightnessSlider — linked to a ColorWheel
// First create the wheel
ColorWheel wheel = new ColorWheel()
    .originalPos(50, 50)
    .originalSize(100, 100)
    .defaultColor(0xFF00AAFF);

// Then create the slider and link it to the wheel via the constructor
BrightnessSlider slider = new BrightnessSlider(wheel)
    .originalPos(50, 160)    // Positioned just below the wheel
    .originalSize(100, 14);  // Thin horizontal strip

addComponent(wheel);
addComponent(slider);

Inherited methods (from Slider)

BrightnessSlider inherits all of Slider's fluent methods. The most relevant ones in this context are:

  • onValueChange(Consumer<Double> callback)
    Called whenever the brightness changes. The value is in the range 0.0 (black) to 1.0 (full brightness). In most cases you can rely on the ColorWheel's onColorChange callback instead.
    EVENT
  • getValue()
    Returns the current brightness as a double between 0.0 and 1.0.
    GETTER

ColorPicker

ColorPicker
fr.eri.eriapi.gui.components
Composite

ColorPicker is a self-contained color-selection widget. It bundles four sub-components into one:

  • A ColorWheel for hue and saturation selection
  • A BrightnessSlider below the wheel for brightness
  • A hex TextField for direct hex input (e.g. FF00AAFF)
  • A small color preview swatch showing the current color

All four are kept in bidirectional sync: editing the hex field updates the wheel, and dragging the wheel updates the hex field. You only need one onChange callback to receive the final color.

Preview
#00AACC

Basic example

ColorPicker — basic usage
ColorPicker picker = new ColorPicker()
    .originalPos(50, 50)          // Top-left corner in design pixels
    .originalSize(120, 170)       // Width x height — the sub-components lay out automatically
    .defaultColor(0xFF00AAFF)     // Initial color (ARGB)
    .backgroundColor(0xFF2A2A2A)  // Background behind the whole picker
    .onChange(color -> {          // Called whenever any sub-component changes the color
        System.out.println("Color changed: #" + Integer.toHexString(color));
    });

addComponent(picker);

// Read the currently selected color at any time:
int selectedColor = picker.getColor();

All methods

  • defaultColor(int argb)
    The color that is selected when the picker first appears. Applied to the wheel, the slider, and the hex field simultaneously.
    FLUENT
  • backgroundColor(int argb)
    The background fill drawn behind the entire picker (wheel, slider, hex field, and swatch). Defaults to a dark grey.
    FLUENT
  • onChange(Consumer<Integer> callback)
    Called whenever the selected color changes, regardless of which sub-component triggered the change. The new color is passed as an ARGB int.
    EVENT
  • getColor()
    Returns the currently selected color as an ARGB int.
    GETTER
Sizing tip

The recommended minimum size is 120 × 170 design pixels. Below that the hex field becomes too narrow to be usable. The wheel and slider automatically resize to fill the available space, so you can scale the whole picker up without any extra work.

ContextMenu

ContextMenu
fr.eri.eriapi.gui.components
Popup

ContextMenu is a popup menu that appears at a given screen position and disappears when the user clicks elsewhere or selects an entry. It is the standard "right-click menu" pattern. Internally it extends ContainerComponent and manages its own list of MenuItems.

Key behaviors:

  • Calls open(x, y) to show the menu at a specific position.
  • If the menu would overflow the screen edge, it auto-adjusts its position so it stays fully visible.
  • Clicking outside the menu automatically calls close().
  • Clicking a disabled item does nothing.
  • Clicking a separator does nothing.
  • Hovered items are highlighted automatically.
Preview
Copy
Paste
Rename
Delete
Undo

Basic example

ContextMenu — typical right-click usage
// 1. Build the menu once (usually in initGui or a field)
ContextMenu menu = new ContextMenu()
    .add("Copy",   () -> performCopy())
    .add("Paste",  () -> performPaste())
    .addSeparator()
    .add("Delete", () -> performDelete())
    .minWidth(120);  // Optional: ensure the menu is at least 120 px wide

addComponent(menu);  // Always register the menu as a component

// 2. Open it when the player right-clicks (or any trigger you choose)
@Override
protected void mouseClicked(int mouseX, int mouseY, int button) {
    super.mouseClicked(mouseX, mouseY, button);
    if (button == 1) {  // button == 1 is the right mouse button
        menu.open(mouseX, mouseY);
    }
}

// 3. The menu closes itself when the user clicks outside — nothing else needed.

Working with MenuItem objects directly

ContextMenu — using addItem(MenuItem)
// Build items separately for more control
MenuItem copyItem    = new MenuItem("Copy",   () -> performCopy());
MenuItem pasteItem   = new MenuItem("Paste",  () -> performPaste());
MenuItem deleteItem  = new MenuItem("Delete", () -> performDelete()).enabled(false);

ContextMenu menu = new ContextMenu()
    .addItem(copyItem)
    .addItem(pasteItem)
    .addItem(MenuItem.separator())
    .addItem(deleteItem);

addComponent(menu);

All methods

  • add(String text, Runnable action)
    Shorthand that creates a new enabled MenuItem and appends it to the menu. Returns this for chaining.
    FLUENT
  • addItem(MenuItem item)
    Appends a pre-built MenuItem (including separators and disabled items) to the menu.
    FLUENT
  • addSeparator()
    Appends a separator line to the menu. Equivalent to addItem(MenuItem.separator()).
    FLUENT
  • clear()
    Removes all items from the menu. Useful when you need to rebuild the item list dynamically before showing the menu.
    FLUENT
  • minWidth(int width)
    Sets a minimum width (in design pixels) for the popup. The menu still expands wider if any item's text requires more space.
    FLUENT
  • open(int x, int y)
    Opens the menu at the given screen coordinates. If the menu would extend beyond the screen edges it is repositioned automatically to stay fully visible.
    ACTION
  • close()
    Hides the menu. Called automatically when the user clicks outside. You can also call it programmatically to close the menu without any user interaction.
    ACTION

Texture support

The popup panel can display a background texture. By default NINE_SLICE with a 4 px border is used so the texture adapts cleanly to any menu size.

  • menuImage(ResourceLocation texture)
    Background texture for the popup panel.
    FLUENT
  • menuImageScaleMode(ScaleMode mode)
    How the panel texture is scaled (default: NINE_SLICE).
    FLUENT
  • menuImageTint(int argb)
    ARGB tint applied on top of the panel texture.
    FLUENT
  • menuSliceBorder(int pixels)
    Corner size for NINE_SLICE mode (default: 4).
    FLUENT
Always register the menu as a component

Even though the menu is invisible most of the time, you must call addComponent(menu) in initGui(). This is what connects the menu to the input event pipeline so it can detect outside clicks and render properly when open.

ToggleSwitch

A ToggleSwitch is a visual ON/OFF switch — the modern equivalent of a Checkbox, with a knob that slides horizontally when toggling. Ideal for enabling or disabling an option clearly.

ToggleSwitch
fr.eri.eriapi.gui.components.ToggleSwitch
Interactive control

Example

Java — ToggleSwitch
import fr.eri.eriapi.gui.components.ToggleSwitch;

// new ToggleSwitch(x, y, width, height)
ToggleSwitch toggle = new ToggleSwitch(860, 500, 60, 30)
    .label("Show Mana HUD")
    .setState(true)
    .activeColor(0xFF00E5FF)
    .onToggle(on -> manaBarMod.setEnabled(on));

root.add(toggle);

// Read state from another component:
boolean active = toggle.getState();
  • setState(boolean state)
    Sets the initial or programmatic state of the switch. true = active (knob on the right), false = inactive.
    Fluent
  • boolean getState()
    Returns the current state of the switch.
    Getter
  • onToggle(Consumer<Boolean> callback)
    Called every time the user toggles the switch. Receives the new state (true = active).
    Event
  • label(String text)
    Text displayed to the right of the switch. Clicking the label also toggles the switch.
    Fluent
  • activeColor(int argb)
    Track background color when the switch is active. Default: cyan (0xFF00E5FF).
    Fluent
  • inactiveColor(int argb)
    Track background color when the switch is inactive. Default: dark grey.
    Fluent

PlayerHead

PlayerHead renders a player's 3D head directly inside a GUI — full skin with hat layer, configurable orientation. Useful for profiles, leaderboards, and member previews.

PlayerHead
fr.eri.eriapi.gui.components.PlayerHead
Minecraft Rendering

Example

Java — PlayerHead
import fr.eri.eriapi.gui.components.PlayerHead;
import com.mojang.authlib.GameProfile;

// From a GameProfile (connected player)
PlayerHead head = new PlayerHead(860, 300, 80, player.getGameProfile())
    .setRotation(-20f, 15f)  // yaw, pitch
    .showHat(true);

root.add(head);

// From a UUID (offline / stored player)
UUID uuid = UUID.fromString("069a79f4-44e9-4726-a5be-fca90e38aaf5"); // Notch
PlayerHead headByUuid = new PlayerHead(960, 300, 80, uuid)
    .showHat(false);
  • PlayerHead(int x, int y, int size, GameProfile profile)
    Creates a head render from a GameProfile. The skin is loaded automatically.
    Constructor
  • PlayerHead(int x, int y, int size, UUID uuid)
    Creates a head render from a UUID. The skin is fetched asynchronously.
    Constructor
  • setProfile(GameProfile profile)
    Changes the rendered profile (useful for dynamic lists).
    Fluent
  • setRotation(float yaw, float pitch)
    Orients the head in degrees. Yaw = left/right rotation, pitch = up/down. E.g. (-20f, 15f) for a three-quarter front angle.
    Fluent
  • showHat(boolean enabled)
    Shows or hides the second skin layer (hat, accessories). Default: true.
    Fluent

ItemStackRenderer

ItemStackRenderer renders a Minecraft ItemStack (with its 2D icon, enchantment glint, stack count and tooltip) directly inside an EriAPI GUI.

ItemStackRenderer
fr.eri.eriapi.gui.components.ItemStackRenderer
Minecraft Rendering

Example

Java — ItemStackRenderer
import fr.eri.eriapi.gui.components.ItemStackRenderer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;

// new ItemStackRenderer(x, y, size, stack)
ItemStackRenderer renderer = new ItemStackRenderer(
        900, 400, 32, new ItemStack(Items.DIAMOND_SWORD))
    .showTooltip(true)    // Show vanilla tooltip on hover
    .showCount(false)     // Hide the stack count
    .scale(1.5f);         // Enlarge the icon by 50%

root.add(renderer);

// Change the item dynamically (e.g. inventory slot)
renderer.setStack(player.getHeldItemMainhand());
  • setStack(ItemStack stack)
    Replaces the rendered ItemStack. Can be called every tick for a dynamic render.
    Fluent
  • showTooltip(boolean enabled)
    Displays the vanilla tooltip (name, lore, enchantments) when the mouse hovers over the component. Default: true.
    Fluent
  • showCount(boolean enabled)
    Displays the item count text as an overlay (bottom-right corner). Default: true. Independent from showDurability() — you can hide the count while keeping the durability bar.
    Fluent
  • showDurability(boolean enabled)
    Displays the durability bar below the icon (for items with durability). Default: true. Independent from showCount() — for example, showCount(false).showDurability(true) renders the durability bar without the count text.
    Fluent
  • scale(float factor)
    Icon scale factor. 1.0f = normal size (16x16), 2.0f = double. Default: 1.0f.
    Fluent

ItemSlot

ItemSlot is a Minecraft inventory slot component with full vanilla interactions: shared cursor, drag-and-drop, shift+click, double-click. It faithfully reproduces the behavior of GuiContainer while integrating into any EriGuiScreen.

The component supports three distinct modes depending on the GUI architecture (client-only, server-authoritative or direct take).

ItemSlot
fr.eri.eriapi.gui.components.ItemSlot
Minecraft Rendering

Example — simple client inventory

Java — ItemSlot in normal mode (client-authoritative)
import fr.eri.eriapi.gui.components.ItemSlot;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;

// Empty interactive slot
ItemSlot slot = new ItemSlot()
    .originalPos(100, 100)
    .originalSize(48, 48)
    .onSlotChanged((s, stack) -> System.out.println("Contents: " + stack.getDisplayName()));

// Pre-filled slot with a diamond
ItemSlot slotDia = new ItemSlot(new ItemStack(Items.DIAMOND, 32))
    .originalPos(160, 100)
    .originalSize(48, 48)
    .slotId("chest:0")                               // logical identifier for the server
    .onSlotChanged((s, stack) -> saveToServer(stack))
    .onShiftClick((s, stack) -> transferToPlayer(stack));

root.add(slot, slotDia);

Example — server-only mode (server inventory)

Java — ItemSlot in serverOnly mode
// All slots target the server — no local manipulation
for (int i = 0; i < 27; i++) {
    final int idx = i;
    ItemSlot slot = new ItemSlot()
        .originalPos(80 + (i % 9) * 54, 200 + (i / 9) * 54)
        .originalSize(48, 48)
        .serverOnly(true)            // server-authoritative mode
        .slotId("chest:" + idx)      // identifier sent to the server in the drag callback
        .onAnyClick((s, button) -> {
            // Called for every simple click. button: 0=left, 1=right, 2=shift+left
            sendClickPacket(idx, button, ItemSlot.getCursorStack());
        })
        .onDoubleClick((s, type) -> {
            // type 0 = double-click collect, type 3 = shift+double-click
            sendDoubleClickPacket(idx, type);
        });
    root.add(slot);
}

// Register the drag callback (one global callback for the whole GUI)
ItemSlot.setServerDragCallback((button, targetSlotIds) -> {
    sendDragPacket(button, targetSlotIds);
});

Example — takeOnly mode (showcase)

Java — ItemSlot in takeOnly mode
// The player can take the item but cannot deposit another one
ItemSlot showcase = new ItemSlot(new ItemStack(Items.DIAMOND_SWORD))
    .originalPos(200, 300)
    .originalSize(48, 48)
    .takeOnly(true)
    .onSlotChanged((s, taken) -> giveTo(player, taken));

Click behavior (normal mode)

Action Behavior
Left click — empty cursor Picks up the full slot contents into the cursor
Left click — cursor has item Deposits / merges / swaps with the slot
Right click — empty cursor Picks up half the stack
Right click — cursor has item Deposits one item into the slot
Shift + left click Triggers onShiftClick (bulk transfer delegated to caller)
Left drag Distributes the cursor stack evenly across hovered slots
Right drag Deposits 1 item per hovered slot
Left double-click Triggers onDoubleClick (type 0 — collect all matching items)
Shift + double-click Triggers onDoubleClick (type 3 — transfer all matching items)

Server-only flow — one action per physical click

In serverOnly mode, no action is fired on mouseDown. All logic is decided at mouseUp (via onDragEnd()): if drag slots were accumulated, it is a drag — otherwise it is a simple click. Only one callback is ever triggered, never two.

  • ItemSlot()
    Creates an empty slot.
    Constructor
  • ItemSlot(ItemStack stack)
    Creates a pre-filled slot with the provided ItemStack.
    Constructor
  • stack(ItemStack s)
    Sets or replaces the slot's ItemStack. Pass null to clear the slot.
    Fluent
  • interactive(boolean b)
    Enables or disables interactions. A non-interactive slot is rendered but does not respond to clicks. Default: true.
    Fluent
  • takeOnly(boolean b)
    Direct-take mode — a click takes the item without going through the cursor. The player cannot deposit items into this slot.
    Fluent
  • serverOnly(boolean b)
    Server-authoritative mode — no local manipulation. Clicks and drags are delegated to callbacks; the server responds with the new state. Automatically enables interactive(true).
    Fluent
  • slotId(String id)
    Logical identifier of the slot (e.g. "chest:5", "player:12"). Used by the server-only drag to identify slots in the packet sent to the server.
    Fluent
  • filter(Predicate<ItemStack> f)
    Filter accepted items. Returning false blocks the item from being deposited into this slot.
    Fluent
  • bgColor(int color)
    Background color of the slot at rest (ARGB). Default: 0x20FFFFFF.
    Fluent
  • hoverColor(int color)
    Background color when the mouse hovers over the slot (ARGB). Default: 0x40FFFFFF.
    Fluent
  • slotBorderColor(int color)
    Border color of the slot (ARGB). Set to 0 to remove the border. Default: 0x15FFFFFF.
    Fluent
  • cornerRadius(int r)
    Rounded corner radius in design pixels. Default: 4.
    Fluent
  • onSlotChanged(SlotAction action)
    Callback called when the slot's contents change. Receives the slot and the new ItemStack (empty if the slot is cleared). Signature: (ItemSlot slot, ItemStack stack) -> void.
    Fluent
  • onShiftClick(SlotAction action)
    Callback called on Shift+left click. Receives the slot and its current ItemStack. Use to implement bulk transfer (e.g. chest → player inventory).
    Fluent
  • onRightClick(SlotAction action)
    Callback called on right click when the cursor is empty (picking up half the stack).
    Fluent
  • onAnyClick(ClickAction action)
    Generic callback called on any simple click in serverOnly mode. Signature: (ItemSlot slot, int button) -> void. button is 0 (left), 1 (right) or 2 (shift+left).
    Fluent
  • onDoubleClick(DoubleClickAction action)
    Callback called on left double-click in serverOnly mode. Signature: (ItemSlot slot, int type) -> void. type is 0 (collect) or 3 (Shift+double-click transfer).
    Fluent

Static methods

  • ItemSlot.getCursorStack()
    Returns the ItemStack currently held by the cursor (shared across all slots of the GUI).
    Static
  • ItemSlot.setCursorStack(ItemStack s)
    Forces the cursor contents (useful for applying the server response).
    Static
  • ItemSlot.clearCursor()
    Clears the cursor and resets all drag state. Called automatically by EriGuiScreen.onGuiClosed().
    Static
  • ItemSlot.renderCursorItem(int mouseX, int mouseY)
    Renders the item held by the cursor at the mouse position. Called automatically by EriGuiScreen.drawScreen() after all components.
    Static
  • ItemSlot.setServerDragCallback(ServerDragCallback cb)
    Registers the global drag callback for server-only mode. Signature: (int button, List<String> targetSlotIds) -> void. One callback is sufficient for the entire GUI.
    Static
  • ItemSlot.onDragEnd()
    Finalizes the current drag and fires the appropriate callbacks. Called automatically by EriGuiScreen.mouseReleased(). Never call manually.
    Static
Automatic integration in EriGuiScreen

EriGuiScreen automatically handles the full lifecycle of ItemSlot components: drawScreen() calls renderCursorItem() after all components, mouseReleased() calls onDragEnd() before propagating to components, mouseClickMove() propagates checkDragHover() to every slot in the tree, and onGuiClosed() calls clearCursor(). You never need to wire anything manually.

Rendering at any size

The item is automatically scaled via GL to fill the slot area. You can use a slot of 32x32, 48x48 or 64x64 design pixels — the icon always adapts cleanly, regardless of the player's actual screen resolution.

TexturedRect

TexturedRect renders a PNG texture (via ResourceLocation) within the component bounds. It supports a color tint, a grayscale mode and sub-pixel rendering via the Tessellator for precise floating-point coordinates. Works equally well inside an EriGuiScreen or an OverlayMod.

TexturedRect
fr.eri.eriapi.gui.components.TexturedRect
Minecraft Rendering

Example

Java — TexturedRect
import fr.eri.eriapi.gui.components.TexturedRect;
import net.minecraft.util.ResourceLocation;

// Color icon 64x64
TexturedRect icon = new TexturedRect(
        new ResourceLocation("eriniumfaction", "textures/gui/faction_icon.png"))
    .originalPos(40, 40)
    .originalSize(64, 64)
    .tint(0xFFFFFFFF);          // white = no tint

root.add(icon);

// Desaturated (grayscale) icon for an inactive element
TexturedRect iconGray = new TexturedRect(
        new ResourceLocation("eriniumfaction", "textures/gui/faction_icon.png"))
    .originalPos(120, 40)
    .originalSize(64, 64)
    .grayscale(true);

root.add(iconGray);

// Colored semi-transparent tint
TexturedRect tinted = new TexturedRect(
        new ResourceLocation("eriniumfaction", "textures/gui/banner.png"))
    .originalPos(0, 0)
    .originalSize(1920, 1080)
    .tint(0x80FF6600)           // orange 50% transparent
    .textureSize(256, 128);     // actual PNG image size

root.add(tinted);

// Update dynamically
icon.setGrayscale(true);
icon.setTint(0x80FFFFFF);
  • TexturedRect(ResourceLocation texture)
    Creates a component that renders the specified PNG texture. The texture must be on the mod's classpath (inside the assets/ folder).
    Constructor
  • texture(ResourceLocation tex)
    Replaces the rendered texture. Can be called dynamically to change the displayed image.
    Fluent
  • tint(int color)
    Applies an ARGB tint to the texture. 0xFFFFFFFF = no tint (default). The tint alpha multiplies the component's opacity.
    Fluent
  • grayscale(boolean gray)
    Enables grayscale rendering (applies a neutral color (0.35, 0.35, 0.35)). Useful for disabled elements or inactive icons. Default: false.
    Fluent
  • textureSize(int w, int h)
    Declares the actual PNG image resolution (in pixels). Informs the render engine about the UV proportions of the texture. Default: 64x64.
    Fluent
  • setGrayscale(boolean g)
    Non-fluent equivalent of grayscale() — useful for toggling the mode from a callback.
    Setter
  • setTint(int c)
    Non-fluent equivalent of tint() — useful for animating the tint from an onColorUpdate().
    Setter
  • getTexture()
    Returns the ResourceLocation of the currently displayed texture.
    Getter
Sub-pixel rendering

TexturedRect uses the Tessellator with float coordinates for precise sub-pixel positioning. Unlike Gui.drawTexturedModalRect() which rounds to integers, this component aligns perfectly with the ScaleManager even at non-integer scales.

Divider

A Divider is a horizontal or vertical separator line. It can be solid color or gradient, with configurable margins, and integrates into any panel to visually separate sections.

Divider
fr.eri.eriapi.gui.components.Divider
Decorative

Example

Java — Divider
import fr.eri.eriapi.gui.components.Divider;

// new Divider(x, y, length)  — horizontal by default
root.add(new Divider(60, 200, 500)
    .gradient(0x4400E5FF, 0x00000000)  // Cyan to transparent
    .thickness(1)
    .margin(20));

// Solid vertical separator
root.add(new Divider(960, 100, 800)
    .vertical()
    .color(0x33FFFFFF)
    .thickness(2));
  • horizontal()
    Horizontal mode (default). The length parameter is the width.
    Fluent
  • vertical()
    Vertical mode. The length parameter becomes the height.
    Fluent
  • color(int argb)
    Solid color for the line. Replaces any previously defined gradient.
    Fluent
  • thickness(int px)
    Line thickness in design pixels. Default: 1.
    Fluent
  • gradient(int startColor, int endColor)
    Applies a linear gradient from startColor to endColor along the line. Replaces the solid color.
    Fluent
  • margin(int px)
    Transparent empty space at the start and end of the line. Useful to add breathing room relative to panel edges.
    Fluent

Badge

A Badge is a compact pill-shaped tag — perfect for displaying categories, ranks, statuses or short labels (e.g. "Combat", "Leader", "Online"). Auto-sized based on its content.

Badge
fr.eri.eriapi.gui.components.Badge
Decorative

Example

Java — Badge
import fr.eri.eriapi.gui.components.Badge;

// new Badge(x, y, text) — auto-size calculated from text
root.add(new Badge(200, 150, "Combat")
    .color(0x206B2FA0, 0xFF9B4FCF)  // (bgColor, textColor)
    .outlined(true));

// Badge with icon
root.add(new Badge(300, 150, "Leader")
    .color(0x20FFD700, 0xFFFFD700)
    .icon(new ResourceLocation("eriniumfaction", "textures/gui/icon_crown.png"))
    .cornerRadius(4));

// Solid badge (not outlined)
root.add(new Badge(400, 150, "Online")
    .color(0xFF1A6B3C, 0xFF2ECC71)
    .scale(0.75f));
  • color(int bgColor, int textColor)
    Background color and text color in ARGB. The background accepts a low alpha value for a translucent effect.
    Fluent
  • outlined(boolean enabled)
    Outline mode: transparent background, colored border using bgColor.
    Fluent
  • cornerRadius(int px)
    Corner radius in design pixels. Default: 999 (perfect pill). Use 4 for a rounded-rectangle look.
    Fluent
  • icon(ResourceLocation texture)
    16x16 icon displayed to the left of the text. The badge width adjusts automatically.
    Fluent
  • scale(float factor)
    Text scale of the badge. Default: 0.8f. Reduce for very compact badges.
    Fluent

Accordion

An Accordion is a list of collapsible sections. Each section has a clickable header that expands or collapses its content with an animated height transition. The singleMode option ensures only one section is open at a time.

Accordion
fr.eri.eriapi.gui.components.Accordion
Layout component

Example

Java — Accordion
import fr.eri.eriapi.gui.components.Accordion;

// new Accordion(x, y, width)
Accordion acc = new Accordion(660, 300, 600)
    .singleMode(true);  // Only one section open at a time

acc.addSection("Information", section -> {
    section.add(new Label(10, 10, 580, 20,
        "Name: " + faction.getName()));
    section.add(new Label(10, 35, 580, 20,
        "Members: " + faction.getMemberCount()));
});

acc.addSection("Statistics", section -> {
    section.add(new Label(10, 10, 580, 20,
        "Wins: " + faction.getWins()));
    section.add(new Label(10, 35, 580, 20,
        "Losses: " + faction.getLosses()));
});

acc.addSection("Members", section -> {
    for (String member : faction.getMembers()) {
        section.add(new Label(10, 10 + i * 25, 580, 20, member));
    }
});

root.add(acc);
  • addSection(String title, Consumer<ContainerComponent> builder)
    Adds a section with the header title. The lambda receives the content ContainerComponent — add your components inside it.
    Method
  • expandAll()
    Expands all sections. Ignores singleMode.
    Method
  • collapseAll()
    Collapses all sections.
    Method
  • singleMode(boolean enabled)
    When active, opening a section automatically closes any other open section. Default: false.
    Fluent

ProgressBarEnhanced

ProgressBarEnhanced is an advanced progress bar supporting 9 geometric shapes, gradients, segments, smooth animations and a centered label. Use it instead of the standard ProgressBar when you need circular, hexagonal, or segmented rendering.

ProgressBarEnhanced
fr.eri.eriapi.gui.components.ProgressBarEnhanced
Visual control

Available shapes — enum BarShape

ConstantRenderTypical use
BarShape.HORIZONTALLeft-to-right barXP, health, mana
BarShape.VERTICALBottom-to-top barWater level, heat
BarShape.CIRCULARRing (arc)Cooldown, stamina
BarShape.PIEFilled pie chartResource share
BarShape.DIAMONDDiamond shapePvP stats
BarShape.PENTAGONPentagonOverall score
BarShape.HEXAGONHexagonAbilities, rank
BarShape.OCTAGONOctagonShield, defense
BarShape.SQUARESquare with cornersCompact bar

Fill direction — enum FillDirection

ConstantDirection
FillDirection.LEFT_TO_RIGHTLeft to right (horizontal default)
FillDirection.RIGHT_TO_LEFTRight to left
FillDirection.BOTTOM_TO_TOPBottom to top (vertical default)
FillDirection.TOP_TO_BOTTOMTop to bottom
FillDirection.CLOCKWISEClockwise (circular shapes)
FillDirection.COUNTERCLOCKWISECounter-clockwise

Examples

Java — Circular ring with gradient
import fr.eri.eriapi.gui.components.ProgressBarEnhanced;
import fr.eri.eriapi.gui.components.ProgressBarEnhanced.BarShape;
import fr.eri.eriapi.gui.components.ProgressBarEnhanced.FillDirection;

// Circular ring for a cooldown
ProgressBarEnhanced ring = new ProgressBarEnhanced(860, 440, 200, 200)
    .shape(BarShape.CIRCULAR)
    .value(0.72f)
    .barWidth(18)
    .gradientFill(0xFF00E5FF, 0xFF6B2FA0)
    .backgroundColor(0xFF1A1A2E)
    .showPercentage(true)
    .animate(true);

root.add(ring);
Java — Segmented horizontal bar
// Segmented XP bar old-school style
ProgressBarEnhanced bar = new ProgressBarEnhanced(100, 50, 400, 20)
    .shape(BarShape.HORIZONTAL)
    .value(0.5f)
    .segments(10)
    .segmentGap(2)
    .fillColor(0xFF00D4FF)
    .cornerRadius(4)
    .animate(true)
    .animationSpeed(10);  // Transition over 10 ticks (0.5 sec)

root.add(bar);
  • shape(BarShape shape)
    Sets the geometric shape of the bar. See the BarShape table above.
    Fluent
  • value(float v)
    Fill value between 0.0 (empty) and 1.0 (full). If animate is active, the transition is animated.
    Fluent
  • fillColor(int argb)
    Solid fill color. Replaces any defined gradient.
    Fluent
  • backgroundColor(int argb)
    Color of the empty area (bar background).
    Fluent
  • barWidth(int px)
    Ring or outline thickness for circular and polygonal shapes.
    Fluent
  • gradientFill(int startColor, int endColor)
    Linear gradient fill. For CIRCULAR/PIE, the gradient follows the arc.
    Fluent
  • segments(int n)
    Divides the bar into n separated segments. Very useful for RPG-style health bars.
    Fluent
  • segmentGap(int px)
    Spacing in design pixels between segments.
    Fluent
  • direction(FillDirection dir)
    Fill direction. See the FillDirection table above.
    Fluent
  • animate(boolean enabled)
    Enables animated transitions when the value changes via value().
    Fluent
  • animationSpeed(int ticks)
    Transition duration in ticks. Default: 10 (0.5 sec). Requires animate(true).
    Fluent
  • showPercentage(boolean enabled)
    Displays the percentage ("72%") centered on the component.
    Fluent
  • label(String text)
    Centered text displayed as an overlay. Overrides the percentage if showPercentage is also active.
    Fluent
  • cornerRadius(int px)
    Corner radius for HORIZONTAL, VERTICAL and SQUARE shapes.
    Fluent

GUI Showcase — Page 2: Textures

The demo GUI (opened with /skyapitest) now has two pages, navigated with the header buttons:

  • Components — All standard components (buttons, inputs, charts, ColorPicker, etc.)
  • Textures — Live demo of texture support for ProgressBar, Slider, Checkbox, ScrollPanel, ScrollList, TabView, ContextMenu, and Notification.
i
Showcase navigation

The "Components" and "Textures" buttons in the showcase header let you switch between pages. The active page is highlighted on the button.