Create a sub command
This example shows how to create a sub command and attach it to a base command.
Sub commands extend the functionality of a parent command and allow structuring more complex command systems.
→ Deep dive: [[Commands|Core-API/Command-&-Interaction/Commands]]
Steps
- Create a class extending
PixelSubCommand - Add
@CommandDefinition(label + usage) - Implement
onPlayerCommand - Attach the sub command to a parent command
- Register the parent command
Implementation
package net.mixelpixel.example.bukkit.command;
import net.mixelpixel.core.api.command.CommandDefinition;
import net.mixelpixel.core.bukkit.api.BukkitCoreLibrary;
import net.mixelpixel.core.bukkit.api.command.PixelSubCommand;
import net.mixelpixel.core.bukkit.api.inventory.ConfirmContent;
import net.mixelpixel.core.bukkit.api.inventory.ConfirmContentBuilder;
import net.mixelpixel.core.bukkit.api.inventory.InventoryHandler;
import net.mixelpixel.core.bukkit.api.player.BukkitPixelPlayer;
import net.mixelpixel.core.bukkit.api.player.PlayerHandler;
import net.mixelpixel.core.bukkit.api.util.item.ItemBuilder;
import net.mixelpixel.example.bukkit.ExamplePlugin;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jspecify.annotations.NonNull;
import java.util.Collection;
/**
* Example: Sub Command
* Shows how to create a sub command.
*/
public class ClearInventoryCommand extends PixelSubCommand<ExamplePlugin, ClearCommand> {
@CommandDefinition(
label = "inventory",
usage = "<Player>"
)
public ClearInventoryCommand(@NonNull ClearCommand parent) {
super(parent);
}
@Override
public void onPlayerCommand(BukkitPixelPlayer player, String label, String[] args) {
if (args.length > 1) {
String playerUsage = getPlayerUsage();
player.sendMessage(playerUsage);
return;
}
if (args.length == 0) {
ConfirmContent confirmContent = ConfirmContentBuilder.create(createMiddleItem()).build();
InventoryHandler inventoryHandler = BukkitCoreLibrary.getInventoryHandler();
inventoryHandler.openConfirmInventory(
player,
" <red><i>Clear inventory?</i></red>",
confirmContent,
clear -> {
if (clear != null && clear) clear(player, player);
}
);
return;
}
PlayerHandler playerHandler = BukkitCoreLibrary.getPlayerHandler();
BukkitPixelPlayer target = playerHandler.getPlayer(args[0]);
if (target == null) {
player.sendMessage(PLAYER_IS_NOT_ONLINE);
return;
}
if (target.equals(player)) {
onPlayerCommand(player, label, new String[0]);
return;
}
ConfirmContent confirmContent = ConfirmContentBuilder.create(createMiddleItem()).build();
String coloredTargetName = target.getColoredName();
InventoryHandler inventoryHandler = BukkitCoreLibrary.getInventoryHandler();
inventoryHandler.openConfirmInventory(
player,
"Clear " + coloredTargetName + "'s Inventory?",
confirmContent,
clear -> {
if (clear != null && clear) clear(player, target);
}
);
}
private @NotNull ItemStack createMiddleItem() {
return ItemBuilder.material(Material.LAVA_BUCKET)
.name("<red>Clear inventory</red>")
.build();
}
private void clear(@NotNull BukkitPixelPlayer player, @NotNull BukkitPixelPlayer target) {
target.playSound(Sound.BLOCK_ANVIL_FALL);
target.clearInventory();
if (player.equals(target)) {
player.sendActionBar("<green>You've cleared your inventory.</green>");
return;
}
player.sendMessage(
"<green>Successfully cleared the inventory of</green> " + target.getColoredName()
);
target.sendMessage(
"<red>Your inventory got cleared by</red> " + player.getColoredName()
);
}
@Override
public Collection<String> onPlayerTabComplete(BukkitPixelPlayer player, String label, String[] args) {
if (args.length != 1) return null;
PlayerHandler playerHandler = BukkitCoreLibrary.getPlayerHandler();
return playerHandler.getOnlinePlayersNames(player);
}
}
Registering the sub command
Sub commands are attached to the parent command before registering it:
CommandHandler commandHandler = BukkitCoreLibrary.getCommandHandler();
ClearCommand clearCommand = new ClearCommand(plugin);
// attach sub command to parent
new ClearInventoryCommand(clearCommand);
// register parent (includes all sub commands)
commandHandler.registerCommand(clearCommand);
Explanation
PixelSubCommandextends a parent command- The constructor receives the parent command instance
- Sub commands are automatically registered when created
usagedefines the expected argumentsgetPlayerUsage()generates a usage message- Tab completion is handled via
onPlayerTabComplete(...)
Notes
- Sub commands help structuring commands into smaller units
- They are always attached to a parent command
- The parent command handles execution routing
Next step
[[Create an event & listener|Core-API/Build-your-first-feature/Start-Here/Create-an-event-&-listener]]