• Es freut uns dass du in unser Minecraft Forum gefunden hast. Hier kannst du mit über 130.000 Minecraft Fans über Minecraft diskutieren, Fragen stellen und anderen helfen. In diesem Minecraft Forum kannst du auch nach Teammitgliedern, Administratoren, Moderatoren , Supporter oder Sponsoren suchen. Gerne kannst du im Offtopic Bereich unseres Minecraft Forums auch über nicht Minecraft spezifische Themen reden. Wir hoffen dir gefällt es in unserem Minecraft Forum!

Wie man GUIs erstellt

alex9849

Redstoneengineer
Mitglied seit
20 Juni 2012
Beiträge
35
Hey :)
Ich verstehe nicht warum so wenige Plugins GUIs (bzw. CUI (chest user interface)) benutzen. GUIs sind gerade für Spieler, welche sich nicht mit den Befehlen eines Servers auseinandersetzen wollen eine extreme Erleichterung. Dabei ist es überhaupt nicht schwer eine gute, ansprechende GUI zu programmieren.
Ich dachte ich mach mal den Anfang und erstelle ein kleines Tutorial, wie man eine vor allem flexibele GUI programmieren kann.

Zu aller erst brauchen wir ein Inventar, welches unsere Anforderungen erfüllt. Dh. es muss Icons beinhalten, die Code ausführen können wenn man darauf klickt. Dafür gibt es von Bukkit schon eine Klasse von der wird erben können.
Ich habe dafür schonmal etwas zusammengeschrieben:

Code:
import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;

public class GuiInventory implements InventoryHolder {

    private final ClickItem[] icons;

    private int size;
    private final String title;

    public GuiInventory(int size, String title) {
        this.size = size;
        this.title = title;
        this.icons = new ClickItem[this.size];
    }

    public void addIcon(ClickItem icon, int position) {
        this.icons[position] = icon;
    }

    public ClickItem getIcon(int position) {
        return this.icons[position];
    }

    public void setSize(int size){
        this.size = size;
    }

    @Override
    public Inventory getInventory() {

        Inventory inventory = Bukkit.createInventory(this, this.size, this.title);

        for (int i = 0; i < this.icons.length; i++) {
            if(this.icons[i] == null) {
                inventory.setItem(i, null);
            } else {
                inventory.setItem(i, this.icons[i].getItemStack());
            }

        }

        return inventory;
    }
}
In dem obigen Codeblock gibt es ein Array mit ClickItems. Diese ClickItems sind Items, welche noch eine ClickAction verlinkt haben. Also Items sind, welche etwas tun, wenn man drauf drückt.

Code:
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import java.util.ArrayList;
import java.util.List;

public class ClickItem extends ItemStack {


    private final ItemStack itemStack;

    private final List<ClickAction> clickActions = new ArrayList<>();

    public ClickItem(ItemStack itemStack) {
        this.itemStack = itemStack;
    }

    public ClickItem(ItemStack itemStack, String name, List<String> lore) {
        ItemMeta itemMeta = itemStack.getItemMeta();
        itemMeta.setDisplayName(name);
        itemMeta.setLore(lore);
        itemStack.setItemMeta(itemMeta);
        this.itemStack = itemStack;
    }

    public ClickItem(ItemStack itemStack, String name) {
        ItemMeta itemMeta = itemStack.getItemMeta();
        itemMeta.setDisplayName(name);
        itemStack.setItemMeta(itemMeta);
        this.itemStack = itemStack;
    }

    public ClickItem addClickAction(ClickAction clickAction) {
        this.clickActions.add(clickAction);
        return this;
    }

    public List<ClickAction> getClickActions() {
        return this.clickActions;
    }

    public ItemStack getItemStack() {
        return this.itemStack;
    }

}
Um jetzt noch ClickItems hinzuzufügen brauchen wir nur noch ein Interface

Code:
import org.bukkit.entity.Player;

public interface ClickAction {

    void execute(Player player);

}
Soweit so gut. Die obigen 3 Klassen reichen eigentlich schon aus um die GUIs zu erstellen. Jetzt müssen wir nur noch irgendwie erkennen, dass ein Spieler irgendwo drauf gedrückt hat. Dafür brauchen wir einen Listener:

Code:
    @EventHandler
    public void onClick(InventoryClickEvent event) {
        if (event.getView().getTopInventory().getHolder() instanceof GuiInventory) {
            event.setCancelled(true);

            if (event.getWhoClicked() instanceof Player) {
                Player player = (Player) event.getWhoClicked();

                ItemStack itemStack = event.getCurrentItem();
                if (itemStack == null || itemStack.getType() == Material.AIR) {
                    return;
                }

                GuiInventory customHolder = (GuiInventory) event.getView().getTopInventory().getHolder();

                ClickItem icon = customHolder.getIcon(event.getRawSlot());
                if (icon == null) return;

                for (ClickAction clickAction : icon.getClickActions()) {
                    clickAction.execute(player);
                }
            }
        }
    }
Das wars eigentlich. Ich hab hier jetzt noch ein Beispiel, wie man die Klassen einsetzten könnte. Zum Beispiel könnte man eine unendliche Liste aus ClickItems erstellen, und den User sich dort durchklicken lassen.

Code:
    public static void openInfiniteGuiList(Player player, List<ClickItem> clickItems, int startitem, String name, ClickAction gobackAction) {

        int invsize = 0;
        int itemsize = 0;

        while (((clickItems.size() - startitem) > itemsize) && (itemsize < 45)) {
            itemsize = itemsize + 9;
        }
        invsize = itemsize;
        if(((gobackAction != null) && (clickItems.size() >= 9)) || ((startitem + 45) < (clickItems.size() - 1)) || (startitem != 0) || (itemsize == 0)) {
            invsize = itemsize + 9;
        }

        GuiInventory inv = new GuiInventory(invsize, name);

        int pos = 0;
        for(int i = startitem; ((i < startitem + itemsize) && (i < clickItems.size())); i++) {
            inv.addIcon(clickItems.get(i), pos);
            pos++;
        }
        if(startitem != 0) {
            int newStartItem = startitem - 45;
            if(newStartItem < 0) {
                newStartItem = 0;
            }
            //TODO Make item and text changeable
            final int finalnewStartItem = newStartItem;
            ClickItem prevPageButton = new ClickItem(new ItemStack(Material.ARROW), "prev Page").addClickAction(new ClickAction() {
                @Override
                public void execute(Player player) {
                    Gui.openInfiniteGuiList(player, clickItems, finalnewStartItem, name, gobackAction);
                }
            });
            inv.addIcon(prevPageButton, invsize - 9);
        }
        if((startitem + 45) < (clickItems.size() - 1)) {
            //TODO Make item and text changeable
            int newStartItem = startitem + 45;
            ClickItem nextPageButton = new ClickItem(new ItemStack(Material.ARROW), "next Page").addClickAction(new ClickAction() {
                @Override
                public void execute(Player player) {
                    Gui.openInfiniteGuiList(player, clickItems, newStartItem, name, gobackAction);
                }
            });
            inv.addIcon(nextPageButton, invsize - 1);
        }
        if(gobackAction != null) {
            ClickItem gobackButton = new ClickItem(new ItemStack(Gui.GO_BACK_ITEM), Messages.GUI_GO_BACK).addClickAction(gobackAction);
            if(clickItems.size() >= 9) {
                inv.addIcon(gobackButton, invsize - 5);
            } else {
                inv.addIcon(gobackButton, 8);
            }

        }

        player.openInventory(inv.getInventory());
    }
Da wars auch schon. Ich hoffe ihr könnt mit dem Tutorial etwas anfangen.

MfG

alex9849
 
Zuletzt bearbeitet:
Allgemein
Hilfe Benutzer
    HardSoul HardSoul: Guten Morgen Milchstraße
    Oben