0
# Events and Interactivity
1
2
Click and hover event system for creating interactive text with commands, URLs, and rich tooltips. Adventure's event system enables rich user interactions within text components.
3
4
## Capabilities
5
6
### Click Events
7
8
Click events define actions that occur when users click on text components.
9
10
```java { .api }
11
/**
12
* Click event that executes an action when text is clicked
13
*/
14
class ClickEvent implements ComponentBuilderApplicable, StyleBuilderApplicable, Examinable {
15
/**
16
* Gets the click action type
17
* @return the action
18
*/
19
Action action();
20
21
/**
22
* Gets the click action value/parameter
23
* @return the value string
24
*/
25
String value();
26
27
// Factory methods for common click actions
28
/**
29
* Opens a URL in the client's browser
30
* @param url the URL to open
31
* @return click event for opening URL
32
*/
33
static ClickEvent openUrl(String url);
34
35
/**
36
* Opens a URL with validation
37
* @param url the URL to open
38
* @return click event for opening URL
39
*/
40
static ClickEvent openUrl(URL url);
41
42
/**
43
* Opens a file (client-side only)
44
* @param file the file path to open
45
* @return click event for opening file
46
*/
47
static ClickEvent openFile(String file);
48
49
/**
50
* Runs a command as the clicking player
51
* @param command the command to run (without /)
52
* @return click event for running command
53
*/
54
static ClickEvent runCommand(String command);
55
56
/**
57
* Suggests a command in the player's chat input
58
* @param command the command to suggest
59
* @return click event for suggesting command
60
*/
61
static ClickEvent suggestCommand(String command);
62
63
/**
64
* Changes the page in a book
65
* @param page the page number to go to
66
* @return click event for changing page
67
*/
68
static ClickEvent changePage(String page);
69
70
/**
71
* Changes the page in a book
72
* @param page the page number to go to
73
* @return click event for changing page
74
*/
75
static ClickEvent changePage(int page);
76
77
/**
78
* Copies text to the client's clipboard
79
* @param text the text to copy
80
* @return click event for copying to clipboard
81
*/
82
static ClickEvent copyToClipboard(String text);
83
84
/**
85
* Executes a callback function (server-side)
86
* @param function the callback function
87
* @return click event for callback
88
*/
89
static ClickEvent callback(ClickCallback<Audience> function);
90
91
/**
92
* Creates a click event
93
* @param action the action type
94
* @param value the action value
95
* @return new click event
96
*/
97
static ClickEvent clickEvent(Action action, String value);
98
99
/**
100
* Types of click actions
101
*/
102
enum Action {
103
/**
104
* Opens a URL in browser
105
*/
106
OPEN_URL("open_url"),
107
108
/**
109
* Opens a file (client-side)
110
*/
111
OPEN_FILE("open_file"),
112
113
/**
114
* Runs a command as the player
115
*/
116
RUN_COMMAND("run_command"),
117
118
/**
119
* Suggests command in chat input
120
*/
121
SUGGEST_COMMAND("suggest_command"),
122
123
/**
124
* Changes book page
125
*/
126
CHANGE_PAGE("change_page"),
127
128
/**
129
* Copies text to clipboard
130
*/
131
COPY_TO_CLIPBOARD("copy_to_clipboard"),
132
133
/**
134
* Executes server-side callback
135
*/
136
CALLBACK("callback");
137
138
/**
139
* Checks if this action is readable by the client
140
* @return true if client can handle this action
141
*/
142
boolean readable();
143
}
144
}
145
```
146
147
**Usage Examples:**
148
149
```java
150
import net.kyori.adventure.text.Component;
151
import net.kyori.adventure.text.event.ClickEvent;
152
import net.kyori.adventure.text.format.NamedTextColor;
153
154
// URL link
155
Component link = Component.text("Visit our website")
156
.color(NamedTextColor.BLUE)
157
.clickEvent(ClickEvent.openUrl("https://example.com"));
158
159
// Command execution
160
Component teleportHome = Component.text("[Home]")
161
.color(NamedTextColor.GREEN)
162
.clickEvent(ClickEvent.runCommand("/home"));
163
164
// Command suggestion
165
Component helpCommand = Component.text("Need help?")
166
.clickEvent(ClickEvent.suggestCommand("/help "));
167
168
// Copy to clipboard
169
Component copyCode = Component.text("Copy Code")
170
.clickEvent(ClickEvent.copyToClipboard("print('Hello World')"));
171
172
// Server-side callback
173
Component callbackButton = Component.text("Click me!")
174
.clickEvent(ClickEvent.callback(audience -> {
175
audience.sendMessage(Component.text("Button clicked!"));
176
}));
177
```
178
179
### Click Callbacks
180
181
Server-side callback interface for handling click events.
182
183
```java { .api }
184
/**
185
* Callback interface for handling click events
186
*/
187
interface ClickCallback<T> {
188
/**
189
* Called when the click event is triggered
190
* @param context the context object (usually Audience)
191
*/
192
void accept(T context);
193
194
/**
195
* Creates a simple callback
196
* @param callback the callback function
197
* @return new click callback
198
*/
199
static <T> ClickCallback<T> of(Consumer<T> callback);
200
}
201
```
202
203
### Hover Events
204
205
Hover events display rich tooltips when users hover over text components.
206
207
```java { .api }
208
/**
209
* Hover event that displays content when text is hovered
210
*/
211
class HoverEvent<V> implements ComponentBuilderApplicable, StyleBuilderApplicable, Examinable {
212
/**
213
* Gets the hover action type
214
* @return the action
215
*/
216
Action<V> action();
217
218
/**
219
* Gets the hover content value
220
* @return the hover content
221
*/
222
V value();
223
224
// Factory methods for common hover types
225
/**
226
* Shows text when hovered
227
* @param text the text to show
228
* @return hover event for showing text
229
*/
230
static HoverEvent<Component> showText(ComponentLike text);
231
232
/**
233
* Shows item information when hovered
234
* @param item the item to show
235
* @return hover event for showing item
236
*/
237
static HoverEvent<ShowItem> showItem(ShowItem item);
238
239
/**
240
* Shows item information from key and count
241
* @param item the item key
242
* @param count the item count
243
* @return hover event for showing item
244
*/
245
static HoverEvent<ShowItem> showItem(Key item, int count);
246
247
/**
248
* Shows entity information when hovered
249
* @param entity the entity to show
250
* @return hover event for showing entity
251
*/
252
static HoverEvent<ShowEntity> showEntity(ShowEntity entity);
253
254
/**
255
* Shows entity information from type and UUID
256
* @param type the entity type
257
* @param id the entity UUID
258
* @return hover event for showing entity
259
*/
260
static HoverEvent<ShowEntity> showEntity(Key type, UUID id);
261
262
/**
263
* Shows entity with custom name
264
* @param type the entity type
265
* @param id the entity UUID
266
* @param name the entity name
267
* @return hover event for showing entity
268
*/
269
static HoverEvent<ShowEntity> showEntity(Key type, UUID id, ComponentLike name);
270
271
/**
272
* Creates a hover event
273
* @param action the action type
274
* @param value the hover content
275
* @return new hover event
276
*/
277
static <V> HoverEvent<V> hoverEvent(Action<V> action, V value);
278
279
/**
280
* Types of hover actions
281
*/
282
interface Action<V> extends Examinable {
283
Action<Component> SHOW_TEXT = Action.of("show_text", Component.class);
284
Action<ShowItem> SHOW_ITEM = Action.of("show_item", ShowItem.class);
285
Action<ShowEntity> SHOW_ENTITY = Action.of("show_entity", ShowEntity.class);
286
287
/**
288
* Gets the action type class
289
* @return the value type
290
*/
291
Class<V> type();
292
293
/**
294
* Checks if this action is readable by the client
295
* @return true if client can handle this action
296
*/
297
boolean readable();
298
299
/**
300
* Creates an action
301
* @param name the action name
302
* @param type the value type
303
* @return new action
304
*/
305
static <V> Action<V> of(String name, Class<V> type);
306
}
307
308
/**
309
* Item information for hover events
310
*/
311
interface ShowItem extends Examinable {
312
/**
313
* Gets the item type key
314
* @return the item type
315
*/
316
Key item();
317
318
/**
319
* Gets the item count
320
* @return the count
321
*/
322
int count();
323
324
/**
325
* Gets the item NBT data
326
* @return the NBT data or null
327
*/
328
@Nullable BinaryTagHolder nbt();
329
330
/**
331
* Sets the item type
332
* @param item the item type
333
* @return new show item with type
334
*/
335
ShowItem item(Key item);
336
337
/**
338
* Sets the item count
339
* @param count the count
340
* @return new show item with count
341
*/
342
ShowItem count(int count);
343
344
/**
345
* Sets the item NBT data
346
* @param nbt the NBT data
347
* @return new show item with NBT
348
*/
349
ShowItem nbt(@Nullable BinaryTagHolder nbt);
350
351
/**
352
* Creates show item data
353
* @param item the item type
354
* @param count the count
355
* @return new show item
356
*/
357
static ShowItem showItem(Key item, int count);
358
359
/**
360
* Creates show item data with NBT
361
* @param item the item type
362
* @param count the count
363
* @param nbt the NBT data
364
* @return new show item
365
*/
366
static ShowItem showItem(Key item, int count, @Nullable BinaryTagHolder nbt);
367
368
/**
369
* Creates builder for show item
370
* @return new builder
371
*/
372
static Builder builder();
373
374
interface Builder extends AbstractBuilder<ShowItem> {
375
Builder item(Key item);
376
Builder count(int count);
377
Builder nbt(@Nullable BinaryTagHolder nbt);
378
}
379
}
380
381
/**
382
* Entity information for hover events
383
*/
384
interface ShowEntity extends Examinable {
385
/**
386
* Gets the entity type key
387
* @return the entity type
388
*/
389
Key type();
390
391
/**
392
* Gets the entity UUID
393
* @return the UUID
394
*/
395
UUID id();
396
397
/**
398
* Gets the entity name
399
* @return the name or null
400
*/
401
@Nullable Component name();
402
403
/**
404
* Sets the entity type
405
* @param type the entity type
406
* @return new show entity with type
407
*/
408
ShowEntity type(Key type);
409
410
/**
411
* Sets the entity UUID
412
* @param id the UUID
413
* @return new show entity with UUID
414
*/
415
ShowEntity id(UUID id);
416
417
/**
418
* Sets the entity name
419
* @param name the name
420
* @return new show entity with name
421
*/
422
ShowEntity name(@Nullable ComponentLike name);
423
424
/**
425
* Creates show entity data
426
* @param type the entity type
427
* @param id the UUID
428
* @return new show entity
429
*/
430
static ShowEntity showEntity(Key type, UUID id);
431
432
/**
433
* Creates show entity data with name
434
* @param type the entity type
435
* @param id the UUID
436
* @param name the name
437
* @return new show entity
438
*/
439
static ShowEntity showEntity(Key type, UUID id, @Nullable ComponentLike name);
440
441
/**
442
* Creates builder for show entity
443
* @return new builder
444
*/
445
static Builder builder();
446
447
interface Builder extends AbstractBuilder<ShowEntity> {
448
Builder type(Key type);
449
Builder id(UUID id);
450
Builder name(@Nullable ComponentLike name);
451
}
452
}
453
}
454
```
455
456
**Usage Examples:**
457
458
```java
459
import net.kyori.adventure.text.event.HoverEvent;
460
import net.kyori.adventure.key.Key;
461
import java.util.UUID;
462
463
// Text tooltip
464
Component tooltip = Component.text("Hover me")
465
.hoverEvent(HoverEvent.showText(
466
Component.text("This appears when you hover!", NamedTextColor.YELLOW)
467
));
468
469
// Complex tooltip with formatting
470
Component complexTooltip = Component.text("Information")
471
.hoverEvent(HoverEvent.showText(
472
Component.text()
473
.append(Component.text("Server: ", NamedTextColor.GRAY))
474
.append(Component.text("Example Server", NamedTextColor.WHITE))
475
.appendNewline()
476
.append(Component.text("Players: ", NamedTextColor.GRAY))
477
.append(Component.text("24/100", NamedTextColor.GREEN))
478
.build()
479
));
480
481
// Item tooltip
482
Component itemDisplay = Component.text("Diamond Sword")
483
.hoverEvent(HoverEvent.showItem(Key.key("minecraft:diamond_sword"), 1));
484
485
// Entity tooltip
486
Component playerName = Component.text("Steve")
487
.hoverEvent(HoverEvent.showEntity(
488
Key.key("minecraft:player"),
489
UUID.randomUUID(),
490
Component.text("Steve the Builder")
491
));
492
```
493
494
### Hover Event Source
495
496
Interface for objects that can be used as hover event sources.
497
498
```java { .api }
499
/**
500
* Objects that can be used as hover event sources
501
*/
502
interface HoverEventSource<V> {
503
/**
504
* Creates a hover event from this object
505
* @return hover event sourced from this object
506
*/
507
@Nullable HoverEvent<V> asHoverEvent();
508
509
/**
510
* Creates a hover event with specific action
511
* @param action the hover action
512
* @return hover event or null if not supported
513
*/
514
@Nullable HoverEvent<V> asHoverEvent(HoverEvent.Action<V> action);
515
}
516
```
517
518
## Data Component System
519
520
### Data Component Values
521
522
Interface for data component values used in modern Minecraft versions.
523
524
```java { .api }
525
/**
526
* Value interface for data components
527
*/
528
interface DataComponentValue extends Examinable {
529
// Marker interface for data component values
530
}
531
532
/**
533
* Registry for data component value converters
534
*/
535
class DataComponentValueConverterRegistry {
536
/**
537
* Converts a data component value to hover event content
538
* @param value the data component value
539
* @return hover event content or null
540
*/
541
@Nullable Object convert(DataComponentValue value);
542
543
/**
544
* Registers a converter for a data component type
545
* @param type the component type
546
* @param converter the converter function
547
*/
548
<T extends DataComponentValue> void register(Class<T> type, Function<T, ?> converter);
549
550
/**
551
* Gets the global converter registry
552
* @return the global registry
553
*/
554
static DataComponentValueConverterRegistry global();
555
}
556
```
557
558
## Event Combination Patterns
559
560
### Click and Hover Together
561
562
```java
563
// Combine click and hover for rich interactivity
564
Component interactiveButton = Component.text("[Click Here]")
565
.color(NamedTextColor.GREEN)
566
.decorate(TextDecoration.BOLD)
567
.clickEvent(ClickEvent.runCommand("/shop"))
568
.hoverEvent(HoverEvent.showText(
569
Component.text("Click to open the shop!", NamedTextColor.YELLOW)
570
));
571
572
// Information with action
573
Component infoWithAction = Component.text("Player123")
574
.color(NamedTextColor.BLUE)
575
.clickEvent(ClickEvent.suggestCommand("/msg Player123 "))
576
.hoverEvent(HoverEvent.showText(
577
Component.text()
578
.append(Component.text("Player123", NamedTextColor.BLUE, TextDecoration.BOLD))
579
.appendNewline()
580
.append(Component.text("Level: 25", NamedTextColor.GREEN))
581
.appendNewline()
582
.append(Component.text("Click to send message", NamedTextColor.GRAY, TextDecoration.ITALIC))
583
.build()
584
));
585
```
586
587
### Conditional Events
588
589
```java
590
// Apply events conditionally
591
Component conditionalComponent = Component.text("Action Button")
592
.colorIf(canClick, NamedTextColor.GREEN, NamedTextColor.GRAY)
593
.applyIf(canClick, component -> component
594
.clickEvent(ClickEvent.runCommand("/action"))
595
.hoverEvent(HoverEvent.showText(Component.text("Click to perform action")))
596
)
597
.applyIf(!canClick, component -> component
598
.hoverEvent(HoverEvent.showText(Component.text("You cannot perform this action", NamedTextColor.RED)))
599
);
600
```
601
602
### Event Builder Patterns
603
604
```java
605
// Helper methods for common event patterns
606
public static ClickEvent commandButton(String command) {
607
return ClickEvent.runCommand("/" + command);
608
}
609
610
public static HoverEvent<Component> tooltip(String text) {
611
return HoverEvent.showText(Component.text(text, NamedTextColor.YELLOW));
612
}
613
614
public static HoverEvent<Component> multilineTooltip(String... lines) {
615
Component.Builder builder = Component.text();
616
for (int i = 0; i < lines.length; i++) {
617
if (i > 0) builder.appendNewline();
618
builder.append(Component.text(lines[i]));
619
}
620
return HoverEvent.showText(builder.build());
621
}
622
623
// Usage
624
Component menuButton = Component.text("[Menu]")
625
.clickEvent(commandButton("menu"))
626
.hoverEvent(multilineTooltip(
627
"Server Menu",
628
"Click to open the main menu"
629
));
630
```
631
632
## Best Practices
633
634
### Security Considerations
635
- Always validate URLs before using them in `ClickEvent.openUrl()`
636
- Sanitize user input when creating dynamic click events
637
- Use server-side callbacks instead of commands when possible for sensitive actions
638
639
### User Experience
640
- Provide clear visual indication for clickable text (color, underline, etc.)
641
- Use informative hover tooltips that explain what will happen when clicked
642
- Keep hover text concise but descriptive
643
- Use consistent styling for similar types of interactive elements
644
645
### Performance
646
- Cache frequently used events rather than creating new instances
647
- Use static factory methods for common event patterns
648
- Consider the client-side impact of complex hover tooltips