2014-10-24 6 views
0

Мне нужно создать игру с памятью чисел, но если пользователь вводит неправильные цифры, я получаю StringIndexOutOfBoundsException. Я рассмотрел множество примеров и до сих пор не могу понять, как это исправить. Это происходит в методе actionPerformed, с этой строкой кода newNumber = answer.substring(counterOne, counterTwo); Любая помощь будет очень оценена.Проблемы с StringIndexOutOfBoundsException

import java.applet.Applet; 
import java.awt.Button; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Label; 
import java.awt.TextField; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 



public class MemoryGame extends Applet implements ActionListener, Runnable { 

    private Label prompt; 
    private Button button; 
    private TextField input, numDisplay; 
    private int arrayCounter = 3, backgroundColor =0; 
    private int[] myArray = new int[arrayCounter]; 
    private int[] compare = new int[arrayCounter]; 
    private Thread delayThread; 
    private boolean running = true, isCompare; 


    public void init(){ 
     prompt = new Label("Enter the numbers!"); 
     input = new TextField(20); 
     numDisplay = new TextField(20); 
     numDisplay.setEditable(false); 
     button = new Button("Enter"); 

     add(prompt); 
     add(input); 
     add(numDisplay); 
     add(button); 
     button.addActionListener(this); 

     populateArray(); 
     delayThread = new Thread(this); 
     delayThread.start(); 


    } 
    public void paint(Graphics g){ 

     if(backgroundColor == 1){ 
      setBackground (Color.green); 
     } 
     else if(backgroundColor == 2){ 
      setBackground (Color.red); 
     } 
    } 


    public void populateArray() { 
     GenerateNumbers a = new GenerateNumbers(); 
     myArray = a.returnArray(); 


     int count = 1; 
     for(int i = 0; i < myArray.length;i++){ 
      System.out.println("index: " + count + " : " + myArray[i]); 
      count++; 
      numDisplay.setText(" "); 
     } //for testing purpose 
    } 

    @Override 
    public void actionPerformed(ActionEvent e)throws StringIndexOutOfBoundsException { 
     String answer ="", newNumber=""; 
     String[] stringArray = new String[arrayCounter]; 
     int counterOne = 0, counterTwo = 2; 
     try{ 
      answer = input.getText(); 
      for(int i = 0; i < arrayCounter;i++){ 
       newNumber = answer.substring(counterOne, counterTwo); 
       stringArray[i] = newNumber; 
       counterOne += 3; 
       counterTwo += 3; 
      } 
     }catch(NumberFormatException ex){ 
      ex.printStackTrace(); 
     } 

     for(int i = 0; i < arrayCounter;i++){ 
      compare[i] = Integer.parseInt(stringArray[i]); 
     } 

     for(int i = 0; i < arrayCounter;i++){ 
      if(myArray[i] != compare[i]){ 
       backgroundColor = 2; 
       input.setText("Wrong"); 
       repaint(); 
      } 
      else{ 
       backgroundColor =1; 
       input.setText("RIGHT!");//testing 
       repaint(); 
      } 

     } 

    } 

    public void destroy(){ 
     running = false; 
    } 

    @Override 
    public void run() { 
     while(running){ 
      String numberString = "" ,stringTwo = " "; 
      for(int i = 0; i < arrayCounter;i++){ 
       numberString += myArray[i] + stringTwo; 
       numDisplay.setText(numberString); 
      } 
      try{ 
       delayThread.sleep(3500); 
      }catch(InterruptedException e){ 
       e.printStackTrace(); 
       Thread.currentThread().interrupt(); 
      } 
      numDisplay.setText(" "); 
      destroy(); 
     } 
    } 

} 

ответ

2

Перед тем, как позвонить answer.substring(counterOne, counterTwo), вы должны убедиться, что 0 <= counterOne < answer.length() и counterTwo <= answer.length().

substring будет кидать IndexOutOfBoundsException, если the beginIndex is negative, or endIndex is larger than the length of this String object, or beginIndex is larger than endIndex.

EDIT:

Давайте попробуем исправить ваши проблемы. Логика следующего цикла несовершенна:

 answer = input.getText(); 
     for(int i = 0; i < arrayCounter;i++){ 
      newNumber = answer.substring(counterOne, counterTwo); 
      stringArray[i] = newNumber; 
      counterOne += 3; 
      counterTwo += 3; 
     } 

Если я понял, что вы пытаетесь сделать, вы ожидаете, что входная строка (хранящаяся в answer), чтобы содержать числа, вы создаете массив из этих чисел, сравните его с массивом правильных чисел.

Однако вышеприведенный цикл может работать только в том случае, если ответ пользователя начинается с чего-то типа «11x22x33 ...», так как вы ожидаете извлечь подстроки из 2-х символов из этой входной строки из arrayCounter (= 3), и вы извлекают их из позиций (0,1) (3,4) (6,7) строки. Это означает, что если строка меньше 8 символов, вы получите StringIndexOutOfBoundsException.

Вам не следует делать предположения о длине чисел или числе чисел во входной строке. Лучшим и простым решением будет:

stringArray = answer.split(" "); 

Это разделило бы входной массив в пространствах. Обратите внимание, что длина полученного массива не обязательно будет соответствовать длине правильного ответа, поэтому вам придется сравнивать длины.

+0

Если мы также проверяем counterTwo больше counterOne? – StackFlowed

+0

@StackFlowed Да, мы должны, но это уже учтено в коде OP, поскольку counterOne инициализируется 0 и counterTwo до 2, и оба они увеличиваются на 3 на каждой итерации. – Eran

+0

Спасибо за это. И да, это то, что я пытался сделать, и полностью забыл, что существует «.split», я знал, что логика была ошибочной (что я делал предположение, что массив будет содержать числа в формате 11x22x33), но не знал, как реши это. Спасибо за помощь и совет! @Eran – Spatulord

0

IndexOutOfBoundsException будет происходить - если какой-либо из указанных ниже условий выполнены

`counterOne` is negative, or 
`counterTwo` is larger than the length of `answer`, or 
`counterOne` is larger than `counterTwo`. 

, прежде чем делать answer.substring(counterOne, counterTwo) вы можете сделать, как показано ниже

if (counterOne >= 0 && counterTwo < answer.length && counterOne <= counterTwo) 
Смежные вопросы