尝试使用HashMap呈现库存时出现StackOverflowError

时间:2017-06-25 21:00:02

标签: java exception exception-handling stack-overflow

我正在尝试使用HashMap为插槽和按钮创建一个包含我的Pane对象的清单。但是,我收到一个StackOverFlowError,可能(可能是?)因为一些递归,但我完全无法找到位置。相关代码:

ro

BecomeYouTuberPane类扩展窗格

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * Project created by ExpDev
 */


public abstract class Pane implements InventoryHolder {

    private Inventory inventory;

    private Map<Integer, Button> buttons = new HashMap<>();

    /**
     * @param rows Amount of rows. Max = 9
     */
    public Pane(int rows, String title) {
        Objects.requireNonNull(title, "title can not be null!");
        if (rows > 6) {
            throw new IllegalArgumentException("Rows must be <= 6, got " + rows);
        }

        this.inventory = Bukkit.createInventory(this, rows * 9, color(title));
    }

    /**
     * @param button The button to add
     */
    public void addButton(Button button) {

        // Finding next available
        buttons.put(buttons.size(), button);

        reRender();
    }

    public void addButton(int place, Button button) {

        buttons.put(place, button);

        reRender();
    }

    /**
     * @param place The place the button is located
     */
    @SuppressWarnings("unused")
    public void removeButton(int place) {
        buttons.remove(place);

        reRender();
    }

    /**
     * Renders the inventory again
     */
    @SuppressWarnings("WeakerAccess")
    public void reRender() {
        inventory.clear();
        createControls(inventory);

        render(inventory);
    }

    /**
     * @param event The {@link InventoryClickEvent}
     */
    @SuppressWarnings("WeakerAccess")
    public void onClick(InventoryClickEvent event) {
        event.setCancelled(true);

        handleClick(event);

    }

    /**
     * Creates the controls
     *
     * @param inventory The inventory
     */
    @SuppressWarnings("WeakerAccess")
    protected abstract void createControls(Inventory inventory);

    /**
     * Get the object's inventory.
     *
     * @return The inventory.
     */
    @Override
    public Inventory getInventory() {
        return inventory;
    }

    @SuppressWarnings("WeakerAccess")
    protected String color(String input) {
        return ChatColor.translateAlternateColorCodes('&', input);
    }

    /**
     * @param player The {@link Player} to open it for
     */
    public void open(Player player) {
        reRender();
        player.openInventory(getInventory());
    }

    /**
     * @param event The click event
     */
    void handleClick(InventoryClickEvent event) {
        // user clicked in his own inventory. Silently drop it
        if (event.getRawSlot() > event.getInventory().getSize()) {
            return;
        }
        // user clicked outside of the inventory
        if (event.getSlotType() == InventoryType.SlotType.OUTSIDE) {
            return;
        }
        if (event.getSlot() >= buttons.size()) {
            return;
        }
        Button button = buttons.get(event.getSlot());
        button.onClick(event);
    }

    /**
     * @param inventory The inventory to render in
     */
    void render(Inventory inventory) {

        for (int i : buttons.keySet()) {
            Button button = buttons.get(i);

            inventory.setItem(i, button.getItemStack());
            System.out.println("Putting " + button.getItemStack().getType().toString() + " in slot " +i);
        }
    }

    /**
     * @return True if this page is empty
     */
    boolean isEmpty() {
        return buttons.isEmpty();
    }
}

按钮类 import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack;

import java.util.Objects; import java.util.function.Consumer;

import me.expdev.youtubebot.Conf;
import me.expdev.youtubebot.YTPlayer;
import me.expdev.youtubebot.utils.ItemStackUtil;
import me.expdev.youtubebot.youtube.YTRequirements;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;

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

/**
 * Project created by ExpDev
 */
public class BecomeYouTuberPane extends Pane {

    private YTPlayer player;

    public BecomeYouTuberPane(YTPlayer player) {
        super(3, "&5YouTuber Rank");

        this.player = player;
    }

    @Override
    protected void createControls(Inventory inventory) {
        // slot 11 and slot 15

        // Lore representing the YTRequirements for the rank
        List<String> reqLore = new ArrayList<String>();
        reqLore.add(ChatColor.GRAY + "YTRequirements for the " + ChatColor.LIGHT_PURPLE + "YouTube Rank" + ChatColor.GRAY + ":");

        // The requirements
        YTRequirements requirements = Conf.YTRequirements;

        reqLore.add(ChatColor.GRAY + " - You need " + ChatColor.YELLOW + requirements.getSubscriberCount() + "+ " + ChatColor.GRAY + "Subscribers");
        reqLore.add(ChatColor.GRAY + " - You need " + ChatColor.YELLOW + requirements.getViewCount() + "+ " + ChatColor.GRAY + "Views");
        reqLore.add(ChatColor.GRAY + " - You need " + ChatColor.YELLOW + requirements.getAverageViewCount() + "+ " + ChatColor.GRAY + "Average Views");
        reqLore.add(ChatColor.GRAY + " - You need " + ChatColor.YELLOW + requirements.getVideoCount() + "+ " + ChatColor.GRAY + "Videos");

        addButton(11, new Button(ItemStackUtil.getItemStack(Material.BOOK,
                1,
                0,
                ChatColor.LIGHT_PURPLE + "YouTube Rank",
                reqLore.toArray(new String[0])))
        );

        // Confirm button
        addButton(15, new Button(ItemStackUtil.getItemStack(Material.WOOD_BUTTON,
                1,
                0,
                ChatColor.BOLD.toString() + ChatColor.GREEN + "Continue",
                ChatColor.GRAY + "Start becoming a " + ChatColor.YELLOW + "YouTuber"),
                e -> {
                    player.setPreVerifying(true);
                    player.closePane();
                    player.msg("&7Type your &9https://www.youtube.com/channel/channelId &7or &9/user/username &7in chat &9(disabled for this process)&7.");
                })); // Start verifying

    }
}

例外:

/**
 * A button
 */
public class Button {

    private static int counter;
    private final int ID = counter++;

    private ItemStack itemStack;
    private Consumer<InventoryClickEvent> action;

    /**
     * @param itemStack The Item
     */
    @SuppressWarnings("unused")
    public Button(ItemStack itemStack) {
        this(itemStack, event -> {});
    }

    /**
     * @param itemStack The Item
     * @param action    The action
     */
    public Button(ItemStack itemStack, Consumer<InventoryClickEvent> action) {
        this.itemStack = itemStack;
        this.action = action;
    }

    /**
     * @return The icon
     */
    @SuppressWarnings("WeakerAccess")
    public ItemStack getItemStack() {
        return itemStack;
    }

    /**
     * @param action The new action
     */
    @SuppressWarnings("unused")
    public void setAction(Consumer<InventoryClickEvent> action) {
        this.action = action;
    }

    /**
     * @param event The event that triggered it
     */
    @SuppressWarnings("WeakerAccess")
    public void onClick(InventoryClickEvent event) {
        action.accept(event);
    }

    // We do not want equals collisions. The default hashcode would not fulfil this contract.
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Button)) {
            return false;
        }
        Button button = (Button) o;
        return ID == button.ID;
    }

    @Override
    public int hashCode() {
        return Objects.hash(ID);
    }
}

非常感谢任何帮助!谢谢。

1 个答案:

答案 0 :(得分:1)

确实你有一个递归问题。它如下:

  1. 您致电reRender(窗格)
  2. {li> createControlsBecomeYouTuberPane来电addButton
  3. addButton调用reRender,因此循环关闭
相关问题