Code Patterns
Copy-paste examples for common plugin tasks. Commands, events, ECS, GUI, and more.
All
225
Command
60
Damage
2
Ecs
27
Entity
5
Gui
75
Interaction
2
Inventory
4
Moderation
3
Permission
2
Player
9
Plugin
4
Storage
2
Teleport
3
Ui
22
Util
5
← Back to Patterns
java
ui
ui-form-inputs
Form pattern with TextField, NumberField, and CheckBox inputs. Shows how to read input values using the @-prefix in EventData codec and binding input values to events.
Example Code
// FormPage.ui (simplified)
Group {
Anchor: (Width: 480, Height: 380);
Background: #141c26(0.98);
LayoutMode: Top;
Padding: (Full: 24);
Label { Text: "Settings"; Style: (FontSize: 24, TextColor: #ffffff); Anchor: (Height: 40); }
// Text input field with ID for binding
TextField #NameInput {
Text: "";
PlaceholderText: "Enter name...";
Anchor: (Height: 40);
}
// Checkbox with nested structure
Group #NotifyOption {
LayoutMode: Left;
Anchor: (Height: 30);
CheckBox #CheckBox { Value: true; }
Label { Text: "Enable notifications"; Style: (TextColor: #ffffff); }
}
TextButton #SaveButton { Text: "Save"; Anchor: (Width: 100, Height: 40); }
TextButton #CancelButton { Text: "Cancel"; Anchor: (Width: 100, Height: 40); }
}
// FormPage.java
public class FormPage extends InteractiveCustomUIPage<FormPage.FormEventData> {
public static class FormEventData {
public String action; // Which button clicked
public String playerName; // Text input value
public boolean notifications; // Checkbox state
// CODEC: Fields with @ prefix read from UI inputs
public static final BuilderCodec<FormEventData> CODEC = BuilderCodec.builder(FormEventData.class, FormEventData::new)
.append(new KeyedCodec<>("Action", Codec.STRING),
(o, v) -> o.action = v, o -> o.action).add()
// @ prefix = bound to input element
.append(new KeyedCodec<>("@PlayerName", Codec.STRING),
(o, v) -> o.playerName = v, o -> o.playerName).add()
.append(new KeyedCodec<>("@Notifications", Codec.BOOLEAN),
(o, v) -> o.notifications = v, o -> o.notifications).add()
.build();
}
public FormPage(@Nonnull PlayerRef playerRef) {
super(playerRef, CustomPageLifetime.CanDismissOrCloseThroughInteraction, FormEventData.CODEC);
}
@Override
public void build(
@Nonnull Ref<EntityStore> ref,
@Nonnull UICommandBuilder cmd,
@Nonnull UIEventBuilder evt,
@Nonnull Store<EntityStore> store
) {
cmd.append("Pages/FormPage.ui");
// Bind Save button with input values
// EventData.append binds: "@FieldName" to "#ElementId.Value"
evt.addEventBinding(
CustomUIEventBindingType.Activating,
"#SaveButton",
new EventData()
.append("Action", "Save")
.append("@PlayerName", "#NameInput.Value") // Read TextField
.append("@Notifications", "#NotifyOption #CheckBox.Value") // Read CheckBox
);
evt.addEventBinding(
CustomUIEventBindingType.Activating,
"#CancelButton",
new EventData().append("Action", "Cancel")
);
}
@Override
public void handleDataEvent(
@Nonnull Ref<EntityStore> ref,
@Nonnull Store<EntityStore> store,
@Nonnull FormEventData data
) {
if ("Save".equals(data.action)) {
// data.playerName contains what user typed
// data.notifications contains checkbox state
playerRef.sendMessage(Message.raw("Saved: " + data.playerName));
}
Player player = store.getComponent(ref, Player.getComponentType());
player.getPageManager().setPage(ref, store, Page.None);
}
}
Thread Safety
Form data is validated on server - never trust client input
Common Mistakes
Forgetting the @ prefix in codec field names when binding to inputs - without @ the value wont be read from UI