听众有更好的练习吗?

假设我有一个swing GUI,我想听MouseEvents 。 你认为谁应该是听众课,谁应该负责? 实施它的最佳或首选方式是什么? 任何意见? 我通常会这样:

 public class MyPanel extends JPanel implements MouseListener{ private JTable table; public void foo(){ table.addMouseListener(this); } /* MouseListener */ //Implement MouseListener here. } 

有没有更好的办法?


编辑:谢谢大家的智慧和帮助。 我很感激。

有一些常见的方法来做事件监听器(我能想到的唯一一个我在下面的代码中留下的是静态内部类)。 下面的代码使用ActionListener,因为它最简单,但您可以将该想法应用于任何侦听器。

请注意,“this”方式(让类实现监听器)可以导致一个巨大的if / else语句集。 我会说这是最糟糕的方式因为这个。 我不喜欢“清算所”方法有两个原因:

1)它们很大2)它很容易在方法内部进行工作,而不是让每个if / else调用一个方法来完成工作(正如你所看到的,这就是我在这里所做的… oops: – )

我也不喜欢Anonymous方式有两个原因:

1)你不能轻易地重复使用代码,所以你可能会发现你有一段时间后重复代码2)我发现它打破了代码的阅读(其他人不同意……个人品味)。 我想每个人都会同意,如果你做的超过5-10行,那么一个匿名的内部课程不是一个好主意(我会说超过2个是太多了)。

这留下了内在和外在的方式。 当我编写一个与它正在监听的GUI没有紧密联系的监听器时,我会使用外部方式。 如果监听器不需要作为类的一部分的信息(成员变量/方法)(在本例中为TestFrame),我将使用外部类。 在下面的示例中,我传入了“this”,以便外部侦听器可以访问GUI …如果我要编写类似的代码,我会将其作为内部类,因为它需要来自GUI的内容。

所以,我的偏好顺序是:

  • 内部类(如果可能的话,静态,但如果你使它静态,我会选择外部类)
  • 外层阶级
  • 匿名内部阶级(罕见)
  • 让这个类自己实现它(我永远不会这样做。从来没有!)

这是代码

 import java.awt.FlowLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class Main { public static void main(String[] args) { SwingUtilities.invokeLater( new Runnable() { public void run() { createAndShowGUI(); } }); } private static void createAndShowGUI() { final TestFrame frame; frame = new TestFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setBounds(new Rectangle(10, 10, 300, 300)); frame.init(); frame.setVisible(true); } } class TestFrame extends JFrame implements ActionListener { private final JButton aBtn; private final JButton bBtn; public TestFrame() { super("Test"); aBtn = new JButton("A"); bBtn = new JButton("B"); } public void init() { setLayout(new FlowLayout()); add(aBtn); add(bBtn); // the class, since it implements ActionListener aBtn.addActionListener(this); bBtn.addActionListener(this); // outer classes aBtn.addActionListener(new OuterAListener(this)); bBtn.addActionListener(new OuterBListener(this)); // inner class aBtn.addActionListener(new InnerAListener()); bBtn.addActionListener(new InnerBListener()); // anonymous classes aBtn.addActionListener( new ActionListener() { public void actionPerformed(final ActionEvent e) { System.out.println ("Hi from Anonymous A"); } }); bBtn.addActionListener( new ActionListener() { public void actionPerformed(final ActionEvent e) { System.out.println ("Hi from Anonymous B"); } }); } public void actionPerformed(final ActionEvent evt) { final Object source; source = evt.getSource(); if(source == aBtn) { System.out.println ("Hi from this A"); } else if (source == bBtn) { System.out.println ("Hi from this B"); } else { // ??? } } private class InnerAListener implements ActionListener { public void actionPerformed(final ActionEvent e) { System.out.println ("Hi from Inner A"); } } private class InnerBListener implements ActionListener { public void actionPerformed(final ActionEvent e) { System.out.println ("Hi from Inner B"); } } } class OuterAListener implements ActionListener { private final TestFrame frame; public OuterAListener(final TestFrame f) { frame = f; } public void actionPerformed(final ActionEvent e) { System.out.println ("Hi from Outer A"); } } class OuterBListener implements ActionListener { private final TestFrame frame; public OuterBListener(final TestFrame f) { frame = f; } public void actionPerformed(final ActionEvent e) { System.out.println ("Hi from Outer B"); } } 

我建议将监听器放在自己的类中,使其可重用,并明确区分关注点

看看Java的Swing代码。 这真的是看到良好标准的最佳场所。

在你的情况下,我有类似的东西:

 public class MyPanel extends JTable { public void foo() { addMouseListener(new MouseHandler() ); } private class MouseHandler implements MouseListener { ... } } 

这样您就可以清楚地分离各种function。 当您的主类开始实现十五个不同的接口时,您的代码将变得完全无法维护。

匿名类主要用于监听器。 如果你知道你有一个特定的监听器只注册一次并且它很短,那么你可以使用匿名类。

就个人而言,我喜欢将GUI与控制器分开。 所以我建议在Controller类中实现监听器(每个functionGUI都有自己的)并在那里工作,即使它需要使用if...elseswich...case