2016-06-14 1 views
0

카드는 JButton이고, 나는 세계에 추가 할 때 각각에 actionListener를 추가하려고합니다. 카드는 2D 배열에 있고 for 루프와 함께 추가하고 있습니다. 그러나 actionListener 클래스에서 table [r] [c]를 사용할 때 "내부 클래스에서 참조되는 로컬 변수가 final 또는 effective final이어야합니다."라는 오류가 발생하기 때문에 특정 카드를 가져올 수 없습니다. 그러나 그것은 for 루프이기 때문에 나는 그것을 최종으로 만들 수 없습니다. 도움이 될 것입니다내부 클래스의 "for 루프"에서 정수 참조하기

for(int r = 0;r<2;r++){ 
     for(int c=0;c<5;c++){ 
      int rNum = gen.nextInt(cards.size()); 

      table[r][c]= new Card("deck",cards.get(rNum), 2); 
      cards.remove(rNum); 
      add(table[r][c]); 
      table[r][c].addActionListener(
       new ActionListener() 
       { 
        public void actionPerformed(ActionEvent event){ 
         BufferedImage img2 = null; 
         BufferedImage img = null; 
         int pos = table[r][c].getName().indexOf("."); 
         String s = table[r][c].getName().substring(0,pos) + "S" + table[r][c].getName().substring(pos, table[r][c].getName().length()); 
         try{ 
          img = ImageIO.read(new File(table[r][c].getPat()+"/"+table[r][c].getName())); 
         }catch(IOException e){ 
          e.printStackTrace(); 
         } 
         try{ 
          img2 = ImageIO.read(new File(table[r][c].getPat()+"/"+s)); 
         }catch (IOException e){ 
          e.printStackTrace(); 
         }     
         if(!table[r][c].isAlive()){ 
          ImageIcon imgFace2 = new ImageIcon(img2); 
          table[r][c].setIcon(imgFace2); 
          table[r][c].changeState(); 
          number++; 
         }else{ 
          ImageIcon imgFace = new ImageIcon(img); 
          table[r][c].setIcon(imgFace); 
          table[r][c].changeState(); 
          number--; 
         }   
        } 
       } 
      ); 
+0

인라인으로 구현하는 대신 ActionListener의 최상위 클래스를 만드는 것이 좋습니다. 그런 다음 필요한 클래스를 해당 클래스의 생성자에 전달할 수 있습니다. –

+0

그러나 for 루프에 새로운 최종 변수를 만들 수 있습니다. – tkausl

+0

그리고 자바 8 믿을 최종 변수를 인라인 클래스에 전달할 수 있습니다. – RobotKarel314

답변

0

ActionListener에 인수로 숫자를 전달할 수 있습니다. 예 :

table[r][c].addActionListener(new Listener(r, c)); 
... 

private class Listener implements ActionListener 
{ 
    private int myR, myC; 
    public Listener(int r, int c) 
    { 
     myR = r; 
     myC = c; 
    } 
    public void actionPerformed(ActionEvent event) 
    { 
     //referece myR and myC here 
     //e.g. table[myR][myC].changeState(); 
    } 
} 
0

빠른 수정은 내부 변수가 액세스 할 수있는 최종 변수에 루프 변수를 할당하는 것입니다.

for(int loopR = 0;r<2;r++){ 
     for(int loopC=0;c<5;c++){ 
      final int r = loopR; 
      final int c = loopC; 
      // the rest of your code, using r and c 
      // rather than loopR and loopC 
     } 
} 

그러나 R과 C 매개 변수를 사용하여 새 클래스를 추출

읽고 새로운 변수를 도입보다 이해하기 더 쉬울 것입니다.

+0

나는이 대답을 좋아한다. – RobotKarel314