title: Error in Android/Eclipse code
body: <p>I have a project due and I cannot find my error. Please take pity on a finals week idiot. :) Android/Eclipse project has errors. I think it's a missed } but I can't seem to find it. Entire project is here: <a href="http://www.andrewadcock.com/flag.zip" rel="nofollow">http://www.andrewadcock.com/flag.zip</a>  Though I think it's just an error in the code below. Thank you very much for any help, I've spent about 4 hours looking for the issue(s).</p>
  
  <p>First error is on line 306.</p>
  
  <pre><code>//FlagQuizGame.java
  //Main Activity Flag Quiz game app
  package com.deitel.flagquizgame;
  
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Random;
  import java.util.Set;
  
  import android.app.Activity;
  import android.app.AlertDialog;
  import android.app.AlertDialog.Builder;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.content.res.AssetManager;
  import android.graphics.drawable.Drawable;
  import android.os.Bundle;
  import android.os.Handler;
  import android.util.Log;
  import android.view.LayoutInflater;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.View.OnClickListener;
  import android.view.animation.Animation;
  import android.view.animation.AnimationUtils;
  import android.widget.Button;
  import android.widget.ImageView;
  import android.widget.TableLayout ;
  import android.widget.TableRow;
  import android.widget.TextView;
  
  public class FlagQuizGame extends Activity
  {
      // String used when logging error messages
      private static final String TAG = "FlagQuizGame Activity" ;
  
      private List&lt;String&gt; fileNameList; //flag filenames
      private List&lt;String&gt; quizCountriesList;// names of countries
      private Map&lt;String, Boolean&gt; regionsMap; //enabled regions
      private String correctAnswer; // correct country per current flag
      private int totalGuesses; // guesses made
      private int correctAnswers; // correct guesses
      private int guessRows; // no. of rows w/ choices
      private Random random; // random number gen
      private Handler handler; //used to delay next flag load
      private Animation shakeAnimation ; //incorrect guess animation
  
      private TextView answerTextView ; // Displays In/Correct
      private TextView questionNumberTextView; //shows current question #
      private ImageView flagImageView ; //displays a flag
      private TableLayout buttonTableLayout; // table of answer buttons
  
      // called upon creation
      @Override
      public void onCreate(Bundle savedInstanceState)
      {
          super.onCreate(savedInstanceState); //call superclass method
          setContentView(R.layout.main); //inflate GUI
  
          fileNameList = new ArrayList&lt;String&gt;();
          quizCountriesList = new ArrayList&lt;String&gt;();
          regionsMap = new HashMap&lt;String, Boolean&gt;();
          guessRows = 1; //default to one row of choices
          random = new Random(); //initialize the random number gen.
          handler = new Handler(); // performs delayed oper.
  
          //load shake animation for incorrect guesses
          shakeAnimation = 
              AnimationUtils.loadAnimation(this, R.anim.incorrect_shake);
          shakeAnimation.setRepeatCount(3);//animation repeats 3 times
  
          //get array of world regions from strings.xml
          String[] regionNames =
              getResources().getStringArray(R.array.regionsList);
  
          //by default countries are all chosen from all regions
          for (String region : regionNames)
              regionsMap.put(region, true);
  
          //get references to GUI components
          questionNumberTextView = 
              (TextView) findViewById(R.id.questionNumberTextView);
          flagImageView = (ImageView) findViewById(R.id.flagImageView);
          buttonTableLayout = 
                  (TableLayout) findViewById(R.id.buttonTableLayout);
          answerTextView = (TextView) findViewById(R.id.answerTextView);
  
          //set questionNumberTextView's text
          questionNumberTextView.setText(
              getResources().getString(R.string.question) + " 1 " +
              getResources().getString(R.string.of) + " 10");
  
          resetQuiz(); // start quiz anew
      }//end of method onCreate
  
      //set up &amp; start next quiz
      private void resetQuiz()
      {
          //use the AssetManage to get image flag
          //file names for the enabled regions
          AssetManager assets = getAssets(); //get the app's AssetManager
          fileNameList.clear(); //empty list
  
          try
          {
              Set&lt;String&gt; regions = regionsMap.keySet();
  
              //loop through each region
              for (String region : regions)
              {
                  if (regionsMap.get(region))//if region is enabled
                  {
                      //get list of all flag image files in this region
                      String[] paths = assets.list(region);
  
                      for (String path : paths)
                          fileNameList.add(path.replace(".png", ""));
                  }//end if
              }//end for
          }//end try
          catch (IOException e)
          {
              Log.e(TAG, "Error loading image file names", e);
          }//end catch
  
          correctAnswers = 0; //reset the number of correct answers to 0
          totalGuesses = 0; //reset the total number of guesses to 0
          quizCountriesList.clear();//clear the prior list
  
          //add 10 random file names the quizCountriesList
          int flagCounter = 1;
          int numberOfFlags = fileNameList.size();//get number of flags
  
          while (flagCounter &lt;= 10)
          {
              int randomIndex = random.nextInt(numberOfFlags);//random index
  
              //get random file name
              String fileName = fileNameList.get(randomIndex);
  
              //if the region is enabled and it hasn't already been chosen
              if (!quizCountriesList.contains(fileName))
              {
                  quizCountriesList.add(fileName);
                  ++flagCounter;
              }//end if
          }//end while
  
          loadNextFlag();//start the quiz by loading the first flag
      }//end method resetQuiz
  
      //after user guesses a correct flag, load the next one
      private void loadNextFlag()
      {
          //get file name of next flag and remove it from list
          String nextImageName = quizCountriesList.remove(0);
          correctAnswer = nextImageName; //update the correct answer
  
          answerTextView.setText(""); //clear answerTextView
  
          //displays the number of current question
          questionNumberTextView.setText(
              getResources().getString(R.string.question) + " " +
              (correctAnswers + 1) + " " +
              getResources().getString(R.string.of) + " 10");
  
          //extract the region from the next image's name
          String region =
              nextImageName.substring(0, nextImageName.indexOf('~'));
  
          //use AssetManager to load next image from assets folder
          AssetManager assets = getAssets();
          InputStream stream; //used to read flag images
  
          try
          {
              //get an InputStream to the asset representing the next flag
              stream = assets.open(region + "/" + nextImageName + ".png");
  
              //load the asset as a drawable display on the flagImageView
              Drawable flag = Drawable.createFromStream(stream, nextImageName);
              flagImageView.setImageDrawable(flag);
          }//end try
          catch (IOException e)
          {
              Log.e(TAG, "Error loading "+ nextImageName, e);
          }//end catch
  
      // clear prior answer Buttons f r om TableRol'I'!oo
      for (int row = 0; row &lt; buttonTableLayout.getChildCount(); ++row)
          ((TableRow) buttonTableLayout.getChildAt(row)).removeAllViews();
  
      Collections.shuffle(fileNameList);
  
      //put the correct answer aht the end of FileNameList
      int correct = fileNameList.indexOf(correctAnswer);
      fileNameList.add(fileNameList.remove(correct));
  
      //get a reference to the LayoutInflater service
      LayoutInflater inflater = (LayoutInflater) getSystemService(
          Context.LAYOUT_INFLATER_SERVICE);
  
      // add 3, 6, or 9 answer buttons based on the value of guess rows
      for (int row = 0; row &lt; guessRows; row++)
      {
          TableRow currentTableRow = getTableRow(row);
  
      //place Buttons in currentTableRow
          for (int column = 0; column &lt; 3; column ++)
          {
              //inflate guess_button.xml to create new Button
              Button newGuessButton = 
                  (Button) inflater.inflate(R.layout.guess_button, null);
  
              //get country name and set it as newGuessButton's text
              String fileName = fileNameList.get((row * 3) + column);
              newGuessButton.setText(getCountryName(fileName));
  
              //register answerButtonListener to respond to button
              newGuessButton.setOnClickListener(guessButtonListener);
              currentTableRow.addView(newGuessButton);
          }//end for
      } //end for
  
          //randomly replace on Button with the correct answer
          int row = random.nextInt(guessRows);//pick random row
          int column = random.nextInt(3);//pick random column
          TableRow randomTableRow = getTableRow(row); // get the table row
          String countryName = getCountryName(correctAnswer);
          ((Button)randomTableRow.getChildAt(column)).setText(countryName);
      }
  
      //returns the specified TableRow
      private TableRow getTableRow(int row)
      {
          return (TableRow) buttonTableLayout.getChildAt(row);
      }//end method getTableRow
  
      //parses the country flag file name and returns the country name
      private String getCountryName(String name)
      {
          return name.substring(name.indexOf('-') + 1).replace('_', ' ');
      }//end method getCountryName
  
      // called when the user selects an answer
      private void submitGuess(Button guessButton)
      {
          String guess = guessButton.getText().toString();
          String answer = getCountryName(correctAnswer);
          ++totalGuesses; //increment the number of guesses the user has made
  
          //if the guess is correct
          if (guess.equals(answer))
          {
              ++correctAnswers; //increment score
  
              //display "Correct!" in the green text
              answerTextView.setText(answer + "!");
              answerTextView.setTextColor(
                  getResources().getColor(R.color.correct_answer));
  
              disableButtons(); //disable all answer buttons
  
              //if the user has correctly identified 10 flags
              if (correctAnswers == 10)
              {
                  //create an AlertDialog Builder
                  AlertDialog.Builder builder = new AlertDialog.Builder(this);
  
                  builder.setTitle(R.string.reset_quiz);//title bar string
  
                  //set AlertDialog's message to display game results
                  builder.setMessage(String.format("%d %s, %.02f%% %s",
                      totalGuesses, getResources().getString(R.string.guesses),
                      (1000 / (double) totalGuesses),
                      getResources().getString(R.string.correct)));
  
                  builder.setCancelable(false);
  
                  //add "Reset Quiz" Button
                  builder.setPositiveButton(R.string.reset_quiz,
                      new DialogInterface.OnClickListener()
                      {
                          public void onClick(DialogInterface dialog, int id)
                          {
                              resetQuiz();
                          }//end method OnClick
                      }//end anon. inner class
                  );//end call to setPositiveButton
  
      //create AlertDialog from the Builder
          AlertDialog resetDialog = builder.create();
          resetDialog.show(); //display the Dialog
      } //end if
      else //answer is correct but quiz is incomplete
      {
          //load the next flag after 1second delay
          handler.postDelayed(
              new Runnable()
              {
                  @Override
                  public void run()
                  {
                      loadNextFlag();
                  }
              }, 1000); // 1000 milliseconds for 1-second delay
          }//end else
      }//end if
      else // guess was incorrect
      {
          //play the animation
          flagImageView.startAnimation(shakeAnimation);
  
          //display "Incorrect!" in red
          answerTextView.setText(R.string.incorrect_answer);
          answerTextView.setTextColor(
              getResources().getColor(R.color.incorrect_answer));
          guessButton.setEnabled(false);//disable the incorrect answer
      }//end else
      }//end method submitGuess
  
      //utility method disables all answer buttons
      private void disableButtons()
      {
          for (int row = 0; row &lt; buttonTableLayout.getChildCount(); ++row)
          {
              TableRow tableRow = (TableRow) buttonTableLayout.getChildAt(row);
              for (int i = 0; i &lt; tableRow.getChildCount(); ++i)
                  tableRow.getChildAt(i).setEnabled(false);
          }//end outer for
      }//end method disableButtons
  
      //create constants for each menu id
      private final int CHOICES_MENU_ID = Menu.FIRST;
      private final int REGIONS_MENU_ID = Menu.FIRST + 1;
  
      //called when the user accesses the options menu
      @Override
      public boolean onCreateOptionsMenu(Menu menu)
      {
          super.onCreateOptionsMenu(menu);
  
          //add two options to the menu - "Choices" and "Regions"
          menu.add(Menu.NONE, CHOICES_MENU_ID, Menu.NONE, R.string.choices);
          menu.add(Menu.NONE, REGIONS_MENU_ID, Menu.NONE, R.string.regions);
  
          return true; //display the menu
      }//end method onCreateOptionsMenu 
  
      //called when the user selects an option from the menu
      @Override
      public boolean onOptionsItemSelected(MenuItem item)
      {
          //switch the menu id of the user-selected option
          switch (item.getItemId())
          {
          case CHOICES_MENU_ID:
              //create a list of the possible numbers of answer choices
              final String[] possibleChoices =
                  getResources().getStringArray(R.array.guessesList);
  
              //create a new AlertDialog Builder and set its title
              AlertDialog.Builder choicesBuilder =
                  new AlertDialog.Builder(this);
              choicesBuilder.setTitle(R.string.choices);
  
              //add possibleChoices items to the dialog and set the
              //behavior for when one of them is clicked
              choicesBuilder.setItems(R.array.guessesList,
                  new DialogInterface.OnClickListener()
                  {
                      public void onClick(DialogInterface dialog, int item)
                      {
                          //update guessRows to match the user's choice
                          guessRows = Integer.parseInt(
                              possibleChoices[item].toString()) / 3;
                          resetQuiz(); //reset the quiz
                      }//end method onClick
                  }//end anon. inner class
              ); //end call to setItems
  
              //create an AlertDialog from the Builder
              AlertDialog choicesDialog = choicesBuilder.create();
              choicesDialog.show(); // show the Dialog
              return true;
  
          case REGIONS_MENU_ID:
              //get array of world regions
              final String[] regionNames = 
                  regionsMap.keySet().toArray(new String[regionsMap.size()]);
  
              //boolean array representing whether each region is enabled
              boolean[] regionsEnabled = new boolean[regionsMap.size()];
              for (int i=0; i &lt; regionsEnabled.length;++i)
                  regionsEnabled[i] = regionsMap.get(regionNames[i]);
  
              //create an AlertDialog Builder and set the dialog's title
              AlertDialog.Builder regionsBuilder = 
                  new AlertDialog.Builder(this);
              regionsBuilder.setTitle(R.string.regions);
  
              //replace_with the space in the region names for display purposes
              String[] displayNames = new String[regionNames.length];
              for(int i=0; i&lt;regionNames.length; ++i)
                  displayNames[i]=regionNames[i].replace('_',' ');
  
          //add displayNames to the Dialog and set behavior
          //when one of the new items is clicked
          regionsBuilder.setMultiChoiceItems(
              displayNames, regionsEnabled,
              new DialogInterface.OnMultiChoiceClickListener()
              {
                  @Override
                  public void onClick(DialogInterface dialog, int which,
                      boolean isChecked)
                  {
                      //include ot exclude the clicked region
                      //depending on whether or not it's checked
                      regionsMap.put(
                          regionNames[which].toString(), isChecked);
                  }//end method onClick
              }//end anon. inner class
          );//end call to setMultiChoiceItems
  
      //resets quiz when user presses "Reset Quiz" button
      regionsBuilder.setPositiveButton(R.string.reset_quiz,
          new DialogInterface.OnClickListener()
          {
              @Override
              public void onClick(DialogInterface dialog, int button)
              {
                  resetQuiz();//reset the quiz
              }//end method OnClick
          }//end anon. inner class
      );//end call to method setPositiveButton
  
          //create a dialog from the Builder
          AlertDialog regionsDialog = regionsBuilder.create();
          regionsDialog.show();//display the Dialog
          return true;
      }// end switch
  
          return super.onOptionsItemSelected(item);
      }//end method onOptionsItemSelected
          //called when a guess Button is touched
          private OnClickListener guessButtonListener = OnClickListener()
          {
              @Override
              public void onClick(View v)
              {
                  submitGuess((Button) v);//pass selected button to submitGuess
              }//end method onClick
          };//end answerButtonListener
  }//end FlagQuizGame
  </code></pre>