Events - ParzivalExe/guiapi GitHub Wiki
Generally, Events are of course handled over the Bukkit-EventHandler and it is therefore not difficult to use these Events, but there are some additions with GuiAPI that are interesting to talk about, so: Lets go
Bukkit-Events
I will demonstrate the BukkitEvent-Implementation by using the EventComponentClickedEvent
but you would use what is shown here with most GuiAPI
Events. So, first we will create a small Gui
to test this on:
Gui eventGui = new Gui("Event-Gui");
ComponentMeta eventMeta = new ComponentMeta("Event", new ItemStack(Material.COMMAND));
EventComponent eventComponent = new EventComponent(eventMeta);
eventGui.setComponent(eventComponent, 4);
eventGui.openGui(player);
Obviously you should create this Gui
through a Command, but I will not explain how to create a new Command in this Tutorial anymore.
Next, you also have to implement Listener
and register this Class as a EventListener so that we are then able to implement BukkitEvents.
@EventHandler
public void eventComponentClicked(EventComponentClickedEvent event) {
//Content
}
Now, that should be familiar to you. But here the problems start, because this Method is now called every time any EventComponent
in any Gui
is clicked, not just the EventComponent(s) in your Gui
we created in this Class. Well, there are several ways to check if the right EventComponent
has been clicked. One of them is to look at the title
of this EventComponent
and the title
of the Gui
if(event.getGui().getTitle().Equals("Event-Gui") && event.getClickedEventComponent().getMeta().getTitle().Equals("Event")) {
//Content
}
But as you can see, this isn't a very good looking and accurate way to test this as this wouldn't work the Moment we changed the title
of either the Gui
or the EventComponent
.
So, let's tackle the Gui
first. Here, there is actually a very good way to check if it's the Gui
right now. We can simply write:
if(event.isGuiOpenedInThisClass()) {
//Content
}
As you might already guess from the name of this Method, this always returns true
if the Gui
that this Event is originating from has been opened in this Class and because we only open one Gui in this class (eventGui for player), we can simply rely on this Method. This would by the way also work for XML-Guis that are opened in this Class and even with Guis that are opened inside the Gui we opened in this Class (for example through a Folder).
There is also a Method isGuiOpenedInClass(Class)
which can be used if the Gui was opened in another class than the EventHandler
s.
When it comes to checking if the Component
is right, there unfortunately isn't a perfect way to check this right now but a good way to at least minimize the risk of title
in creation and event not being the same is to make this title
a variable:
public static final string EVENT_COMPONENT_TITLE = "Event";
Then change the creation of the EventComponent
to
ComponentMeta eventMeta = new ComponentMeta(EVENT_COMPONENT_TITLE, new ItemStack(Material.COMMAND));
EventComponent eventComponent = new EventComponent(eventMeta);
and then add this to the if-statement in EventComponentClickedEvent
if(event.isGuiOpenedInThisClass() && event.getClickedEventComponent().getMeta().getTitle().Equals(EVENT_COMPONENT_TITLE)) {
//Content
}
ComponentClickAction
Now, if we want to simplify this a bit, we must leave Bukkit-Events behind us and use a custom interface from the GuiAPI.
For this we can use the method eventComponent.addClickListener(ComponentClickAction)
. There are two ways to use this Method.
The first one is for the whole class in which case we first have to implement ComponentClickAction
for this class and therefore also add the following method to your class:
@Override
public boolean onClick(Component component, Player whoClicked, Gui gui, InventoryAction action, ClickType clickType) {
//Content
return true;
}
The return must always be true
when you have performed some action and false
if this method has done nothing.
Now we only need to call...
eventComponent.addClickListener(this);
...and it will work.
The second way to implement ComponentClickAction
is for every Component
separately, either directly in the function or through a variable. To implement it directly into the function would look like this:
eventComponent.addClickListener(new ComponentClickAction() {
@Override
public boolean onClick(Component component, Player whoClicked, Gui gui, InventoryAction action, ClickType clickType) {
//Content
return true;
}
});
This is especially useful for very small actions that don't need to be implemented to complicated because they don't take up a lot of space.
If you still want to use a different ComponentClickAction
for different Components but not implement
them at the same position in code where you are also building your inventory (is pretty useful because it keeps UI and Logic separate), you can implement ComponentClickAction
as one or more fields
inside your class:
private ComponentClickAction eventComponentClickAction = new ComponentClickAction() {
@Override
public boolean onClick(Component component, Player player, Gui gui, InventoryAction inventoryAction, ClickType clickType) {
//Content
return true;
}
};
and then add this ComponentClickAction
to your component
like this:
eventComponent.addClickListener(eventComponentClickAction);
Now, that were many different ways to implement ComponentClickAction
. As you can probably see by how much I talked about ComponentClickAction
, in my opinion this is probably the superior way of handling ClickEvents for a Component
as every Component
can easily have it's own Listener
and we don't have to check first, if this is actually the right component
that has thrown this event.
But, if you are already fully invested in the Bukkit-Event System, you have also seen that it is not very difficult to use this System as well.
Resources
BukkitEvent-Classes: io.github.parzivalExe.guiApi.events.*
ClickAction-Interface: io.github.parzivalExe.guiApi.components.ComponentClickAction
For an complete overview about all the events and what they do, you can check out what events are thrown by the different Components by looking at their own chapters under the Events-Section.