Skip to content

Handles: enable, hide, tooltip

Every add… method returns a handle. It keeps the element's state before and after the window opens, so you can disable a button, hide a line or explain a choice with a tooltip.

⏱ 5 minGaldur UI 0.1.0Client

The three states

An ElementHandle changes three things on any element:

StateMethodEffect
DisabledsetEnabled(false)Drawn in a muted colour, ignores mouse and keyboard. The tooltip still shows on hover, to explain why.
HiddensetVisible(false)Not drawn and frees its space: the window lays itself out again without it.
TooltipsetTooltip(text)Text shown when the element is hovered. null removes it.
Example.java
ElementHandle confirm = window.addButton(Component.literal("Confirm"), this::confirm);confirm.setEnabled(false);confirm.setTooltip(Component.literal("Fill in the form first"));ElementHandle details = window.addText(Component.literal("Details..."));details.setVisible(false);   // the element disappears and frees its space

A change made while the window is shown is visible on the next frame. Call handles on the client thread.

Why the state lives in the handle

Minecraft rebuilds widgets on every resize. The state lives in the handle, not in the shown widget, so a checked box stays checked and a hidden line stays hidden: the new widgets read the state back.

Connect elements together

Handles make it easy to tie elements to each other. Enable "Take" only when a line is selected:

Example.java
ElementHandle take = buttons.addButton(Component.literal("Take"), this::take);take.setEnabled(false);list.onSelect(index -> take.setEnabled(index >= 0));

Show a line only while a checkbox is ticked:

Example.java
ElementHandle detail = window.addText(Component.literal("12 items, 3 different kinds"));detail.setVisible(false);CheckboxHandle showDetail = window.addCheckbox(Component.literal("Show details"), false);showDetail.onChange(detail::setVisible);

Specialised handles

Some elements return a handle with more methods. All of them are also an ElementHandle.

HandleReturned byAdds
CheckboxHandleaddCheckboxisChecked, setChecked, onChange
ListHandleaddListsetLines, addLine, getSelected, onSelect
SearchHandleaddSearchgetText, setText, onChange (every keystroke)
ProgressHandleaddProgresssetProgress(0..1), setProgress(done, total), setLabel
RowHandleaddRowaddText, addButton, addIconButton, addCheckbox
TabsHandleaddTabsaddTab, getSelected, setSelected, onSelect
One action per handle

onChange and onSelect keep only one action: a new call replaces the previous one. They fire when the value really changes, whether the change comes from the player or from your code.

Rows and tabs

On a row or a tab row, the three states apply to everything inside:

  • disabled, a row disables all its elements; a tab row can no longer be switched, and the shown content is disabled too;
  • hidden, it disappears with its content and frees its space;
  • tooltip: on a row, it shows on the elements that have none of their own; on a tab row, only when the tabs are hovered, not the content.

Progress bars

A ProgressHandle is read every frame: update it as often as you like, every tick for instance, without rebuilding the screen.

Example.java
ProgressHandle craft = window.addProgress(Component.literal("Iron ingots: 0 / 64"));craft.setProgress(16, 64);craft.setLabel(Component.literal("Iron ingots: 16 / 64"));

The bar width is computed when the screen is built, from the text. A longer text given later is cut with "…" until the next rebuild.

© 2026 Galdur Studio · galdurstudio.com · Discord · LGPL-3.0-onlyNot an official Minecraft product. Not approved by or associated with Mojang or Microsoft.