2009-05-03 2 views
3

양식 요소에서 입력 한 정보를 가져와 정보를 조작해야하는 GUI를 설정하고 있습니다. 이를 위해서는 다른 요소에 액세스 할 때 일부 요소를 사용해야합니다.다른 요소에 액세스하기 위해 리스너를 어떻게 사용할 수 있습니까?

예를 들어 입력 상자 (JTextField)와 단추 (JButton)가 있습니다. 버튼을 누르면 입력 상자에 입력 된 텍스트를 조작 할 수 있어야합니다. 이 일을 처리하기 위해 내가 지금까지 시도한 모든 것은 실패했다.

이 지금 (내가 코멘트에 내 질문에 포함 된 것)처럼 내 코드는 모습입니다 : 어떤 도움

public class MyClass 
{ 
    public static void main(String args[]) 
    { 
     // Form elements are in here 
     JTextField myTextField = new JTextField(10); 
     JButton myTextFieldSubmit = new JButton("Submit"); 
     myTextFieldSubmit.addActionListener(new ListenerClass()); 
    } 
} 

class ListenerClass implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     // This is what happens when these elements are used 
     // I need to be able to access the form elements from MyClass in here, but this doesn't seem possible with my current setup 
     // For example, when the Submit button is pressed, I need to be able to myTextField.getText() and edit MyClass members 
     // How should my setup be changed to accommodate these needs? 
    } 
} 

감사합니다!

답변

3

이것은 매우 다양한 범위 문제입니다.

현재 텍스트 필드와 버튼은 main 메서드의 범위에 있으므로 ActionListener에 대한 별도의 클래스를 사용하면 해당 변수에 액세스 할 수 없습니다.

이를 달성하기 위해 몇 가지 방법이 있습니다 :

(1) MyClass에서 내부 클래스 ListenerClass을 확인하고 MyClass의 인스턴스 필드에 myTextFieldmyTextFieldSubmit을 켜십시오.

public class MyClass 
{ 
    final static JTextField myTextField = new JTextField(10); 
    final static JButton myTextFieldSubmit = new JButton("Submit"); 

    public static void main(String args[]) 
    { 
    myTextFieldSubmit.addActionListener(new ListenerClass()); 
    } 

    static class ListenerClass implements ActionListener 
    { 
    public void actionPerformed(ActionEvent e) 
    { 
     myTextField.setText(""); 
    } 
    } 
} 

(2) main 방법에 익명의 내부 클래스를 확인하고이 그들이 final을 선언으로 myTextFieldmyTextFieldSubmit만큼, 같은 장소에 남아있게됩니다.

public class MyClass 
{ 
    public static void main(String args[]) 
    { 
    final JTextField myTextField = new JTextField(10); 
    final JButton myTextFieldSubmit = new JButton("Submit"); 

    myTextFieldSubmit.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) 
     { 
      myTextField.setText(""); 
     } 
    }); 
    } 
} 

(3) main 방법에 로컬 로컬 클래스를 확인. 다시 말하지만 내부 클래스의 액세스를 허용하려면 텍스트 필드와 버튼을 final으로 선언해야합니다.

public class MyClass 
{ 
    public static void main(String args[]) 
    { 
    final JTextField myTextField = new JTextField(10); 
    final JButton myTextFieldSubmit = new JButton("Submit"); 

    class ListenerClass implements ActionListener 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
     myTextField.setText(""); 
     } 
    } 

    myTextFieldSubmit.addActionListener(new ListenerClass()); 
    } 
} 

(4) 생성자 예컨대 ListenerClass에 참조를 나눠주고, 또한 myTextFieldmyTextFieldSubmit과 인스턴스 변수를 결정.

public class MyClass 
{ 
    JTextField myTextField = new JTextField(10); 
    JButton myTextFieldSubmit = new JButton("Submit"); 

    public MyClass() 
    { 
    myTextFieldSubmit.addActionListener(new ListenerClass(this)); 
    } 

    public static void main(String args[]) 
    { 
    new MyClass(); 
    } 
} 

class ListenerClass implements ActionListener 
{ 
    MyClass myClass; 

    public ListenerClass(MyClass myClass) 
    { 
    this.myClass = myClass; 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
    myClass.myTextField.setText(""); 
    } 
} 

(5) static 필드에 myTextFieldmyTextFieldSubmit을 확인하고 ListerClass에서 직접 액세스 할 수 있습니다.

public class MyClass 
{ 
    static JTextField myTextField = new JTextField(10); 
    static JButton myTextFieldSubmit = new JButton("Submit"); 

    public static void main(String args[]) 
    { 
    myTextFieldSubmit.addActionListener(new ListenerClass()); 
    } 
} 

class ListenerClass implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
    MyClass.myTextField.setText(""); 
    } 
} 

이 방법은 아직 많이있을 수 있으며이를 구현하는 데 더 좋은 방법이있을 수 있습니다. 어떤 접근 방식을 택할지는 응용 프로그램의 원하는 디자인에 따라 달라집니다.

+0

감사! 나는 이것을 (적어도 나를 위해)하는 가장 간결한 방법이라고 생각하기 때문에 (2)를 사용할 것이다. :) –

+1

나는 (2)도 좋아하는 경향이 있으며, 동일한 작업이 수행되는 여러 인스턴스가없는 한 제대로 작동하는 것으로 나타났습니다. 그러나 익명의 클래스는 다른 클래스 나 메서드에서 액세스 할 수 없으므로 단점이있을 수 있음을 지적해야합니다. (경우에 따라 구현 세부 사항을 숨기는 등 긍정적 인 결과를 가져올 수 있습니다.) – coobird

0

생성자의 MyClass에 대한 참조를 ListenerClass으로 전달할 수 있습니다.

0

사용자의 문제점은 Java의 모든 목적을 위해 리스너를 사용하는 것입니다. 핸들러가 리스너 또는 동료를 통지 한 객체에 액세스하게하는 방법.

일반적으로 두 가지 규칙이 있습니다.

하나는 이벤트 개체에서 개체를 직접 가져 오는 것입니다. getSource()를 사용하여이 작업을 수행 할 수 있습니다. 그러나 그런 다음에야 위젯을 만들 수 있습니다.

또 다른 옵션은 수신기 클래스가 위젯에 액세스 할 수있게하는 것입니다. 한 가지 방법은 정적이 아닌 내부 클래스를 사용하는 것입니다 (선언하는 방법에 따라 다름).이 경우 포함하는 클래스의 멤버에 액세스 할 수 있습니다.

그러나이 경우 위젯은 변수가 아니라 구성원입니다 (정말로 하시겠습니까?). 따라서 유일한 해결책은 Listener 클래스에서 멤버를 보유한 다음 addListener 호출에서 리스너를 만들고 리스너를 만들고 관련 위젯을 전달하고 리스너를 추가하는 것입니다. 청취자는 이제 멤버에 저장된 참조를 통해 위젯에 액세스 할 수 있습니다.

관련 문제