Text Holograms
Creating and managing text display holograms
This documentation is for FancyHolograms v3. For v2, see Text Holograms v2.
Text holograms display formatted text in the world. They support multiple lines, colors, MiniMessage formatting, and PlaceholderAPI placeholders.
Creating a text hologram
Using the builder
The recommended way to create text holograms is using the TextHologramBuilder:
import de.oliver.fancyholograms.api.data.TextHologramData;
import de.oliver.fancyholograms.api.data.builder.TextHologramBuilder;
import de.oliver.fancyholograms.api.hologram.Hologram;
import de.oliver.fancyholograms.api.FancyHolograms;
import org.bukkit.Location;
Location location = new Location(world, 100, 64, 200);
TextHologramData data = TextHologramBuilder.create("my_hologram", location)
.text("<rainbow>Rainbow Text</rainbow>", "<gold>Second Line</gold>")
.background("#80000000") // Semi-transparent black
.textAlignment(TextDisplay.TextAlignment.CENTER)
.textShadow(true)
.persistent(true)
.build();
Hologram hologram = FancyHolograms.get().getHologramManager().create(data);
FancyHolograms.get().getHologramRegistry().register(hologram);Direct instantiation
You can also create TextHologramData directly:
import de.oliver.fancyholograms.api.data.TextHologramData;
import java.awt.Color;
import java.util.Arrays;
TextHologramData data = new TextHologramData("my_hologram", location);
data.setText(Arrays.asList(
"<gradient:red:blue>Gradient Text</gradient>",
"<gold>Golden Line</gold>"
));
data.setBackground(new Color(0, 0, 0, 128)); // RGBA
data.setTextShadow(true);Text properties
Setting text lines
import java.util.List;
// Set all lines at once
data.setText(List.of("Line 1", "Line 2", "Line 3"));
// Add a line
data.addLine("<green>New line</green>");
// Set a specific line (0-indexed)
data.setLine(0, "<red>First line updated</red>");
// Remove a line
data.removeLine(1);
// Clear all text
data.clearText();
// Get current text
List<String> lines = data.getText();Text formatting
FancyHolograms supports MiniMessage formatting:
// Colors
data.setText("<red>Red text</red>");
data.setText("<#FF5555>Hex color</hex>");
// Gradients
data.setText("<gradient:red:blue>Gradient</gradient>");
// Rainbow
data.setText("<rainbow>Rainbow text!</rainbow>");
// Bold, italic, underline, strikethrough
data.setText("<bold>Bold</bold>");
data.setText("<italic>Italic</italic>");
data.setText("<underline>Underlined</underline>");
data.setText("<strikethrough>Strikethrough</strikethrough>");
// Combined
data.setText("<bold><gradient:gold:yellow>Fancy!</gradient></bold>");Text alignment
Control how multi-line text is aligned:
import org.bukkit.entity.TextDisplay;
// Center aligned (default)
data.setTextAlignment(TextDisplay.TextAlignment.CENTER);
// Left aligned
data.setTextAlignment(TextDisplay.TextAlignment.LEFT);
// Right aligned
data.setTextAlignment(TextDisplay.TextAlignment.RIGHT);
// Get current alignment
TextDisplay.TextAlignment alignment = data.getTextAlignment();Text shadow
Enable or disable text shadow for better readability:
// Enable shadow
data.setTextShadow(true);
// Disable shadow
data.setTextShadow(false);
// Check if enabled
boolean hasShadow = data.hasTextShadow();See-through text
Make text visible through blocks:
// Enable see-through
data.setSeeThrough(true);
// Disable see-through
data.setSeeThrough(false);
// Check if enabled
boolean seeThrough = data.isSeeThrough();Background
Set a background color behind the text:
import java.awt.Color;
// Solid black background
data.setBackground(Color.BLACK);
// Semi-transparent background (RGBA)
data.setBackground(new Color(0, 0, 0, 128)); // 50% opacity
// Fully transparent (no background)
data.setBackground(new Color(0, 0, 0, 0));
// From hex string with alpha
data.setBackground("#80000000"); // Semi-transparent black
// Get current background
Color bg = data.getBackground();Dynamic text updates
Make text update automatically to show live data:
import de.oliver.fancynpcs.api.utils.Interval;
// Update every second (20 ticks)
data.setTextUpdateInterval(20);
// Update every 5 seconds
data.setTextUpdateInterval(100);
// Disable automatic updates
data.setTextUpdateInterval(-1);
// Get current interval
int interval = data.getTextUpdateInterval();Use dynamic updates with PlaceholderAPI placeholders to show live information like player count, time, etc.
PlaceholderAPI integration
If PlaceholderAPI is installed, you can use placeholders in your text:
// Player count
data.setText("<gold>Players: %server_online%</gold>");
// Server TPS
data.setText("<green>TPS: %server_tps%</green>");
// Custom placeholders from other plugins
data.setText("<aqua>Balance: %vault_eco_balance%</aqua>");
// Multiple placeholders
data.setText(List.of(
"<gradient:gold:yellow>Server Stats</gradient>",
"<white>Players: %server_online%/%server_max_players%</white>",
"<white>TPS: %server_tps%</white>"
));
// Enable dynamic updates to refresh placeholders
data.setTextUpdateInterval(20); // Update every secondComplete example: Server info hologram
import de.oliver.fancyholograms.api.FancyHolograms;
import de.oliver.fancyholograms.api.data.builder.TextHologramBuilder;
import org.bukkit.Location;
import org.bukkit.entity.TextDisplay;
import java.awt.Color;
public class ServerInfoHologram {
public void create(Location location) {
TextHologramData data = TextHologramBuilder.create("server_info", location)
.text(
"<gradient:gold:yellow><bold>SERVER INFO</bold></gradient>",
"",
"<white>Players: <green>%server_online%/%server_max_players%</green></white>",
"<white>TPS: <green>%server_tps%</green></white>",
"<white>Uptime: <aqua>%server_uptime%</aqua></white>"
)
.background(new Color(0, 0, 0, 180)) // Dark semi-transparent
.textAlignment(TextDisplay.TextAlignment.CENTER)
.textShadow(true)
.textUpdateInterval(20) // Update every second
.scale(1.5f) // Make it larger
.billboard(Display.Billboard.CENTER) // Always face player
.visibilityDistance(50)
.persistent(true)
.build();
Hologram hologram = FancyHolograms.get().getHologramManager().create(data);
FancyHolograms.get().getHologramRegistry().register(hologram);
}
}Example: Welcome hologram
public class WelcomeHologram {
public void create(Location spawnLocation) {
TextHologramData data = TextHologramBuilder.create("welcome", spawnLocation)
.text(
"<rainbow><bold>WELCOME</bold></rainbow>",
"",
"<gray>to our server!</gray>",
"",
"<gold>Type /help for assistance</gold>"
)
.background("#40000000") // Subtle background
.textAlignment(TextDisplay.TextAlignment.CENTER)
.textShadow(true)
.scale(2.0f) // Double size
.billboard(Display.Billboard.CENTER)
.glowColor(ChatColor.YELLOW)
.persistent(true)
.build();
Hologram hologram = FancyHolograms.get().getHologramManager().create(data);
FancyHolograms.get().getHologramRegistry().register(hologram);
}
}Example: Player-specific text
Create holograms that show different text to different players using PlaceholderAPI:
public class PersonalizedHologram {
public void create(Location location) {
TextHologramData data = TextHologramBuilder.create("personal", location)
.text(
"<gold>Hello, %player_name%!</gold>",
"",
"<gray>Balance: <green>$%vault_eco_balance%</green></gray>",
"<gray>Rank: <aqua>%luckperms_primary_group_name%</aqua></gray>"
)
.textUpdateInterval(40) // Update every 2 seconds
.background(new Color(0, 0, 0, 150))
.textShadow(true)
.build();
Hologram hologram = FancyHolograms.get().getHologramManager().create(data);
FancyHolograms.get().getHologramRegistry().register(hologram);
}
}Updating text holograms
Update text content
Hologram hologram = FancyHolograms.get().getHologramRegistry()
.get("my_hologram").orElse(null);
if (hologram != null && hologram.getData() instanceof TextHologramData textData) {
// Update text
textData.setText(List.of("<red>Updated!</red>", "<blue>New content</blue>"));
// Refresh for all viewers
FancyHolograms.get().getHologramController().refreshHologram(hologram);
}Add line to existing hologram
if (hologram.getData() instanceof TextHologramData textData) {
textData.addLine("<green>New line added</green>");
FancyHolograms.get().getHologramController().refreshHologram(hologram);
}