Search code examples
javaindexoutofboundsexceptionpaintcomponenttiles

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 100


We are trying to create a game board with tiles (10 x 10). However, when running the class below, we keep getting an ArrayIndexOutOfBoundsException. For some reason, when running the same class on another device, this error is not given.

Board.java

public class Board extends JComponent {

    public Board() {

    }


    public static String[] gameElements = new String[100];


    String[][] Map = new String[10][10];
    int positionX = 50;
    int positionY = 50;
    int i = 0;
    String currentLevel = "1";

    @Override
    public void paintComponent(Graphics g) {
        loadLevel();
        for (int y = 0; y < Map.length; y++) {
            for (int x = 0; x < Map.length; x++) {
                new Tile(x, y).paintComponent(g);
                Map[y][x] = gameElements[i];
                g.drawString(Map[y][x], positionY, positionX);
                positionY = positionY + 50;
                System.out.print("[" + Map[y][x] + "]");
                i++;

            }
            positionY = 50;
            positionX = positionX + 50;
            System.out.println();

        }
    }

    public static void main(String[] args) {

        JFrame frame = new JFrame();
        frame.setSize(600, 600);
        frame.setTitle("SleutelBarricade");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JComponent chart = new Board();
        frame.add(chart);

        frame.setVisible(true);


    }

    public void readTextFile(String fileName) {
        try {
            FileReader fileReader = new FileReader(fileName + ".txt");
            BufferedReader buffer = new BufferedReader(fileReader);
            String splitBy = ",";
            String line = buffer.readLine();

            for (int i = 0; i < gameElements.length; i++) {
                gameElements = line.split(splitBy);
            }

        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void loadLevel() {
        readTextFile(currentLevel);

    }

}

Part of the Exception:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 100
    at Main.GameBoard.Board.paintComponent(Board.java:45)
    at javax.swing.JComponent.paint(JComponent.java:1056)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paint(JComponent.java:1065)
    at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
    at javax.swing.JComponent.paintChildren(JComponent.java:889)
    at javax.swing.JComponent.paintToOffscreen(JComponent.java:5217)

Solution

  • You never reset i before your double-nested loop begins. Move the variable inside or reset it to 0.

    @Override
    public void paintComponent(Graphics g) {
        int i = 0;
        loadLevel();
    
        for (int y = 0; y < Map.length; y++) {
            for (int x = 0; x < Map.length; x++) {
                new Tile(x, y).paintComponent(g);
                Map[y][x] = gameElements[i];
                g.drawString(Map[y][x], positionY, positionX);
                positionY = positionY + 50;
                System.out.print("[" + Map[y][x] + "]");
                i++;
    
            }
    
            positionY = 50;
            positionX = positionX + 50;
            System.out.println();
        }
    }
    

    I would also suggest you reorganize your class to make it easier to read. You do not have to follow this to the letter, but try to group similar things. This will make things stand out better and help others follow your program more easily.

    With this simple tip, the stray int i = 0 (instance variable) would have been easy to spot.

    public class Board extends JComponent {
        // I. Static variables
        public static String[] gameElements = new String[100];
    
        // II. Instance variables (These should be private or protected)
        private String[][] map = new String[10][10];
        private int positionX = 50;
        private int positionY = 50;
        private int i = 0; // <------------------------- Hey, you don't belong here!
        private String currentLevel = "1";
    
        // III. Getter/Setters
        public String[] getMap() {
            return map;
        }
        public void setMap(String[] map) {
            this.map = map;
        }
    
        // IV. Constructor
        public Board() { }
    
        // V. Overrides
        @Override
        public void paintComponent(Graphics g) { }
    
        // VI. Custom Instance Methods
        public void readTextFile(String fileName) { }
    
        public void loadLevel() { }
    
        // VII. Main Method
        public static void main(String[] args) { }
    }