Skip to content

FancyText

Petrus Pradella edited this page Jul 23, 2026 · 2 revisions

FancyText

What this page covers: FancyText and FancyFormatter, the rich-text builders behind every message EverNifeCore sends. A FancyText is one styled segment (text + optional hover tooltip + optional click action); a FancyFormatter is a chain of segments. Both render to an Adventure Component, so hover and click work across supported Minecraft versions (and on Hytale). A resolved Localization message is a FancyText.


The 30-second version

import br.com.finalcraft.evernifecore.fancytext.FancyText;

// One styled segment with a hover tooltip and a click-to-run-command action.
FancyText.of("&aClick me")
        .setHoverText("&7Runs /spawn for you")
        .setRunCommandAction("/spawn")
        .send(player);
// A multi-segment line (FancyFormatter) - each .append(...) adds a segment.
FancyText.of("&7Player: &f" + name)
        .append(" &e[teleport]")
            .setHoverText("&7Teleport to " + name)
            .setRunCommandAction("/tp " + name)
        .append(" &c[kick]")
            .setHoverText("&7Kick " + name)
            .setSuggestCommandAction("/kick " + name + " ")
        .send(sender);

send(FCommandSender...) renders and sends; broadcast() sends to every online player.


Building a FancyText

Create one with the constructor or the of(...) factories:

FancyText a = new FancyText("&aHello");
FancyText b = FancyText.of("&aHello");                              // same thing
FancyText c = FancyText.of("&aHello", "&7a hover tooltip");         // text + hover
FancyText d = FancyText.of("&aClick", "&7hover", "/spawn");         // text + hover + run-command

Then refine it fluently (every setter returns the FancyText):

Method Effect
setText(String) Replace the segment text.
setHoverText(String) Set the hover tooltip.
setHoverText(List<String>) Multi-line hover (joined with newlines).
setHoverItem(String) Show a serialized item as the hover tooltip (see below).
setRunCommandAction(String) Click runs the given command.
setSuggestCommandAction(String) Click puts the text in the chat box.
setOpenLinkAction(String) Click opens a URL.
setClickAction(String, ClickActionType) Set click text + type explicitly.
replace(String, String) Literal placeholder replace across text/hover/click.
replace(CompoundReplacer) Apply a Placeholders replacer.

ClickActionType is one of RUN_COMMAND, SUGGEST_COMMAND, OPEN_URL, NONE.

Color codes use & or §. A trailing color on one segment carries into the next segment (see Color bleed).


Hover and click

Hover and click are independent - a segment can have either, both, or neither.

FancyText.of("&e[Confirm]")
        .setHoverText("&aClick to confirm the trade")
        .setRunCommandAction("/trade confirm")
        .send(player);

// Multi-line hover:
FancyText.of("&6" + item.getName())
        .setHoverText(Arrays.asList("&7Rarity: &bEpic", "&7Value: &a1200"))
        .send(player);

Because a hover/click lives on a single FancyText, in a FancyFormatter chain the setter always targets the segment you just appended:

FancyText.of("&7Status: &aOnline")   // segment 1 - no hover
        .append(" &e(?)")            // segment 2
            .setHoverText("&7Last seen just now"); // hover attaches to segment 2 only

Item hover

setHoverItem(serializedItem) renders the tooltip as an actual item (via Adventure's show-item hover). It expects the item's serialized form (its material key + NBT). This is a lower-level hook; most plugins use plain text hovers.

fancyText.setHoverItem(serializedItem); // tooltip renders as the item, not text

FancyFormatter - multiple segments

Calling .append(...) on a FancyText promotes it to a FancyFormatter (the original becomes the first segment) and returns that formatter, so you can keep chaining. You can also build one directly:

import br.com.finalcraft.evernifecore.fancytext.FancyFormatter;

FancyFormatter formatter = FancyFormatter.of("&6=== Menu ===");
formatter.append("\n&e- option A").setHoverText("&7pick A").setRunCommandAction("/pick A");
formatter.append("\n&e- option B").setHoverText("&7pick B").setRunCommandAction("/pick B");
formatter.send(sender);

append accepts a String, a (text, hover) / (text, hover, runCommand) tuple, or a whole FancyText/FancyFormatter (nested formatters are flattened, segment by segment).

Color bleed between segments

In legacy chat a color code bleeds into the text that follows it; Adventure components, by contrast, do not inherit a sibling's color. FancyFormatter bridges the two: it carries each segment's trailing color into the next segment as its starting color, so "&aHello " followed by "World" renders World in green, exactly as a legacy string would. You don't configure anything - it's how segments are joined.


Placeholders in FancyText

FancyFormatter can hold placeholders resolved at send time:

FancyText.of("&7# %number%: &a %value% &7(%version%)")
        .setHoverText("%plugin_info%")
        .send(sender);
  • addPlaceholder(String token, Object value) - a static value substituted literally.
  • addPlaceholder(String token, Function<PlayerData, Object>) - a per-recipient value computed from the receiving player's data.

For the regex-based placeholder engine and PlaceholderAPI bridging (feeding %papi% placeholders into a message), see Placeholders and replace(CompoundReplacer).


Sending

fancyText.send(sender);                 // send to one or more FCommandSender
fancyText.send(playerA, playerB);       // varargs
fancyText.broadcast();                  // every online player

send/broadcast render the FancyText to an Adventure Component (cached until the text changes) and dispatch it through the platform's chat adapter, so the same code works on Bukkit and Hytale.

📌 Note - a resolved LocaleMessage is a FancyText under the hood, so everything here applies to localized messages too. Prefer declaring player-facing text as @FCLocale messages (Localization) and reserve raw FancyText for text you build dynamically (menus, lists, confirmation buttons).


See also

  • Localization - @FCLocale/LocaleMessage, which produce FancyText; the recommended way to declare messages.
  • Placeholders - Replacer/RegexReplacer/CompoundReplacer and replace(CompoundReplacer), PlaceholderAPI bridging.
  • Command Framework - building clickable menus and lists inside a command.

Clone this wiki locally