2012-05-14 2 views
0

제어 배경을 변경할 수있는 정적 클래스를 작성하려고합니다. 매개 변수에 전달됩니다. 그래서 나는이 달성 :비 최종 변수 및 타이머를 참조 할 수 없습니다.

public static void wrong(final Component component) { 

     component.setBackground(Color.RED); 
     Timer timer = new Timer(2, wrongAction); 

     wrongAction = new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 

       int green = component.getBackground().getGreen(); 
       int blue = component.getBackground().getBlue(); 
       component.setBackground(new Color(255, green + 1, blue + 1)); 
       if (component.getBackground() == Color.WHITE) { 
        timer.stop(); 
       } 
      } 
     }; 

     timer.start(); 

    } 

을 그리고 오류를 가지고 : 물론

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

, 우리는 마지막에 타이머를 변경할 수 있지만, 우리가 그렇게 후에 방법은 작동을 멈 춥니 다.
나는 그것을 시도하고 다른 stackoverflow 주제에 대한 답변을 찾으려고했지만 아무것도 도움이되지 않았다.

미리 감사드립니다.

+1

를 추가 한 다음 생성자에서 널을 통과 할 수 있습니다 (http://sscce.org/). BTW - 질문 있니? 이게 뭐야? –

+2

타이머를 마지막으로 만든 후에는 메소드가 작동을 멈추게합니까? –

+1

"최종 타이머 타이머 ="로 변경하십시오. 그것은 나를 위해 잘 작동합니다. – Adam

답변

4

문제는 다른 wrongAction 참조를 사용하는 것입니다.

public static void wrong(final Component component) { 

    component.setBackground(Color.RED); 
    Timer timer = new Timer(2, wrongAction);// <-- Here wrongAction is not the one you 
               // define on the next line 

    wrongAction = new ActionListener() { // <-- This is a new ActionListener but Timer 
             // has no knowledge about it. 
     @Override 
     public void actionPerformed(ActionEvent e) { 

      int green = component.getBackground().getGreen(); 
      int blue = component.getBackground().getBlue(); 
      component.setBackground(new Color(255, green + 1, blue + 1)); 
      if (component.getBackground() == Color.WHITE) { 
       timer.stop(); 
      } 
     } 
    }; 

    timer.start(); 

} 

타이머는 클래스의 변수와 청취자 수 될 수 있도록, 전용 개체의 모든 것을 캡슐화하는 더 나은 것, 다음 코드는 즉시 작동합니다 (그러나 나는 매우 깨끗를 찾을 수 없습니다)이를 참조 :

public static void wrong(final Component component) { 
     class MyActionListener implements ActionListener { 
      private Timer timer; 

      public void setTimer(Timer timer) { 
       this.timer = timer; 
      } 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       int green = component.getBackground().getGreen(); 
       int blue = component.getBackground().getBlue(); 
       component.setBackground(new Color(255, green + 1, blue + 1)); 
       if (component.getBackground().equals(Color.WHITE)) { 
        if (timer == null) { 
         System.err.println("This sucks, I got no timer"); 
        } else { 
         timer.stop(); 
        } 
       } 

      } 
     } 
     MyActionListener wrongAction = new MyActionListener(); 
     component.setBackground(Color.RED); 
     Timer timer = new Timer(2, wrongAction); 
     wrongAction.setTimer(timer); 


     timer.start(); 

    } 
+0

그건 내가 정말로 원했던거야! 정말 고맙습니다! –

+0

나는 이것이 내가 똑같은 일을했을 때 주변에 있었으면 좋겠다. 많이 혼란 스러울 때 내 스스로 알아낼 수밖에 없었다 : D – KChaloux

+0

+1 설명 및 접근 :) – Kshitij

1

wrongAction는 내부 클래스이며, 자바는 외부가 내부 클래스에 사용하기 위해 마지막이 될 필요가있는 지역 변수 정의가 필요합니다

final Timer timer = new Timer(2, wrongAction); 

wrongAction = new ActionListener() { 
    //... 
} 
1

당신이 다음 타이머 생성자에 wrongAction를 전달하는 것 실제로 그것을 초기화! 코드

wrongAction = new ActionListener() {... 
     }; 

Timer timer = new Timer(2, wrongAction); 

상기

이어야한다 ???

물론, Timer timer = null이 필요합니다. 상단

EDITED에서 : 어떻게 완전히 wrongAction를 제거하고 this-

final Timer timer = new Timer(2, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 

       int green = component.getBackground().getGreen(); 
       int blue = component.getBackground().getBlue(); 
       component.setBackground(new Color(255, green + 1, blue + 1)); 
       if (component.getBackground() == Color.WHITE) { 
        timer.stop(); 
       } 
      } 
     }); 

같은 간단한 유지에 대해;

+0

이 작동하지 않습니다, 당신은 여전히 ​​ActionListener 내에서 타이머를 참조 할 수 없습니다 –

+0

그냥 그 사건에서 최종 ... 내가하려고하는 지점은 "잘못된"이전에 또는 완전히 제거해야합니다 – Kshitij

+0

그것도 작동하지 않습니다. 컴파일러는 타이머가 아직 초기화되지 않았다고 불평 할 것입니다. –

0

는 당신이 [SSCCE] 게시, 더 빨리 더 나은 도움을 ActionListener

final Timer timer = new Timer(2,null); 

timer.addActionListener(new ActionListener(){ 
//... 
}); 
timer.start(); 
관련 문제