2010-03-25 2 views
3

각 셀에 버튼이 포함 된 큰 표가 있습니다. 이 단추는 매우 유사하며 거의 동일합니다. 나는이 방법으로 모든 버튼에 액션 청취자를 추가하는 경우 :ActionListener를 추가 할 수 있습니까? actionPerformed에 인수를 추가 할 수 있습니까?

tmp.addActionListener(new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent evt) { 
     proposition = proposition + action; 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      updatePropositionPanel(); 
     } 
     }); 
    } 
}); 

사실, 모든 액션 청취자는 action의 값에 의해 다른 모든 다르다. propositionupdatePropositionPanel은 클래스의 필드 및 메서드입니다.

  1. 처음에는 내부 클래스를 사용하지 않으면 짧게 만들 수 있다고 생각했습니다. 그래서 새로운 ActionListener 클래스를 프로그래밍하기로 결정했습니다. 그러나이 경우 "명제"가이 클래스의 인스턴스에 표시되지 않는다는 것을 깨달은 것보다.

  2. 그런 다음 actionPerformed 메서드를 현재 클래스에 추가하기로 결정했습니다. addActionListener(this). 그러나 actionPerformed 메서드에 인수를주는 방법을 알지 못한다는 것을 깨닫는 것보다.

그래서 어떻게 작동합니까? 짧고 우아하게 액션 리스너를 추가 할 수 있습니까?

ADDED :

나는 생성자에 지정된 인수를 사용할 수있는 몇 가지 인수 및 actioPerformed 방법을 취할 수 생성자와 내부 클래스를 프로그램 아이디어를 좋아했다. 나는 그렇게하기 시작했고 다른 내부 익명 클래스들 (위의 코드 에서처럼 사용됨)과 충돌을 일으킨다는 것을 깨달았다. 그래서 나는 다른 클래스 (내부 클래스가 아닌)를 만들 것이라고 생각합니다.

+0

각 버튼의 기능은 무엇입니까? –

+0

버튼을 클릭하면 버튼이 원래 위치에서 사라지고 새 장소에 나타납니다. 버튼은 플레이어 중 하나에 속할 수 있으며 클릭을 통해 다른 플레이어에게 제공 될 수있는 "칩"을 나타냅니다. – Roman

+0

내부 클래스가 익명 내부 클래스와 정확히 충돌한다는 것은 무엇을 의미합니까? – justkt

답변

4

: 리스너를 추가 할 수

호출은 다음과 같이 보일 것입니다. 예를 들어

public class MyActionListener 
{ 
    private int proposition; 
    private MyOtherClass moc; 

    public MyActionListener(int proposition, MyOtherClass moc) { 
     this.proposition = proposition; 
     this.moc = moc; 
    } 

    public void actionPerformed(ActionEvent evt) { 
     proposition += moc.action; 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       moc.updatePropositionPanel(); 
      } 
     }); 
    } 
} 

그런 다음 당신은 당신이 생성자에 원하는대로 인수를 전달 정상으로 추가 할 수 있습니다 :

tmp.addActionListener(new MyActionListener(proposition, this)); 
0

을 변경할 수있는 경우 옵션 1이 작동합니다 (예 : String 대신 StringBuilder). 옵션 2는 final이라고 선언하면 작동합니다. 이렇게하면 내부 클래스에서 액세스 가능/표시 가능합니다.

+0

그러나 actionPerformed의 인수 값은 어떤 버튼을 눌렀는지에 따라 달라집니다. – Roman

+0

작성시 인수로 지정하면됩니다. – BalusC

+0

나는 이해하지 못한다. 무엇을 만들었나요? 나는 무엇을 논증으로 규정 할까? 'action' 변수의 값은 모든 버튼에 따라 다릅니다.특정 값을 가진 최종 변수 "action"을 만들면 하나의 값이됩니다. 그리고 많은 버튼이 있습니다. 그들은 같은 가치를 볼 것이고 그들은 다른 가치를 가져올 필요가 있습니다. – Roman

0

MyActionListener 클래스를 별도로 만들고 생성자와 함께 두 값 proposition 및 action을 전달할 수 있습니다. 그것은 소스 코드를 선언합니다.

0

ActionListener를 구현하는 자체 수신기 클래스를 만들 수 있습니다. 이 클래스는 여러분이 말하는 매개 변수에 해당하는 멤버 변수를 포함 할 수 있습니다. 생성자를 사용하여 설정합니다. 당신은 당신의 자신의 클래스를 생성하고 생성자에 데이터를 전달할 수 있습니다

tmp.addActionListener(new MyActionListenerSubClass(proposition, action)); 
+0

ActionListener 클래스에 생성자를 사용할 수 있습니까? – Roman

+0

올바른 클래스 인 경우 원하는 모든 클래스에 생성자를 가질 수 있습니다 (예제에서 사용하는 것과 같은 익명의 내부 클래스와 반대). – Syntactic

1

편집을 : 나는 MyOuterClass 건설을 보여 클래스를 변경했다.

다음은 일부 코드입니다. 바라기를 이것은 당신의 1에 도착합니다, 그것은 제가 그것을 구현하는 방법입니다.

public class MyOuterClass { 
    // member variables for MyOuterClass 

    public MyOuterClass() { 
     // ...constructor stuff here 
    } 
    // ...outer class stuff here - methods, etc. 

    // The code each place you want to add the listener, somewhere in MyOuterClass 
    tmp.addActionListener(new MyActionListener(poposition, action)); 


    // below outer class stuff, although it can really be most places, I usually put 
    // it here - personal style preference. Swing's classes often put inner 
    // classes first 

    /** 
    * An inner class. 
    */ 
    private MyActionListener implements ActionListener { 
     /** 
     * Object used here as a filler, replace with appropriate 
     * class types 
     */ 
     private Object proposition; 
     private Object action; 

     private MyActionListener(Object proposition, Object action) { 
      this.proposition = proposition; 
      this.action = action; 
     } 
     public void actionPerformed(ActionEvent evt) { 
      proposition = proposition + action; 
      SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       updatePropositionPanel(); 
      } 
     } 
     /** 
     * Setters provided in case you need to change proposition and action. If not, 
     * feel free not to have them and to have final members 
     */ 
     private void setProposition(Object proposition) { 
      this.proposition = proposition; 
     } 
     private void setAction(Object action) { 
      this.action = action; 
     } 
    } 
} 

편집 : 당신이 당신의 편집의 요청으로, 다른 클래스를 만들 위와 같이 할 수 있지만, 멀리 또 다른 된 .java 파일과 코드가 아닌 개인 다른 클래스를 만들 수 있습니다.

+0

이 솔루션은 나에게 매력적입니다. 하나의 문제가 있습니다. 내부 클래스를 만들 수 없습니다. "외부"클래스가있는 동일한 파일에서 생성 할 수 있습니까? 그렇다면 "외부"클래스의'{...} '에 내부 클래스가 있어야합니까? 이 방법을 사용하면 컴파일러가 불평합니다. 그것은';'을 써야한다고 말한다. 내부 클래스의'{...} '뒤에';'을 써도 여전히 불평합니다. – Roman

+0

@Roman - 클래스를 수정하여 보통 내부 클래스를 만드는 방법을 보여줍니다. 세미콜론을 말할 때 내가 말하는 것에 대해 확신 할 수 없습니다. 세미콜론은 어디에 두었습니까? @Rahul G - 원래 포스터의 actionPerformed 메소드에서. – justkt

+0

답해 주셔서 감사합니다. 나는 그 문제를 발견했다. 다른 내부 클래스 간의 충돌 때문이었습니다 (원래 질문의 "ADDED"섹션에서 설명했습니다). 그래서 나는 다른 클래스 (안쪽 클래스가 아닌)를 프로그램하기로 결정했습니다. – Roman

0

이 예제에서는 명제 및 동작 변수가 문자열이라고 가정합니다.

public class DefaultPropositionUpdater implements PropositionUpdater { 
    public void updateProposition(final PropositionHolder holder, final String action) { 
     holder.setProposition(holder.getProposition() + action); 
    } 
} 

나는 PropositionHolder의 기본을 떠날거야 :

public interface PropositionUpdater() { 
    public void updateProposition(PropositionHolder holder, String action); 
} 

public interface PropositionHolder() { 
    public String getProposition(); 

    public void setProposition(String proposition); 
} 

public interface PropositionPanelUpdater() { 
    public void updatePropositionPanel(); 
} 

명제 업데이터의 기본 구현은 단순히 이것이다 : 인터페이스 PropositionUpdater, 인터페이스 PropositionPanelUpdater, 공동 작업자 제안 홀더를 정의 및 귀하의 상상력에 PropositionPanelUpdater;)

이제는 청취자가 있습니다 :

public class PropositionUpdaterActionListener implements ActionListener { 
    private PropositionHolder holder; 

    private PropositionUpdater updater; 

    private PropositionPanelUpdater panelUpdater; 

    public PropositionUpdaterActionListener(final PropositionHolder holder, final PropositionUpdater updater, final PropositionPanelUpdater panelUpdater) { 
     super(); 
     this.holder = holder; 
     this.updater = updater; 
     this.panelUpdater = panelUpdater; 
    } 

    public void actionPerformed(final ActionEvent evt) { 
     //Not sure how you *got* the action, but whatever... 
     updater.updateProposition(holder, action); 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       panelUpdater.updatePropositionPanel(); 
      } 
     }); 
    } 
} 
0

당신이 말하는 버튼의 개수를 말하지 않았습니다.

체스 보드 이하의 작은 숫자 인 경우 @ juskt의 접근 방식이 좋습니다.

public class MyActionListener { 
     public void actionPerformed(ActionEvent evt) { 
      JComponent c = (JComponent)evt.getSoource(); 
      int prop = (Integer)c.getclientProperty("PROPOSITION"); 
      int act = (Integer)c.getclientProperty("ACTION"); 
      SomeClass obj = c.getclientProperty("UPDATE"); 
      prop += act; 
      // If necessary, clientPut("PROPOSITION", prop); 
      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        obj.updatePropositionPanel(); 
       } 
      }); 
     } 
} 

이 액션 청취자가없는 상태를 유지하지 : 당신이 더 큰 무언가를 찾고 있다면

그러나, 나는이 방법을 사용합니다. 그 결과, 모든 버튼에 단일 인스턴스가 사용될 수 있습니다. Go 보드 (19x19)와 같은 경우, 361 대신 1 개의 오브젝트로 작동합니다.

1

유일한 차이는 action이므로 메소드 내에 코드를 삽입 할 수 있습니다. (또한 @Override는 불필요하고, += 여기에 유용합니다.) 당신은 어쨌든 AWT 이벤트 발송 쓰레드 (EDT)에있을 것 같은

public void setup(
    final AbstractButton button, 
    final int action 
) { 
    button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent evt) { 
      proposition += action; 
      EventQueue.invokeLater(new Runnable() { 
       public void run() { 
        updatePropositionPanel(); 
       } 
      }); 
     } 
    }); 
} 

invokeLater 아마 무의미하다.

일반적인 용도의 작업을 많이 추가하는 경우 관련된 무의미한 이벤트 개체가없는 인터페이스를 사용하여 단순하게 만들 수 있습니다.

해킹하고 싶다면 하위 클래스 생성자에 리스너를 추가 할 수 있습니다.

new ActionHandler(button) { public void action() { 
     proposition += action; 
     updatePropositionPanel(); 
    }}); 

JDK7은 이러한 종류의 Java 구문을 간결하게 만듭니다. 그러나 Java는 항상 다소 장황합니다.

관련 문제