2

I get a ConcurrentModificationException when I clear an array.

package net.minecraft.client.gui;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import net.minecraft.block.Block;
import net.minecraft.block.Xray;
import net.minecraft.client.Minecraft;

import org.lwjgl.opengl.GL11;

public class GuiHub extends GuiScreen{
    static List<GuiInterface> components = new ArrayList<GuiInterface>();
    static FontRenderer fontRenderer;
    static Xray xrayManager;

    public GuiHub(){
        this.components.clear();
        xrayManager = new Xray();
        //Color format: 0xAARRGGBB <-- 
        //Transparent: 0x80RRGGBB
        //Solid: 0xFFRRGGBB
        GuiFrameComponent world = new GuiFrameComponent("World" , 10, 10);
        GuiFrameComponent player = new GuiFrameComponent("Player" , 130, 10);
        GuiFrameBindComponent bindings = new GuiFrameBindComponent("Binds Explorer", 210, 10);
        GuiFrameComponentButton xray = new GuiFrameComponentButton("Xray", false);
        GuiFrameComponentButton fullbright = new GuiFrameComponentButton("Fullbright", false);
        GuiFrameComponentButton day = new GuiFrameComponentButton("Always Day", false);
        GuiFrameComponentButton fly = new GuiFrameComponentButton("Fly", false);
        GuiFrameComponentButton nofall = new GuiFrameComponentButton("NoFall", false);
        GuiFrameComponentButton spider = new GuiFrameComponentButton("Spider Mode", false);
        GuiFrameComponentButton blockreach = new GuiFrameComponentButton("Block Reach", false);
        GuiFrameComponentButton noswing = new GuiFrameComponentButton("No Swing", false);
        //World
        world.addComponent(xray);
        world.addComponent(fullbright);
        world.addComponent(day);
        //Player
        player.addComponent(fly);
        player.addComponent(spider);
        player.addComponent(nofall);
        player.addComponent(blockreach);
        player.addComponent(noswing);

        addComponent(player);
        addComponent(world);

        //addComponent(bindings);

        xrayManager.loadFromStorage();
        xrayManager.addBlock(14);
        xrayManager.addBlock(15);
        xrayManager.addBlock(16);
        xrayManager.addBlock(21);
        xrayManager.addBlock(56);
        xrayManager.addBlock(129);
        xrayManager.addBlock(73);



    }

    public static void addComponent(GuiInterface component){
        components.add(component);
    }

    public void drawScreen(int par1, int par2, float par3) {
        super.drawScreen(par1, par2, par3);

        for(GuiInterface component : components){
            component.drawGuiComponent(par1, par2);
        }
    }

    public void mouseClicked(int par1, int par2, int par3){
        super.mouseClicked(par1, par2, par3);
        for(GuiInterface component : components){
            component.onGuiComponentClicked(par1, par2, par3);
        }
    }

    public void mouseMovedOrUp(int par1, int par2, int par3){
        super.mouseMovedOrUp(par1, par2, par3);
        for(GuiInterface component : components){
            component.onGuiMouseMovedOrUp(par1, par2, par3);
        }
    }

    public boolean doesGuiPauseGame()
    {
        return false;
    }

    public void setMinecraft(Minecraft mc){
        this.mc = mc;
    }

    public void setFontRenderer(FontRenderer fontRenderer) {
        this.fontRenderer = fontRenderer;   
    }

    public static FontRenderer getFontRenderer(){
        return fontRenderer;
    }

    public static Minecraft getMinecraft() {
        return mc;
    }

    public static Xray getXrayManager() {
        return xrayManager;
    }

    public static void setOnTop(GuiInterface component) {
        components.clear();
    }


}

As you can see, drawScreen basically iterates through the components ArrayList. I assume this concurrent modification exception is being thrown when it tries to access an element in my components ArrayList. I've tried various approaches to fix this, including:

  • Adding a shouldRender boolean. Setting that to false before it clears the components ArrayList and then setting it to true when it has finished clearing the components arrayList, looking like this:

    public static void setOnTop(GuiInterface component) { shouldRender = false; components.clear(); shouldRender = true; }

And I had it so that it shouldRender had to be true to iterate and draw through the components.

Here is the StackTrace:

This bit is generated by the game API -->

net.minecraft.util.ReportedException: Updating screen events
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1696) ~[bin/:?]
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:995) ~[bin/:?]
    at net.minecraft.client.Minecraft.run(Minecraft.java:911) [bin/:?]
    at net.minecraft.client.main.Main.main(Main.java:109) [bin/:?]
    at Start.main(Start.java:11) [bin/:?]


Not generated by the game API -->
Caused by: java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source) ~[?:1.8.0_05]
    at java.util.ArrayList$Itr.next(Unknown Source) ~[?:1.8.0_05]
    at net.minecraft.client.gui.GuiHub.mouseClicked(GuiHub.java:81) ~[bin/:?]
    at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:324) ~[bin/:?]
    at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:288) ~[bin/:?]
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1682) ~[bin/:?]
    ... 4 more

1 Answer 1

3

The ConcurrentModificationException is telling you that the list was modified while you were trying to iterate over it.

You can avoid this by several methods, including:

  • Using thread synchronization to ensure that another thread isn't trying to modify your list while you're iterating over it.
  • Using a java.util.concurrent.CopyOnWriteArrayList. After a modification, any existing iterators continue working on the old list.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.