Question

In my main class:

public class Main{
    public static void main(String[] args) {
    //some code
    final int number = 0;


    numberLabel.setText(number);

    Timer t = new Timer();

        t.scheduleAtFixedRate(new TimerTask(){
           public void run(){
           //elapsed time
               number = number + 1;
           }

        }, 1000, 1000);

   }

}

I am using the final int variable number to display into a label numberLabel the elapsed time. But i cannot access the final int variable inside the timer, error says:

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

I know i can update the label directly using numberLabel.setText() inside the run() however i need the number variable for some computations of time. How do i update the number variable? Thank you

Était-ce utile?

La solution

You should declare number as a class field, not a variable local to a method. This way it does not need to be final and can be used in anonymous inner classes.

I suggest that it not be made static and that you not use your Timer in a static environment but rather in the instance world.

public class Main{
    private int number = 0;

    public void someNonStaticMethod() {
      //some code
      // final int number = 0;

      numberLabel.setText(number);
      Timer t = new Timer();
      t.scheduleAtFixedRate(new TimerTask(){
           public void run(){
           //elapsed time
               number = number + 1;
           }

      }, 1000, 1000);
   }
}

As an aside, your use of numberLabel.setText(...) suggests that this will be used in a Swing GUI. If so, then don't use a java.util.Timer but rather you should use a javax.swing.Timer or Swing Timer.

public class Main2 {
  public static final int TIMER_DELAY = 1000;
  private int number = 0;

  public void someMethod() {
    numberLabel.setText(String.valueOf(number));
    new javax.swing.Timer(TIMER_DELAY, new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        number++;
        numberLabel.setText(String.valueOf(number));
      }
    }).start();
  }
}

Again if this is a Swing application (you don't say), then it is critical that the code run repeatedly by the Timer run on the Swing event thread, the EDT (Event Dispatch Thread). The java.util.Timer does not do this while the Swing Timer does.

Autres conseils

You cannot update a field declared final. On the other hand, you need to declare it final to be able to use it in an inner class. As you are doing multi-threading, you might want to use a final java.util.concurrent.atomic.AtomicInteger number; instead. This allows for assignment via set() in your TimerTask as well as basic thread-safety.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top