假设我有一个swing GUI,我想听MouseEvents
。你认为谁应该是听众课,谁应该负责?实施它的最佳或首选方式是什么?任何意见?我通常会这样:
public class MyPanel extends JPanel implements MouseListener{
private JTable table;
public void foo(){
table.addMouseListener(this);
}
/* MouseListener */
//Implement MouseListener here.
}
有更好的方法吗?
编辑:感谢大家的智慧和帮助。我很感激。
答案 0 :(得分:6)
有一些常见的方法来做事件监听器(我能想到的唯一一个我在下面的代码中留下的是静态内部类)。下面的代码使用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");
}
}
答案 1 :(得分:2)
我建议将监听器放在自己的类中,使其可重用,并明确分离关注点
答案 2 :(得分:2)
查看Java的Swing代码。这确实是看到良好标准的最佳场所。
在你的情况下,我会有类似的东西:
public class MyPanel extends JTable {
public void foo() {
addMouseListener(new MouseHandler() );
}
private class MouseHandler implements MouseListener {
...
}
}
通过这种方式,您可以清楚地分离各种功能。当您的主类开始实现十五个不同的接口时,您的代码将变得完全无法维护。
答案 3 :(得分:0)
匿名类主要用于监听器。如果你知道你有一个特定的监听器只注册一次并且它很短,那么你可以使用匿名类。
答案 4 :(得分:0)
就个人而言,我喜欢将GUI与控制器分开。所以我建议在Controller类中实现监听器(每个功能GUI都有自己的)并在那里工作,即使它需要使用if...else
或swich...case