Create Runnable with "final" variable from the parent?

70 Views Asked by At

Create multiple new Runnable inside a loop ?

I want to create multiple new instances of Runnable that calls another method and passing the "i" parameter from the parent's loop.

I do not want to use Threads since those runnables will be used as actions for keyboard shortcuts (using KeyCombination and accelerators). (ex: Ctrl + 1, Ctrl + 2, ... Ctrl + 9)

The content of the runnable that I want looks like this :

if (shortcutsEnabled && checkDestinationValidity(i)) {
    copyImage(i);
}

possibly important : the number of "i" will go up to 9.

Is there any way to do this without having to make a premade table of Runnable ?

When I try to just put the variable inside, the NetBeans IDE shows me this message : local variables referenced from a lambda expression must be final or effectively final

I have found a solution that has delayed my "deadline" for the solution :

for (int i = 0; i < copyKeyCombinations.size(); i++) {
    final int index = i;
    Runnable copyRunnable = ()-> {
        if (shortcutsEnabled && checkDestinationValidity(index)) {
            copyImage(index);
        }
    };
    accelerators.put(copyKeyCombinations.get(i), copyRunnable);
}

For the record, the runnable are registered before the loop ends, and the solution above works but I was asked to find another solution

However, this is a solution that is not accepted for my work situation, I am looking for any alternatives.

(Note : this loop will only be launched one time, at the start of the app).

1

There are 1 best solutions below

4
Chaosfire On BEST ANSWER

You can implement Runnable the "standard" way, as a class, not as lambda function:

public class CopyRunnable implements Runnable {

  private final int index;
  private final boolean shortcutsEnabled;

  public CopyRunnable(int index, boolean shortcutsEnabled) {
    this.index = index;
    this.shortcutsEnabled = shortcutsEnabled;
  }

  @Override
  public void run() {
    if (shortcutsEnabled && checkDestinationValidity(index)) {
      copyImage(index);
    }
  }
}
for (int i = 0; i < copyKeyCombinations.size(); i++) {
  Runnable copyRunnable = new CopyRunnable(i, shortcutsEnabled);
  //do something with it
}