java - Android/Eclipse 代码错误

标签 java android eclipse dictionary

我有一个项目到期,但我找不到我的错误。请可怜一个 final 周的白痴。 :) Android/Eclipse 项目有错误。我认为这是一个错过的 } 但我似乎找不到它。整个项目在这里:http://www.andrewadcock.com/flag.zip虽然我认为这只是下面代码中的一个错误。非常感谢您的帮助,我花了大约 4 个小时寻找问题。

第一个错误出现在第 306 行。

//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<String> fileNameList; //flag filenames
    private List<String> quizCountriesList;// names of countries
    private Map<String, Boolean> 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<String>();
        quizCountriesList = new ArrayList<String>();
        regionsMap = new HashMap<String, Boolean>();
        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 & 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<String> 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 <= 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 < 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 < guessRows; row++)
    {
        TableRow currentTableRow = getTableRow(row);

    //place Buttons in currentTableRow
        for (int column = 0; column < 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 < buttonTableLayout.getChildCount(); ++row)
        {
            TableRow tableRow = (TableRow) buttonTableLayout.getChildAt(row);
            for (int i = 0; i < 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 < 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<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

最佳答案

如果您让 Eclipse 重新格式化您的所有代码,我想您会发现问题。我怀疑它位于第 210-229 行左右:

for (int row = 0; row < guessRows; row++)
{
    TableRow currentTableRow = getTableRow(row);
}
//place Buttons in currentTableRow
    for (int column = 0; column < 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

请注意第一个简短的 for 循环之后的缩进是如何错误的(它只是声明了一个变量,然后不对其执行任何操作。

我的猜测是你的意思不是第四行的右大括号。但尝试自己解决此类问题非常重要。我建议:

  • 总是在 if/for/etc 语句中使用大括号,即使正文只是一行
  • 您要求 Eclipse 为您格式化代码,特别是当您遇到这样的问题时
  • 你试图让你的方法更短;这使得更容易发现问题

关于java - Android/Eclipse 代码错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8455167/

相关文章:

java - 使用 eclipse 调试 Maven 构建的更短方法

java - 如何使用 gwt 打开 .exe 文件?

java - 如何从彼此不关注的数字池中生成一个随机数

android使 View 包装内容但不大于特定大小

java - 开始 Activity 并保持之前的 Activity 数据完好无损

java - 如何从 Java HttpServer 流式传输 M-JPEG?

android - 使用位置更改 PagerTabStrip 的背景颜色

java - javadoc方法中的变量类型eclipse

java - 广播 Intent 已取消。安卓系统

java - Eclipse ANT Build.xml 创建 JAR 显示损坏的文件