1

Im trying to create a dice rolling tool as part of a larger application. However if i try to roll more than 1 dice in my dice roll function the application crashes. Howver as im new to Java i cant seem to find the cause of the index out of bounds error.

DiceActvity.Java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RadioButton;
import java.util.ArrayList;
import java.util.List;


public class DiceActivity extends AppCompatActivity
{
    ListView LVDiceList;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dice);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //Radio button
        final RadioButton rbGreater = (RadioButton) findViewById(R.id.greaterThanRadioB);
        final RadioButton rbLess = (RadioButton) findViewById(R.id.lessThanRadioB);

        //Edit boxes
        final EditText txtDiceType = (EditText) findViewById(R.id.diceTypeEdTxt);
        final EditText txtNumberDice = (EditText) findViewById(R.id.numDiceEdTxt);
        final EditText txtFilterNum = (EditText) findViewById(R.id.filterNumEdTxt);

        //Buttons
        Button btnRoll = (Button) findViewById(R.id.rollButton);
        Button btnDiscard = (Button) findViewById(R.id.discardButton);

        //Display Array
        final List<Integer> diceList = new ArrayList<Integer>(10);
        //Array Adapter
        final ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item, diceList);

        //Set adapter
        LVDiceList = (ListView) findViewById(R.id.diceResultListV);
        LVDiceList.setAdapter(adapter);

        //Roll the dice
        btnRoll.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                //Hide soft keyboard
                Utils.hideKeyboard(DiceActivity.this);

                //Validation of fields
                //If both fields >0
                if (Integer.valueOf(txtDiceType.getText().toString()) > 0 && Integer.valueOf(txtNumberDice.getText().toString()) > 0)
                {
                    int number =  Integer.valueOf(txtNumberDice.getText().toString());
                    int sides = Integer.valueOf(txtDiceType.getText().toString());

                    //Populate array
                    for (int i=0;i <number; i++)
                    {
                        diceList.add(i, rollDice(sides,number).get(i));
                    }
                    //Update the list view
                    adapter.notifyDataSetChanged();
                }
                return;

            }
        });

        //Clear the list of results
        btnDiscard.setOnClickListener(new View.OnClickListener()
         {
             @Override
             public void onClick(View v)
             {
                 diceList.clear();
                 adapter.notifyDataSetChanged();
             }
          });

        //Radio Button Validation
        rbGreater.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if(rbGreater.isChecked() == true)
                {
                    rbLess.setChecked(false);
                }
            }
        });
        rbLess.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if(rbLess.isChecked() == true)
                {
                    rbGreater.setChecked(false);
                };
            }
        });

    }

    //Returns a list of rolled dice results
    private List<Integer> rollDice(int chance, int amount)
    {
        final List<Integer> rollArray = new ArrayList<Integer>(amount);
        int result;
        //Gives a random number between 1 and X,Y number of times
        {
            //BASE Equation||Min + (int)(Math.random() * ((Max - Min) + 1))
            //1 = minimum roll
            result = 1 + (int) (Math.random() * ((chance - 1) + 1));
            rollArray.add(result);
        }
        return rollArray;
    }
}

content_dice.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context="garethgriffiths.tabletopcompanion.DiceActivity"
    tools:showIn="@layout/activity_dice">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="@string/textView_NumDice"
        android:id="@+id/numDiceTextV"
        android:layout_alignBottom="@+id/numDiceEdTxt"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:textSize="25dp"
        android:textStyle="bold"
        android:textAlignment="gravity"/>

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="number"
        android:ems="4"
        android:id="@+id/numDiceEdTxt"
        android:maxLength="3"
        android:text="@string/edText_NumDice"
        android:gravity="right"
        android:selectAllOnFocus="true"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/numDiceTextV"
        android:layout_toEndOf="@+id/numDiceTextV"
        android:numeric="integer"/>

    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:text="@string/textView_DiceType"
    android:id="@+id/diceTypeTextV"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/numDiceTextV"
    android:layout_alignBottom="@+id/diceTypeEdTxt"
    android:layout_toLeftOf="@+id/diceTypeEdTxt"
    android:layout_toStartOf="@+id/diceTypeEdTxt"
    android:textSize="25dp"
    android:textStyle="bold"
    android:textAlignment="gravity"/>


    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="number"
        android:ems="4"
        android:id="@+id/diceTypeEdTxt"
        android:maxLength="2"
        android:text="@string/edText_DiceType"
        android:layout_below="@+id/numDiceEdTxt"
        android:layout_alignLeft="@+id/numDiceEdTxt"
        android:layout_alignStart="@+id/numDiceEdTxt"
        android:gravity="right"
        android:selectAllOnFocus="true"
        android:numeric="integer"/>

    <RadioButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/radioB_LessThan"
        android:id="@+id/lessThanRadioB"
        android:layout_above="@+id/discardButton"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="36dp"/>

    <RadioButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/radioB_GreaterThan"
        android:id="@+id/greaterThanRadioB"
        android:layout_alignTop="@+id/lessThanRadioB"
        android:layout_toRightOf="@+id/lessThanRadioB"
        android:layout_toEndOf="@+id/lessThanRadioB"/>

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:inputType="number"
        android:ems="4"
        android:maxLength="3"
        android:id="@+id/filterNumEdTxt"
        android:layout_alignTop="@+id/greaterThanRadioB"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:text="@string/edText_NumFilter"
        android:gravity="center"
        android:selectAllOnFocus="true"
        android:numeric="integer"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_Discard"
        android:id="@+id/discardButton"
        android:layout_alignTop="@+id/rollButton"
        android:layout_toLeftOf="@+id/rollButton"
        android:layout_toStartOf="@+id/rollButton"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_Roll"
        android:id="@+id/rollButton"
        android:layout_marginTop="108dp"
        android:layout_below="@+id/diceTypeTextV"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>

    <ListView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/diceResultListV"
        android:scrollIndicators="right"
        android:visibility="visible"
        android:layout_below="@+id/discardButton"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>

</RelativeLayout>

Heres a small Class used to hide softkeyboard thats called in DiceActivity

import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;

/**
 * http://stackoverflow.com/questions/1109022/close-hide-the-android-soft-keyboard
 * Used to close soft keyboard
 */

public class Utils
{
    public static void hideKeyboard(Activity activity)
    {
        // Check if no view has focus:
        View view = activity.getCurrentFocus();
        if (view != null)
        {
            InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
            inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }
}

1 Answers1

0

Your method private List<Integer> rollDice(int chance, int amount) returns a list of Integer. And according to your comment inside the method it should have multiple numbers in it.

But this method always returns only one number.

Now you invoke this method here:

for (int i=0;i <number; i++)
{
    diceList.add(i, rollDice(sides,number).get(i));
}

You are invoking this method in a loop. Storing the results in a NEW list.

You get an exception because in the second loop get(i) is 1 and there is only 1 entry in this list on index 0.

To correct this is should read: .get(0)

Also this kind of implementation is very messy. Please take a paper and a pencil to figure it out.

Marcinek
  • 2,079
  • 1
  • 16
  • 23
  • Thanks for that! it works as inended now. Also now that you point it out it is very meessy. Although it is my first time doing anything in android/java this is kindof embarrasing. However now that i understand what the problem there are some obvious ways i can clean it up. – user5861358 Jan 31 '16 at 12:45