从ArrayList中删除项目时出现异常

时间:2014-09-17 22:33:29

标签: java exception arraylist static removechild

我一直在思考解决方案已有一段时间了。每次我尝试从ArrayList中删除项目时,我总是会遇到异常错误。与ArrayList相关的items.add()工作得很好,但我无法理解为什么它在删除项目时会抛出异常(items.remove())。

此ArrayList用于库存,用于绘制和更新每个项目。我使用典型的for循环遍历每个对象:

for(int i = 0; i< items.size(); i ++)

这是我的库存类的内部:

public class Inventory {

public static boolean bOpen;
public static boolean bSelected;

private Rectangle selectBox;
private Color hover;
private Color select;
private Color color;
private Font f;
private FontMetrics fontMetrics;

public static int tileCount;
private boolean pressed;

private int sx;
private int sy;

public boolean I;
private BufferedImage HUD;
private BufferedImage infoBase;
public static ArrayList<Item> items;
private int itemCount;

// Items
public static Shovel shovel;
public static PickAxe pickAxe;
public static Key key;

public Inventory() {
    try {
        HUD = ImageIO.read(getClass().getResource("/HUD.png"));
        infoBase = ImageIO.read(getClass().getResource("/InfoBase.png"));
    } catch (Exception e) {
        e.printStackTrace();
    }

    items = new ArrayList<Item>();

    // Init items
    shovel = new Shovel();
    pickAxe = new PickAxe();
    key = new Key();

    items.add(shovel);
    items.add(pickAxe);

    hover = new Color(150, 150, 180, 180);
    select = new Color(255, 174, 0, 180);

    f = new Font("Bodoni MT", Font.PLAIN, 12);

    sx = 34;
    sy = 198;
}

public void draw(Graphics2D g) {

    itemCount = items.size();

    if (I) {
        bOpen = true;
    }

    if (bOpen) {
        g.setColor(new Color(0, 0, 0, 180));
        g.fillRect(0, 0, GamePanel.WIDTH, GamePanel.HEIGHT);
        g.drawImage(HUD, 26, 194, 270, 41, null);

        for (int i = 0; i < items.size(); i++) {

            if (items.get(i) != null) {
                items.get(i).update();
                items.get(i).draw(g, 22 + i * 32, 180);
            }

            g.setColor(color);
            g.setStroke(new BasicStroke(2));
            selectBox = new Rectangle(sx, sy, 32, 32);

            if (!bSelected && items.get(i) != null) {
                color = hover;
                items.get(tileCount).bSelected = false;

            } else {
                color = select;
                if (items.get(i) != null) {
                    items.get(tileCount).bSelected = true;
                    g.drawImage(infoBase, 20, 59, null);
                    g.setFont(f);
                    fontMetrics = g.getFontMetrics();
                    int width = fontMetrics.stringWidth(items
                            .get(tileCount).getInfo());
                    g.drawString(items.get(tileCount).getInfo(),
                            GamePanel.WIDTH / 4 - width / 2, 80);
                }
            }

            g.draw(selectBox);
        }

        if (GamePanel.right) {
            bSelected = false;
            if (GamePanel.left == false) {
                if (!pressed) {
                    pressed = true;
                    if (tileCount <= itemCount - 2) {
                        try {
                            Thread.sleep(120);
                            sx = sx + 32;
                            tileCount = tileCount + 1;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        if (GamePanel.left) {
            bSelected = false;
            if (GamePanel.right == false) {
                if (!pressed) {
                    pressed = true;
                    if (tileCount > 0) {
                        try {
                            Thread.sleep(120);
                            sx = sx + -32;
                            tileCount = tileCount - 1;
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        if (GamePanel.right || GamePanel.left) {
            pressed = false;
        }

        if (GamePanel.enter && itemCount > 0) {
            bSelected = true;
        }
    }

    if (itemCount > 8) {
        items.remove(8);
    }
    System.out.println(items.size());
}

}

这是我调用items.remove()方法的类:

public class Chest extends Item {

public static boolean bOpen;

private StringEvent se;

public Chest() {
    se = new StringEvent();
    bSolid = true;
}

public void draw(Graphics2D g, int x, int y) {
    setRadius(TileLayer.xx + x + getWidth() / 2, TileLayer.yy + y
            + getHeight() / 2, 32, 32);
    checkCollision();

    if (bTouched) {
        if (GamePanel.e) {
            if (Inventory.key.bSelected == true) {
                bOpen = true;
                Inventory.key.bUsed = true;
            } else
                se.draw(g, this, 2, "Chest is locked.");
        }
    }

    if (!bOpen) {
        g.drawImage(content.chestShut(), TileLayer.xx + x,
                TileLayer.yy + y, null);
    }

    if (bOpen) {
        g.drawImage(content.chestOpen(), TileLayer.xx + x,
                TileLayer.yy + y, null);
        if (Inventory.bOpen == false) {
            Audio.playOnce(Audio.unlock);
        }
    }

    if (Inventory.key.bUsed && !bRemove) {
        Inventory.items.remove(Inventory.key);
        bRemove = true;
    }
}

public void update() {
}

}

关于如何克服这个问题的任何想法?

编辑:这是堆栈跟踪:

Game (31) [Java Application]    
Main.Game at localhost:49264    
    Thread [AWT-Shutdown] (Running) 
    Daemon Thread [AWT-Windows] (Running)   
    Thread [AWT-EventQueue-0] (Running) 
    Thread [Thread-2] (Suspended (exception IndexOutOfBoundsException)) 
        ArrayList<E>.rangeCheck(int) line: not available    
        ArrayList<E>.get(int) line: not available   
        Inventory.draw(Graphics2D) line: 102    
        GamePanel.draw() line: 184  
        GamePanel.run() line: 105   
        Thread.run() line: not available    
    Thread [DestroyJavaVM] (Running)    
    Daemon Thread [Java Sound Event Dispatcher] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
    Daemon Thread [Direct Clip] (Running)   
C:\Program Files\Java\jre7\bin\javaw.exe (18 Sep 2014 18:40:22) 

感谢您的帮助。

我也在我的控制台中得到了这个:

Exception in thread "Thread-2" 

我尝试将itemSize编辑为items.size(),但不幸的是仍然出现错误。我不相信itemCount是问题,因为items.size()不超过'8'的值。

编辑:好的,所以我发现了问题。 items.get(i)导致异常,因为:

if (!bSelected) {
                color = hover;
                if (items.get(i) != null) {
                    items.get(tileCount).bSelected = false;

            } else {
                color = select;
                if (items.get(i) != null) {
                    items.get(tileCount).bSelected = true;
                    g.drawImage(infoBase, 20, 59, null);
                    g.setFont(f);
                    fontMetrics = g.getFontMetrics();
                    int width = fontMetrics.stringWidth(items
                            .get(tileCount).getInfo());
                    g.drawString(items.get(tileCount).getInfo(),
                            GamePanel.WIDTH / 4 - width / 2, 80);
                }
            }

这是因为当库存打开时,它会尝试设置items.get(i).bSelected = true或items.get(i).bSelected = false。也许它正试图找到ArrayList中不存在的东西?仍然有同样的错误:/

3 个答案:

答案 0 :(得分:0)

编辑:实际上你的代码并不一定与我最初的想法一致。请提供其他人提到的堆栈跟踪,以便更容易确定问题所在。

尝试更改

if (itemCount > 8) {
    items.remove(8);
}

if (items.size() > 8) {
    items.remove(8);
}

您可能正在删除第二个类中未反映在itemCount中的项目,因为您在第一个绘制方法的顶部得到了该计数。

答案 1 :(得分:0)

查看你的堆栈:它不是触发异常的“remove”方法,而是“get”。看起来当你删除一个对象时,你的“tileCount”没有得到正确的更新,是吗?

答案 2 :(得分:0)

[固定]

我有

if (items.get(i) != null) {
                    items.get(tileCount).bSelected = false;
                }

当被删除的项目甚至不存在时!我刚刚删除了这个陈述,它完全没问题!