Grawl
Grawl

Reputation: 53

Can't change final variable inside AlertDialog

I've got the following code (it's not the full code, but the rest doesn't matter). I'm trying to set the boolean "ignoreLength" to either true or false based on what the user picks in an Alertdialog. However, when the code is like this, I get this error:

"Cannot refer to a non-final variable ignoreLength inside an inner class defined in a different method"

When I make it final, it changes to this:

"The final local variable ignoreLength cannot be assigned, since it is defined in an enclosing type"

How can I make it so I can change ignoreLength?

package com.grawl.passgen;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class PassGenActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {

    // Interface -- Default

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    // Interface -- Custom

    final Button button_generate = (Button) findViewById(R.id.button_generate);
    final EditText text_pass = (EditText) findViewById(R.id.textPassWord);
    final EditText edit_length = (EditText) findViewById(R.id.editLength);

    // Set up Arrays

    final String[] lowerCase;
    final String[] upperCase;
    final String[] numbers;
    final String[] symbols;

    // Fill Arrays

    createArray characters = new createArray();
    lowerCase = characters.getArrayLower();
    upperCase = characters.getArrayUpper();
    numbers = characters.getArrayNumbers();
    symbols = characters.getArraySymbols();


    // Pressing the button WOOOSH!

    button_generate.setOnClickListener(new View.OnClickListener() {

        **boolean ignoreLength = false;**

        public void onClick(View v) {

            // Set up parameters

            boolean lowerCaseEnabled = true; // needs interface option
            boolean upperCaseEnabled = true; // needs interface option
            boolean numbersEnabled = true; // needs interface option
            boolean symbolsEnabled = true; // needs interface option

            // Set up length based on input from EditText

            int length = 0;

            try {
                length = Integer.parseInt(edit_length.getText().toString());
            } catch(NumberFormatException nfe) {
                Toast.makeText(PassGenActivity.this, "Can't parse " + nfe, Toast.LENGTH_LONG).show();
            }

            if (length < 1) {
                length = 1; 
                edit_length.setText("1");
                Toast.makeText(PassGenActivity.this, "Password length can't be less than 1, set it to 1.", Toast.LENGTH_LONG).show();
                };

            if (length > 100) {
                AlertDialog.Builder alert = new AlertDialog.Builder(PassGenActivity.this);

                alert.setTitle("Warning");
                alert.setMessage("You are trying to create quite a long password, are you sure?");

                alert.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton) {
                      ignoreLength = true;
                      }
                    });


                alert.setNegativeButton("No", null);
                alert.show();  
            }

            Password password = new Password();
            password.fillPassword(lowerCase, upperCase, numbers, symbols);

            // Generate password

            password.setPassword(lowerCaseEnabled, upperCaseEnabled, numbersEnabled, symbolsEnabled, length);
            text_pass.setText(password.getPassword());
        }
    });

    }

}

Upvotes: 0

Views: 2821

Answers (3)

Ross Hambrick
Ross Hambrick

Reputation: 5940

You could move the boolean ignoreLength; declaration outside of the onClick to make it a member variable of the anonymous OnClickListener class.

Also, you could put the variable in something that holds it (like an array with one item) and update it that way. ignoreLength[0] = true;

Upvotes: 1

jjm
jjm

Reputation: 6198

You can't reassign local variables in java from an inner type. More here.

There are two ways to solve your problem. 1) Make ignore case a field on something--you could actually use the anonymous OnClickListener type, and give it the ignoreLength field, but I think generally you would want it to be a field on the top level class

2)
<superuglyhack>

final boolean[] ignoreLengthHolder= new boolean[]{ false };
...
ignoreLengthHolder[0] = true

</superuglyhack>

Upvotes: 1

Arpit Garg
Arpit Garg

Reputation: 8546

Firstly as per your question. "Can't change final variable inside AlertDialog" is wrong.

As making you clear that a final variable can never be changed as it's final and already declared at the time of creation.

Also in you case boolean ignoreLength = false; declare the variable outside and before the click listener and do not make it final. As you need to update ignoreLength value in future.

Upvotes: 1

Related Questions