Question

I am developing a game that requires rows and columns of buttons.I really cant figure out how ArrayIndexOutOfBound exception occurs in my code.Help me figure out the error.Thank you

this is my XML view

 <?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tl1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:stretchColumns="0,2"
    android:background="@drawable/game"
    android:alpha="20" >

    <TableRow
        android:id="@+id/tr1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/tvNoOfMines"
            android:layout_height="100dp"
            android:layout_column="0"
            android:gravity="center"
            android:text="000" >
        </TextView>

        <ImageButton
            android:id="@+id/ibSmiley"
            android:layout_height="wrap_content"
            android:layout_column="1"
            android:background="@drawable/custom_reaction" >
        </ImageButton>

        <TextView
            android:id="@+id/tvTimer"
            android:layout_height="100dp"
            android:layout_column="2"
            android:gravity="center"
            android:text="000" >
        </TextView>
    </TableRow>

    <TableRow
        android:id="@+id/tr2"
        android:layout_width="match_parent"
        android:layout_height="50dp" >
    </TableRow>

    <TableRow android:id="@+id/tr3" >

        <TableLayout
            android:id="@+id/tlMineFields"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_span="3"
            android:stretchColumns="*" 
            android:scrollbars="vertical"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            android:padding="5dp">
        </TableLayout>
    </TableRow>

</TableLayout>

this is the part of my code where I access the button array

 private void createMineFields() {
        // TODO Auto-generated method stub
        buttonBlock = new ButtonBlock[noOfMineFields][noOfMineFields];

        for(int i=0;i<noOfMineFields;i++){
            for(int j=0;j<noOfMineFields;j++){
                buttonBlock[i][j]=new ButtonBlock(this);
                buttonBlock[i][j].setOnClickListener(this);
                buttonBlock[i][j].setOnLongClickListener(this);
            }
        }
    }


private void placeMineFields() {
        // TODO Auto-generated method stub

        for (int i = 0; i < noOfMineFields; i++) {
            tablerow = new TableRow(this);
            tablerow.setLayoutParams(new LayoutParams(blockWidth
                    + (2 * blockPadding) * noOfMineFields, blockHeight
                    + (2 * blockPadding)));
            //tablerow.setPadding(blockPadding, blockPadding, blockPadding, blockPadding);
            for (int j = 0; j < noOfMineFields; j++) {
                buttonBlock[i][j].setLayoutParams(new LayoutParams(blockWidth
                    + (2 * blockPadding) * noOfMineFields, blockHeight
                    + (2 * blockPadding)));
                buttonBlock[i][j].setPadding(blockPadding, blockPadding, blockPadding, blockPadding);
                String createId = "" + (i + 1) + "" + j;
                buttonBlock[i][j].setId(Integer.parseInt(createId));
                tablerow.addView(buttonBlock[i][j]);

            }

            tablelayout.addView(tablerow,new TableLayout.LayoutParams(blockWidth
                    + (2 * blockPadding) * noOfMineFields, blockHeight
                    + (2 * blockPadding)));

        }
    }

Im calling the createMineFields() field first followed by placeMineFields().Im new to android and programming.Help me figure out where and how ArrayIndexOutOfBound exception happens.

this is the Error that was issued in LogCat

  01-18 23:12:54.805: D/dalvikvm(2766): GC_EXTERNAL_ALLOC freed 52K, 53% free 2562K/5379K, external 1625K/2137K, paused 59ms
01-18 23:13:52.445: D/dalvikvm(2766): GC_EXTERNAL_ALLOC freed 8K, 52% free 2583K/5379K, external 2525K/3154K, paused 33ms
01-18 23:13:52.615: D/AndroidRuntime(2766): Shutting down VM
01-18 23:13:52.615: W/dalvikvm(2766): threadid=1: thread exiting with uncaught exception (group=0x40015560)
01-18 23:13:52.625: E/AndroidRuntime(2766): FATAL EXCEPTION: main
01-18 23:13:52.625: E/AndroidRuntime(2766): java.lang.RuntimeException: Unable to start activity ComponentInfo{btdw.agilan.minesweeper/btdw.agilan.minesweeper.Game}: java.lang.ArrayIndexOutOfBoundsException
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.os.Looper.loop(Looper.java:123)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.main(ActivityThread.java:3683)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at java.lang.reflect.Method.invokeNative(Native Method)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at java.lang.reflect.Method.invoke(Method.java:507)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at dalvik.system.NativeStart.main(Native Method)
01-18 23:13:52.625: E/AndroidRuntime(2766): Caused by: java.lang.ArrayIndexOutOfBoundsException
01-18 23:13:52.625: E/AndroidRuntime(2766):     at btdw.agilan.minesweeper.Game.placeMineFields(Game.java:115)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at btdw.agilan.minesweeper.Game.onCreate(Game.java:58)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-18 23:13:52.625: E/AndroidRuntime(2766):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
01-18 23:13:52.625: E/AndroidRuntime(2766):     ... 11 more

this is the code where I call createminefields() and placeminefields()

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mine);
        initialize();
        placeMineFields();
    }



   private void initialize() {
        // TODO Auto-generated method stub
        createMineFields();
        time = (TextView) findViewById(R.id.tvTimer);
        tablelayout = (TableLayout) findViewById(R.id.tlMineFields);
        tvNoOfMines=(TextView) findViewById(R.id.tvNoOfMines);
        currentTime=0;
        check=0;
        isMineClicked = false;
        isClickedFirst = false;
        blockWidth = 10;
        blockHeight = 10;
        blockPadding = 5;
        noOfMineFields = 6;
        noOfMines = 1;
        noOfSafeFields=(noOfMineFields*noOfMineFields)-noOfMines;
        mineArray = new int[noOfMineFields][noOfMineFields];
        for (int i = 0; i < noOfMineFields; i++)
            for (int j = 0; j < noOfMineFields; j++)
                mineArray[i][j] = 0;
        mineWeight = new int[noOfMineFields][noOfMineFields];
        for (int i = 0; i < noOfMineFields; i++)
            for (int j = 0; j < noOfMineFields; j++)
                mineWeight[i][j] = 0;

        tablerow = new TableRow(this);
        timer= new Handler();
        timeElasped=new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                check=System.currentTimeMillis();
                currentTime++;
                time.setText(""+currentTime);
                timer.postAtTime(this, check);
                timer.postDelayed(timeElasped, 1000);
            }
        };
        tvNoOfMines.setText(""+noOfMines);
    }
Was it helpful?

Solution

The problem I see is that you do not set a fixed value for noOfMineFields variable before you call createMineFields() function. I assume it is a global variable, but you have no knowledge of what value it holds when createMineFileds() is called (most likely 0 since it's default number-based value). Then when you call placeMineFields(), the noOfMineFields is set to 6 so it goes beyond the scope of your array (assuming it was initially 0)

OTHER TIPS

After knowing your exception comes from the:

buttonBlock[i][j].setLayoutParams(new LayoutParams(blockWidth+(2*blockPadding)*noOfMineFields,blockHeight +(2*blockPa‌​dding)));

The exception you're getting is probably because any i and j combination is not initialized in your buttonBlock array. I recommend putting Log elements in your code for each loop iteration and see where is the problem (also printing the current sizes of your array may help).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top