2011-12-19 64 views
1

是否有可能在java中有一个类,它具有EventHandlers用于不同的功能?例如button1会让你登录,而button2会让你登出,这可能吗?这是我所做的代码似乎不起作用的代码。类的事件处理程序

package event.handlers; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

public class TheHandler implements ActionListener { 

    @Override 
    public void actionPerformed(ActionEvent logInEvent) { 
     System.out.println("Button Login"); 
    } 

    public void actionPerformed(ActionEvent cancelEvent) { 
     System.out.println("Cancel Login"); 
    } 
} 

回答

1

不能让一个类实现具有相同函数签名的两个方法。编译器如何知道哪一个要调用不同的事件?您给参数的名称对编译器没有任何意义。

作为一种替代方法,您可以创建多个匿名操作侦听器,只需将调用转发给具有唯一名称的方法即可,如果您希望所有内容都处于同一个类中。

public class TheHandler { 

    public TheHandler() { 
     JButton login, cancel; 

     //initialize code here 

     login.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent logInEvent) { 
       loginPerformed(logInEvent); 
      } 
     }); 
     cancel.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent cancelEvent) { 
       cancelPerformed(cancelEvent); 
      } 
     }); 
    } 

    public void loginPerformed(ActionEvent logInEvent) { 
     System.out.println("Button Login"); 
    } 

    public void cancelPerformed(ActionEvent cancelEvent) { 
     System.out.println("Cancel Login"); 
    } 
} 
+0

他们的实现如何?不会那样吗? – KyelJmD 2011-12-19 13:16:34

+0

如何注册其他课程的按钮? – KyelJmD 2011-12-19 15:25:39

+0

@KyelJmD:你可以让'ActionListener'调用你想要的任何方法。如果该方法恰好在不同的类中,那么'TheHandler'需要对该类的一个实例的引用。这与在对象上调用方法没有任何区别。你只是在你的'ActionListener'定义中这样做。 – unholysampler 2011-12-19 15:31:45

2

要么你需要的ActionListener的两个实现,每一个按钮或的actionPerformed需要确定由事件参数的按钮,并采取适当的行动。您的代码不会编译,因为两种方法的签名都是相同的。

+0

你能否提供一个例子,其中一个类包含一个类中的不同处理程序? – KyelJmD 2011-12-19 13:17:15

0

您可以使用ActionEvent的getSource()getActionCommand()方法。

@Override 
public void actionPerformed(ActionEvent logInEvent) { 
     Object src=logInEvent.getSource(); 
     String cmd=logInEvent.getActionCommand(); //It will return caption of button 
     if(src==btn1) 
     { 
      // 
     } 
     //Or 
     if(cmd.equals("Button1")) { ... } 

} 
0

在一个类中不能有多个actionPerformed方法。简单的方法是基于类似行动的源做手术:

(在actionPerformed方法)

if(e.getSource() == loginButtton) { // based on button variable if they are in same class and accessible in actionPerformed method 
    loginMethod() 
} else if(e.getSource == logoutButton) { 
    logoutMethod() 
} 

if(e.getActionCommand().equals("loginButtton")) { // based on caption/text on button 
    loginMethod() 
} else if(e.getActionCommand().equals("logoutButtton")) { 
    logoutMethod() 
} 

,或者你可以有不同的按钮不同匿名类像

loginButton.addActionListner(new ActionListerner(){ 
    public void actionPerformed(ActionEvent loginEvent) { 
     loginMethod(); 
    } 
}); 
logoutButton.addActionListner(new ActionListerner(){ 
    public void actionPerformed(ActionEvent cancelEvent) { 
     logoutMethod(); 
    } 
}); 
0

问题在于您的两个方法签名是相同的。当Java试图找出要调用的方法时,它无法分辨两者之间的区别。

我能想到的两种方法可以做到你想要什么:

想必,你上的按钮注册听众像cancelButton.addActionListener(...)。所以,你可以提供每个按钮都有自己的匿名内部类:

loginButton.addActionListener(new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent logInEvent) { 
     System.out.println("Button Login"); 
    } 
} 
cancelButton.addActionListener(new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent cancelEvent) { 
     System.out.println("Cancel Login"); 
    } 
} 

,或者你可以定义检查呼叫源的单一actionPerformed方法:

public class TheHandler implements ActionListener { 

    JButton loginButton; 
    JButton cancelButton; 

    public TheHandler() 
    { 
     ... 
     // Now, technically, this is bad form because you're leaking 'this'. 
     // But as long as this will only be called after this constructor finishes 
     // initializing, it's safe. 
     loginButton.addActionListener(this); 
     cancelButton.addActionListener(this); 
     ... 
    } 

    ... 

    @Override 
    public void actionPerformed(ActionEvent evt) { 
     if(evt.getSource() == loginButton) 
      System.out.println("Button Login"); 
     else if(evt.getSource() == cancelButton) 
      System.out.println("Cancel Login"); 
    } 
} 

使用匿名内部类有时更清楚一点,因为你看到addListener调用旁边的代码,但它也增加了很多样板,如果你正在处理一个可能需要一段时间才能加载的非常大的项目,有时候可以减少类的数量使其加载速度更快一些(每个匿名内部类是JVM加载的另一件事)。

+0

我不想拥有内部类,因为它们都是混乱的,有没有其他方法?我可以有不同的方法吗? – KyelJmD 2011-12-19 13:46:57

+0

尝试第二个选项,即不使用内部类。 – Dogmatixed 2011-12-19 16:45:37

+0

我会如何注册?像cancelButton.addActionlistenr(处理程序); ?? – KyelJmD 2011-12-20 03:10:48