Skip to content
CoolLoong edited this page Jul 6, 2023 · 26 revisions

Languages: Dutch (Nederlands)

GUIs are the main part of the framework and the entry point for every pane and inventory. The GUI is always the top-level part of the inventory. A single GUI has the same characteristics for every player viewing it. E.g. if two players are seeing the same GUI and you change the title of the GUI, both players will get to see the new title. If you want the GUI's behavior to be independent for every player, you'll have to create a new GUI for every player.

Alright, let's see how to create GUIs.

To create a GUI simply create a new ChestGui object. The ChestGui takes in two parameters. The first one is the amount of rows the GUI has and the second one is the title of the GUI.

See how the GUI takes in the amount of rows the GUI has, not the amount of slots. So where as you would previously specify 36 slots, you'd now specify 4 rows.

ChestGui gui = new ChestGui(5, "My GUI");

This will create a GUI with 5 rows and a title saying "My GUI". You can also use Adventure components for the title. To do this, wrap your Component into a ComponentHolder via ComponentHolder.of and pass this as the title of the gui.

While you might want to create other types of guis than a chest, it's recommended to follow this first if you're unfamiliar with this framework. Afterwards you can see how to create different types of guis.

Keep in mind that this is the amount of rows present in the top-half of the inventory, the four rows in the bottom part are not included into the count needed to specify in the constructor parameters.

If you want to change the amount of rows or the title later, you can call setRows and setTitle respectively.

Every method called on a GUI or pane requires you to update the GUI manually.

There are also getters for the amount of rows and the title, getRows and getTitle (resp.).

To show the created gui to a player, you can call Gui#show with the player you want to show the gui to.

gui.show(thePlayer);

If you make any change to any part of the GUI, you'll have to update it. You can do so by calling update on the GUI object to update the GUI for every player that is currently viewing it. Failing to update the gui after making a set of changes may cause the gui to no longer behave correctly.

gui.update();

You can specify what will happen when a player clicks on the GUI and what happens when you close it. You can do so by calling setOnTopClick, setOnBottomClick, setOnGlobalClick and setOnClose. Both take in a Consumer with an InventoryClickEvent and an InventoryCloseEvent respectively.

gui.setOnTopClick(event -> {});
gui.setOnBottomClick(event -> {});
gui.setOnGlobalClick(event -> {});
gui.setOnOutsideClick(event -> {});
gui.setOnClose(event -> {});

Don't use these methods for click events on single items; there are much easier ways of doing this that'll be explained later.

The difference between the different clicks is as follows. Top and bottom will only be called when a player clicks in the top-half/bottom-half of the inventory respectively. Global click will fire as long as you click inside the inventory. Outside click will fire when you clicked outside of the inventory.

The same overall system used for clicks is in place for drag events, which can be defined on gui level. The only exception is that there is not outside drag event, since items cannot be dragged outside of the gui. In case a drag goes both in the top and bottom area of the gui, both events for the top and bottom half will be fired, unlike the clicks where the top or bottom are mutually exclusive.

gui.setOnTopDrag(event -> {});
gui.setOnBottomDrag(event -> {});
gui.setOnGlobalDrag(event -> {});

If you want to for any particular reason, you can also get all the panes, all the items and the inventory itself from the GUI.

Collection<Pane> panes = gui.getPanes();
Collection<GuiItem> items = gui.getItems();
Inventory inventory = gui.getInventory();

XML

If you have an XML file defined for your GUI, you can load it by calling load on the ChestGui class. This takes in two parameters; the class you want to load the GUI into and the input stream pointing to the XML file.

ChestGui gui = ChestGui.load(this, myXMLFile);

You can either specify in the code which type of gui you want (as done here) or specify this in the XML file and then you can load the XML file via Gui.load, on the pages for different types of guis is explained how this can be done.

If you have specified any kind of methods or fields that will be accessed you need to specify the class in which these methods and fields are located. That's what the firsy parameter is for. This will almost always be the class you're in, so if you aren't really sure what to do, just specify this.
The second parameter is the InputStream to your XML file. There is a built-in method in Bukkit for getting this, namely

InputStream inputStream = plugin.getResource("gui.xml");

Where plugin, is your main plugin object and the "gui.xml" the name of your XML file.

To create a base GUI in an XML file add the following element to the file.

<gui/>

As attributes you are required to have a rows and title attribute. The rows attribute specifies the amount of rows the GUI will have and the title attribute specifies the title of the GUI.

<gui rows="5" title="My GUI"/>

Optional attributes

field attribute

You can specify several optional attributes to the GUI element. The first one is field. With field you can specify a field name in your code which should be initialized with the GUI once it is loading.

In the XML file:

<gui rows="5" title="My GUI" field="gui"/>

In the code:

ChestGui gui; //this field will get initialized with the gui

onTopClick attribute

You can also specify an onTopClick attribute. Here you can specify the method name of the method that will be called once someone has clicked on the top-half of the GUI.

In the XML file:

<gui rows="5" title="My GUI" onTopClick="guiClick"/>

In the code:

public void guiClick(InventoryClickEvent event) {}

The method specified needs to be public. The InventoryClickEvent parameter is optional.
You may set any return type you want, but the result will be ignored in all cases.

onBottomClick attribute

You can also specify an onBottomClick attribute. Here you can specify the method name of the method that will be called once someone has clicked on the bottom-half of the GUI.

In the XML file:

<gui rows="5" title="My GUI" onBottomClick="guiClick"/>

In the code:

public void guiClick(InventoryClickEvent event) {}

The method specified needs to be public. The InventoryClickEvent parameter is optional.
You may set any return type you want, but the result will be ignored in all cases.

onGlobalClick attribute

This attribute specifies a method name for a method that should get called when someone clicks in either the top or bottom half of the Gui.

In the XML file:

<gui rows="5" title="My GUI" onGlobalClick="guiClick"/>

In the code:

public void guiClick(InventoryClickEvent event) {}

The method specified needs to be public. The InventoryClickEvent parameter is optional.
You may set any return type you want, but the result will be ignored in all cases.

onOutsideClick attribute

This attribute specifies a method name for a method that should get called when someone clicks outside of the Gui.

In the XML file:

<gui rows="5" title="My GUI" onOutsideClick="guiClick"/>

In the code:

public void guiClick(InventoryClickEvent event) {}

The method specified needs to be public. The InventoryClickEvent parameter is optional.
You may set any return type you want, but the result will be ignored in all cases.

onClose attribute

You can specify an onClose attribute. Here you specify the method name of the method that will be called once someone has closed the GUI.

In the XML file:

<gui rows="5" title="My GUI" onClose="guiClose"/>

In the code:

public void guiClose(InventoryCloseEvent event) {}

The method specified needs to be public. The InventoryCloseEvent parameter is optional.
You may set any return type you want, but the result will be ignored in all cases.

populate attribute

You can specify a populate attribute. Here you specify the method name of the method that will take over the population of the GUI when loading. Any child elements appended to the GUI element will be ignored when this attribute is set.

In the XML file:

<gui rows="5" title="My GUI" populate="populateGui"/>

In the code:

public void populateGui(Gui gui) {}

You may set any return type you want, but the result will be ignored in all cases.

Clone this wiki locally