Thomas
Thomas

Reputation: 337

Variable is accessed from within inner class needs to be declared final

I know the topic sounds like a dupplicate, but I am not trying to debug this issue here but to get around it.

What my program is supposed to do is : For every file there is in a folder, create a new button. If you click on this button, put in the intent extra the name of the folder you've just entered.

 File directory = new File(prefs.getString("path",null));
 File[] files = directory.listFiles();
        for (File file :files){
            if(file.isDirectory()) {
                buttons.add(new Button(this));
                Button button = buttons.get(buttons.size() - 1);
                String fileName = file.getName();

                button.setText(fileName);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(currentActivity, EOChoiceActivity.class);
                        intent.putExtra("fileExtension",fileName);
                        startActivity(intent);
                    }
                });
                layout.addView(button);
            }
        }

Now the problem I have is that the "fileName" variable needs to be put in final, due to Java giving the pointer of the object and not the value itself. But if I do so, only the last fileName selected will be sent for any button.

Upvotes: 2

Views: 10322

Answers (2)

Ben P.
Ben P.

Reputation: 54204

You can just go ahead and make fileName final. I know you think that this will cause problems, but it won't.

the "fileName" variable needs to be put in final, due to Java giving the pointer of the object and not the value itself. But if I do so, only the last fileName selected will be sent for any button.

On each iteration through the loop, you're declaring a different String instance. Each one will be final, but they will not be "shared" across loop iterations.

I made a tiny app that iterated over an array of Strings, doing something very similar to your code. Despite declaring my String as final, each button still toasts a different name when I click it.

for (int i = 0; i < names.length; i++) {
    final String name = names[i];

    Button button = new Button(this);
    button.setText(name);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show();
        }
    });

    root.addView(button);
}

Upvotes: 5

ρяσѕρєя K
ρяσѕρєя K

Reputation: 132972

No need to declare fileName final.

Because you are setting fileName as text to Button. So use getText using v parameter of onClick to get file name on Button click.like

...
intent.putExtra("fileExtension",((Buttton)v).getText().toString());
...

Or you can also do it using setTag()/getTag() method's of button Button.

Upvotes: 2

Related Questions