GridAdapter array out of bounds?
<p>I am having a problem with GridAdapter for Andorid gridview. The error is "12-28 21:35:44.893: E/AndroidRuntime(370): java.lang.RuntimeException: Unable to start activity ComponentInfo{btn.grid/btn.grid.ButtonGridActivity}: java.lang.ArrayIndexOutOfBoundsException
"</p>

<p>and the adapter is </p>

<pre><code> package btn.grid;



import android.content.Context;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

class MonthAdapter extends BaseAdapter {
        private GregorianCalendar mCalendar;
        private Calendar mCalendarToday;
        private Context mContext;
        private DisplayMetrics mDisplayMetrics;
        private List&lt;String&gt; mItems;
        private int mMonth;
        private int mYear;
        private int mDaysShown;
        private int mDaysLastMonth;
        private int mDaysNextMonth;
        private int mTitleHeight, mDayHeight;
        private final String[] mDays = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
        private final int[] mDaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

        public MonthAdapter(Context c, int month, int year ) {
                mContext = c;
                mMonth = month;
                mYear = year;
                mCalendar = new GregorianCalendar(mYear, mMonth, 1);
                mCalendarToday = Calendar.getInstance();

                populateMonth();
        }

        private void populateMonth() {
                mItems = new ArrayList&lt;String&gt;();              
                for (String day : mDays) {
                        mItems.add(day);
                        mDaysShown++;
                }

                int firstDay = getDay(mCalendar.get(Calendar.DAY_OF_WEEK));
                int prevDay;
                if (mMonth == 0)
                        prevDay = daysInMonth(11) - firstDay + 1;
                else
                        prevDay = daysInMonth(mMonth - 1) - firstDay + 1;
                for (int i = 0; i &lt; firstDay; i++) {
                        mItems.add(String.valueOf(prevDay + i));
                        mDaysLastMonth++;
                        mDaysShown++;
                }

                int daysInMonth = daysInMonth(mMonth); 
                for (int i = 1; i &lt;= daysInMonth; i++) {
                        mItems.add(String.valueOf(i));
                        mDaysShown++;
                }

                mDaysNextMonth = 1;
                while (mDaysShown % 7 != 0) {
                        mItems.add(String.valueOf(mDaysNextMonth));
                        mDaysShown++;
                        mDaysNextMonth++;
                }

                mTitleHeight = 30;
                int rows = (mDaysShown / 7);
                mDayHeight = (mDisplayMetrics.heightPixels - mTitleHeight
                                - (rows * 3) - getBarHeight())/ (rows - 1);
        }

        private int daysInMonth(int month) {
                int daysInMonth = mDaysInMonth[month];
                if (month == 1 &amp;&amp; mCalendar.isLeapYear(mYear))
                        daysInMonth++;
                return daysInMonth;
        }

        private int getBarHeight() {
                switch (mDisplayMetrics.densityDpi) {
                case DisplayMetrics.DENSITY_HIGH:
                        return 48;
                case DisplayMetrics.DENSITY_MEDIUM:
                        return 32;
                case DisplayMetrics.DENSITY_LOW:
                        return 24;
                default:
                        return 48;
                }
        }

        /**
         * For week starting Monday
         * @param day from Calendar.DAY_OF_WEEK
         * @return day week starting Monday
         */
        private int getDay(int day) {
                switch (day) {
                case Calendar.MONDAY:
                        return 0;
                case Calendar.TUESDAY:
                        return 1;
                case Calendar.WEDNESDAY:
                        return 2;
                case Calendar.THURSDAY:
                        return 3;
                case Calendar.FRIDAY:
                        return 4;
                case Calendar.SATURDAY:
                        return 5;
                case Calendar.SUNDAY:
                        return 6;
                default:
                        return 0;
                }
        }

        private boolean isToday(int day, int month, int year) {
                if (mCalendarToday.get(Calendar.MONTH) == month
                                &amp;&amp; mCalendarToday.get(Calendar.YEAR) == year
                                &amp;&amp; mCalendarToday.get(Calendar.DAY_OF_MONTH) == day) {
                        return true;
                }
                return false;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                final TextView view = new TextView(mContext);
                view.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
                view.setText(mItems.get(position));
                view.setBackgroundColor(Color.rgb(244, 244, 244));
                view.setTextColor(Color.BLACK);

                if (position &lt;= 6) {
                        // names
                        view.setBackgroundColor(Color.argb(100, 10, 80, 255));
                        view.setHeight(mTitleHeight);
                } else if (position &lt;= mDaysLastMonth + 6) {
                        // previous month
                        view.setBackgroundColor(Color.rgb(234, 234, 245));
                        view.setHeight(mDayHeight);
                } else if (position &lt;= mDaysShown - mDaysNextMonth  ) {
                        // current month
                        view.setHeight(mDayHeight);
                        int day = position - (mDaysLastMonth + 6);
                        if (isToday(day, mMonth, mYear)) {
                                view.setTextColor(Color.RED);
                        }
                        // check db and colour for shifts
                        // ...
                } else {
                        // next month
                        view.setHeight(mDayHeight);
                        view.setBackgroundColor(Color.rgb(234, 234, 245));
                }
                return view;
        }

        @Override
        public int getCount() {
                return mItems.size();
        }

        @Override
        public Object getItem(int position) {
                return mItems.get(position);
        }

        @Override
        public long getItemId(int position) {
                return position;
        }
}
</code></pre>

<p>*LogCat</p>

<pre><code>    12-28 21:35:44.873: W/dalvikvm(370): threadid=1: thread exiting with uncaught exception (group=0x40015560)
12-28 21:35:44.893: E/AndroidRuntime(370): FATAL EXCEPTION: main
12-28 21:35:44.893: E/AndroidRuntime(370): java.lang.RuntimeException: Unable to start activity ComponentInfo{btn.grid/btn.grid.ButtonGridActivity}: java.lang.ArrayIndexOutOfBoundsException
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.access$1500(ActivityThread.java:117)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.os.Looper.loop(Looper.java:123)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.main(ActivityThread.java:3683)
12-28 21:35:44.893: E/AndroidRuntime(370):  at java.lang.reflect.Method.invokeNative(Native Method)
12-28 21:35:44.893: E/AndroidRuntime(370):  at java.lang.reflect.Method.invoke(Method.java:507)
12-28 21:35:44.893: E/AndroidRuntime(370):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
12-28 21:35:44.893: E/AndroidRuntime(370):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
12-28 21:35:44.893: E/AndroidRuntime(370):  at dalvik.system.NativeStart.main(Native Method)
12-28 21:35:44.893: E/AndroidRuntime(370): Caused by: java.lang.ArrayIndexOutOfBoundsException
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.MonthAdapter.daysInMonth(MonthAdapter.java:82)
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.MonthAdapter.populateMonth(MonthAdapter.java:62)
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.MonthAdapter.&lt;init&gt;(MonthAdapter.java:40)
12-28 21:35:44.893: E/AndroidRuntime(370):  at btn.grid.ButtonGridActivity.onCreate(ButtonGridActivity.java:16)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-28 21:35:44.893: E/AndroidRuntime(370):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
12-28 21:35:44.893: E/AndroidRuntime(370):  ... 11 more
</code></pre>
