Skip to content
stefvanschie edited this page Feb 5, 2019 · 26 revisions

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 Gui object. The Gui takes in three parameters. The first one is the main class of your plugin. The second one is the amount of rows the GUI has and the third 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.

Gui gui = new Gui(plugin, 5, "My GUI");

This will create a GUI with 5 rows and a title saying "My GUI".

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. These two methods are an exception however. Due to technical reasons, these two methods will cause an update by themselves. If possible, call these methods last in a chain as you don't have to update the GUI again.

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

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.

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.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 always fire regardless of the pane in which you click.

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 Gui class. This takes in three parameters; the main plugin class, the class you want to load the GUI into and the input stream pointing to the XML file.

Gui gui = Gui.load(plugin, this, myXMLFile);

Alright, so the plugin is self-explanatory, just the main class of your plugin.
The second parameter is a little different though. 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 second 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 third 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:

Gui 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 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 InventoryClickEvent parameter is optional.
You may set any return type you want, but the result will be ignored in all cases.

onGlobalClick attribute

This is similar to the onLocalClick attribute, but now the method will only get called when someone clicks in the bottom half of the Gui (the player inventory and the hotbar).

In the XML file:

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

In the code:

public void guiClick(InventoryClickEvent event) {}

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 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