Using the Event API - Historical

Applied By Blutkrone: Jan 7, 2021 at 11:30 AM

Using the Event API

Using the Event API


One of the best features of using Spigot is the ability to intercept a wide range of events. This tutorial will demonstrate how to get started on listening to and intercepting events and how to create your own.

1) Creating your First Listener

1.1) Create a new Spigot project
Or use an existing project.
1.2) Create a new class
Name this class whatever you wish, keeping in mind that this class will listen to events.
1.3) Preparing your listener
Listeners must implement the org.bukkit.event.Listener interface. Your listener class should now look like so:
Code (Java):
import org.bukkit.event.Listener;

public class MyListener implements Listener
{

}
1.4) Registering your listener
It is now necessary to register an instance of this class so Spigot is able to pass events to your plugin. A common area to create a new instance of your listener and register it is in your onEnable() method in your main class. Example:
Code (Java):
@Override
public void onEnable()
{
    getServer().getPluginManager().registerEvents(new MyListener(), this);
}
You are now ready to proceed to add events to your listener.
1.5) Listening to events
To listen to any given event in your listener class, you must create a method with the org.bukkit.event.EventHandler annotation attached and the event is specified by the type in the method's argument. The method may be named whatever you wish. Example:
Code (Java):
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public class MyListener implements Listener
{
     @EventHandler
     public void onPlayerJoin(PlayerJoinEvent event)
     {

     }
}
This method will fire whenever a player joins the server. Let's make this broadcast a greeting to the whole server:
Code (Java):
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public class MyListener implements Listener
{
     @EventHandler
     public void onPlayerJoin(PlayerJoinEvent event)
     {
         Bukkit.broadcastMessage("Welcome to the server!");
     }
}
1.6) Manipulating events
You may modify what happens with most events and also obtain information about the given event. These functions are stored in the Event object in your method. Let's modify the message that is broadcasted when a player joins the server:
Code (Java):
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public class MyListener implements Listener
{
     @EventHandler
     public void onPlayerJoin(PlayerJoinEvent event)
     {
         event.setJoinMessage("Welcome, " + event.getPlayer().getName() + "!");
     }
}
1.7) What can I listen to?
Browse through the org.bukkit.event package for a full list of events you can listen to. See the Spigot JavaDocs.

2) Advanced Functions

2.1) EventHandler parameters
The org.bukkit.event.EventHandler annotation accepts a couple parameters.

priority - Indicates the priority of your listener. There are the six different priorities, in order of execution: LOWEST,LOW,NORMAL[default],HIGH,HIGHEST,MONITOR. These constants refer to the org.bukkit.event.EventPriority enum.

Note: The MONITOR priority should only be used for reading only. This priority is useful for logging plugins to see the results of an event and modifying values may interfere with those types of plugins.

ignoreCancelled - A boolean which indicates whether or not your listener should fire if the event has been cancelled before it is the listener's turn to handle the event. False by default.

Example:
Code (Java):
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;

public class MyListener implements Listener
{
     // Executes before the second method because it has a much lower priority.
     @EventHandler (priority = EventPriority.LOWEST)
     public void onPlayerChat1(AsyncPlayerChatEvent event)
     {
         event.setCancelled(true);
     }

     // Will not execute unless another listener with a  lower priority has uncancelled the event.
     @EventHandler (priority = EventPriority.HIGHEST, ignoreCancelled = true)
     public void onPlayerChat2(AsyncPlayerChatEvent event)
     {
         System.out.println("This shouldn't be executing.");
     }
}
2.2) Unregistering a listener
Unfortunately, unregistering a listener isn't as straight-forward as registering, though it is not difficult at all. This is how it is done:
Code (Java):
// import org.bukkit.event.HandlerList
//import (your listener)
HandlerList.unregisterAll(Listener);
3) Creating your own Event
Sometimes you need to create your own Event, one that other plugins can listen to (Vault, among other plugins, does this) and even cancel. Bukkit's Event API also allows this to be possible.

3.1) Creating the Event
Firstly, your class must extend Event:
Code (Java):
import org.bukkit.event.Event;

public class ExampleEvent extends Event {

}
This seems like all you need to do at a first glance, but after running your program you'll get error messages from Spigot. This is because, although not heavily documented, you need to incorporate the following methods into your Event class:
Code (Java):
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;

public class ExampleEvent extends Event {

    private static final HandlerList HANDLERS = new HandlerList();

    @Override
    public HandlerList getHandlers() {
        return HANDLERS;
    }

    public static HandlerList getHandlerList() {
        return HANDLERS;
    }

}
You need these methods because Spigot uses the HandlerList class to separate other EventHandlers from listening to other events.

We can now add some implementation to make our event complete:
Code (Java):
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;

public class ExampleEvent extends Event {

    private final String playerName;

    public ExampleEvent(String playerName) {
        this.playerName = playerName;
    }

    private static final HandlerList HANDLERS = new HandlerList();

    @Override
    public HandlerList getHandlers() {
        return HANDLERS;
    }

    public static HandlerList getHandlerList() {
        return HANDLERS;
    }

    public String getPlayerName() {
        return this.playerName;
    }

}
3.2) Calling and Listening to your Event
Calling your event is relatively easy:
Code (Java):
ExampleEvent exampleEvent = new ExampleEvent("Msrules123"); // Initialize your Event
Bukkit.getPluginManager().callEvent(exampleEvent); // This fires the event and allows any listener to listen to the event
Bukkit.getPlayer("Msrules123").sendMessage(exampleEvent.getPlayerName()); // Use your event's data
And listening to it is the same as any other event:
Code (Java):
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class ExampleListener implements Listener {

   @EventHandler
   public void onExampleEvent(ExampleEvent event) {
       // Handle implementation here
   }

}
3.3) Making your Event cancellable
In order to make your Event cancellable, just implement Cancellable. It's simple:
Code (Java):
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;

public class ExampleEvent extends Event implements Cancellable {

    private final String playerName;
    private boolean isCancelled;

    public ExampleEvent(String playerName) {
        this.playerName = playerName;
        this.isCancelled = false;
    }

    @Override
    public boolean isCancelled() {
        return this.isCancelled;
    }

    @Override
    public void setCancelled(boolean isCancelled) {
        this.isCancelled = isCancelled;
    }

    private static final HandlerList HANDLERS = new HandlerList();

    @Override
    public HandlerList getHandlers() {
        return HANDLERS;
    }

    public static HandlerList getHandlerList() {
        return HANDLERS;
    }

    public String getPlayerName() {
        return this.playerName;
    }

}
Now, instead of directly using your event's data, you would use it after checking whether or not your event was cancelled:
Code (Java):
ExampleEvent exampleEvent = new ExampleEvent("Msrules123"); // Initialize your Event
Bukkit.getPluginManager().callEvent(exampleEvent); // This fires the event and allows any listener to listen to the event
if (!exampleEvent.isCancelled()) {
    Bukkit.getPlayer("Msrules123").sendMessage(exampleEvent.getPlayerName()); // Use your event's data
}