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

Icon Menu

squiby

Minecrafter
Registriert
23 November 2012
Beiträge
8
Diamanten
0
Problem: IconMenu.OptionClickEvent wird pro Klick 2x gecalled. Das Problem liegt irgendwo in der API, nur meldet sich deren Entwickler nicht, weshalb ich hier nochmal nachfrage.

Hier die benutzte API:
Code:
public class IconMenu implements Listener {
    private String name;
    private int size;
    private OptionClickEventHandler handler;
    private Plugin plugin;
 
    private String[] optionNames;
    private ItemStack[] optionIcons;
 
    public IconMenu(String name, int size, OptionClickEventHandler handler, Plugin plugin) {
        this.name = name;
        this.size = size;
        this.handler = handler;
        this.plugin = plugin;
        this.optionNames = new String[size];
        this.optionIcons = new ItemStack[size];
        plugin.getServer().getPluginManager().registerEvents(this, plugin);
    }
 
    public IconMenu setOption(int position, ItemStack icon, String name, String... info) {
        optionNames[position] = name;
        optionIcons[position] = setItemNameAndLore(icon, name, info);
        return this;
    }
 
    public void open(Player player) throws Exception {
        Inventory inventory = Bukkit.createInventory(player, size, name);
        if (optionIcons == null)
        	throw new Exception("Null!");
        
        for (int i = 0; i < optionIcons.length; i++) {
           inventory.setItem(i, optionIcons[i]);           
        }
        player.openInventory(inventory);
    }
 
    public void destroy() {
        HandlerList.unregisterAll(this);
        handler = null;
        plugin = null;
        optionNames = null;
        optionIcons = null;
    }
 
    @EventHandler(priority = EventPriority.MONITOR)
    void onInventoryClick(InventoryClickEvent event) {
        if (event.getInventory().getTitle().equals(name)) {
            event.setCancelled(true);
            int slot = event.getRawSlot();
            if (slot >= 0 && slot < size && optionNames[slot] != null) {
                Plugin plugin = this.plugin;
                OptionClickEvent e = new OptionClickEvent((Player) event.getWhoClicked(), slot, optionNames[slot]);
                handler.onOptionClick(e);
                if (e.willClose()) {
                    final Player p = (Player) event.getWhoClicked();
                    Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
                        public void run() {
                            p.closeInventory();
                        }
                    }, 1);
                }
                if (e.willDestroy()) {
                    destroy();
                }
            }
        }
    }
 
    public interface OptionClickEventHandler {
        public void onOptionClick(OptionClickEvent event);
    }
 
    public class OptionClickEvent {
        private Player player;
        private int position;
        private String name;
        private boolean close;
        private boolean destroy;
 
        public OptionClickEvent(Player player, int position, String name) {
            this.player = player;
            this.position = position;
            this.name = name;
            this.close = true;
            this.destroy = false;
        }
 
        public Player getPlayer() {
            return player;
        }
 
        public int getPosition() {
            return position;
        }
 
        public String getName() {
            return name;
        }
 
        public boolean willClose() {
            return close;
        }
 
        public boolean willDestroy() {
            return destroy;
        }
 
        public void setWillClose(boolean close) {
            this.close = close;
        }
 
        public void setWillDestroy(boolean destroy) {
            this.destroy = destroy;
        }
    }
 
    private ItemStack setItemNameAndLore(ItemStack item, String name, String[] lore) {
        ItemMeta im = item.getItemMeta();
        im.setDisplayName(name);
        im.setLore(Arrays.asList(lore));
        item.setItemMeta(im);
        return item;
    }
   
}

Hier das Objekt in der Main:

Code:
	private IconMenu CreateIconMenu()
	{
        IconMenu menu = new IconMenu("Navi", 9, new IconMenu.OptionClickEventHandler() {
            @Override

           //Dieser Part wird 2x ausgeführt!

            public void onOptionClick(IconMenu.OptionClickEvent event) {
            	Player p = (Player) event.getPlayer();
            	
            	if(event.getName().equals(...
            	
                event.setWillClose(true);
            }
        }, (Plugin) this)
        .setOption(...
       
        return menu;
	}
 
G

games6471

Guest
Also ich hab mir mal die Mühe gemacht und die gleiche API vom Entwickler genommen und ausprobiert. Ich habe keine Probleme, dass irgendetwas doppelt ausgeführt wird. Vllt gibt es irgendein Logik-Fehler bei deinem Plugin, da man aber nur ein kleinen Teil sieht, kann man dir hier nicht viel weiterhelfen.
 
G

games6471

Guest
Nein hier:

Code:
	public void onEnable() { 
		PluginManager pm = Bukkit.getPluginManager();
		this.im = this.CreateIconMenu();
		this.il = new IconListener(this.im);
		
		Bukkit.getWorlds().get(0).setGameRuleValue("keepInventory", "true");
		
		[COLOR="#FF0000"]pm.registerEvents(this.im, this);[/COLOR]
		pm.registerEvents(this.il, this);
    }

und hier:


Code:
    public IconMenu(String name, int size, OptionClickEventHandler handler, Plugin plugin) {
        this.name = name;
        this.size = size;
        this.handler = handler;
        this.plugin = plugin;
        this.optionNames = new String[size];
        this.optionIcons = new ItemStack[size];
        [COLOR="#FF0000"]plugin.getServer().getPluginManager().registerEvents(this, plugin);[/COLOR]
    }
 

squiby

Minecrafter
Registriert
23 November 2012
Beiträge
8
Diamanten
0
Problem 2.0

Hier wieder die relevanten Teile:
IconMain: http://pastie.org/private/dsoxwzbpkmqoqtqaci7uiq
IconMenu: http://pastie.org/private/ndk4wm2coihxt9cqesjaoa
IconListener: http://pastie.org/private/0xjt6rvdumfnkvderdk8aq

Folgendes Problem: Das Ganze funktioniert gut, solange man nicht auf ein Item außerhalb des Iconmenüs klickt, während es geöffnet ist. Der Vorgang sollte ja normal gecancelled werden, nur leider wird danach das Event scheinbar nicht mehr ausgelöst (mit Nachrichten getestet). Wäre cool, wenn jemand einen schnellen Blick drauf werfen könnte!
 
Zuletzt bearbeitet:

squiby

Minecrafter
Registriert
23 November 2012
Beiträge
8
Diamanten
0
Update: Kleinigkeit vergessen (Events neu initialisieren nach .unregisterAll(this)) und schon stecke ich wieder bei meinem eigentlichen Problem fest: Beim Öffnen des Menüs (Interaktion mit der Uhr in der Hand) reseted sich das komplette Inventar. Alle aufgenommenen Items gehen verloren und Verschobene werden wieder in ihren vorigen Slot gesetzt. Blöcke, die im 2x2-Feld gecrafted wurden, verschwinden beim Setzen und die Ressourcen erscheinen wieder im Inventar. Das tritt auf, sobald der Spieler auf ein Icon klickt, welches IHN TELEPORTIERT. Nachrichten versenden, etc. funktioniert einwandfrei. Sobald, ich z.B. p.teleport(world.getSpawnLocation()) einfüge, beginnt das Inventar sich selbst zurückzusetzen.

IconMain: http://pastie.org/private/kfim55lkyvv2xnenkj4ja#33
IconMenu: http://pastie.org/private/5mkjagv2ao4wbvqowlog
 
Zuletzt bearbeitet:
Oben