嵌套类作为GUI监听器的优势

11

对于相当大的项目,我被告知在扩展JPanels的类时,最好实现使用嵌套类来实现监听器。例如,我可以有一个扩展JPanel的FactoryScreen类,并有一个嵌套的FactoryScreenBrain类来实现所有必要的监听器。

我从来没有得到过关于在此方式下封装我的类的具体好处或缺点的好的解释,直到现在一直只是用同时扩展JPanel并实现监听器的类。有人能给我提供一些指导吗?


不必要地扩展JPanel(或JFrameThread)并不是最佳实践。但是,GUI编程和良好的实践往往不会相遇。 - Tom Hawtin - tackline
3个回答

8

在监听器中使用内部类,可以使所有监听器的目的非常清晰。有时,这还可以避免许多if检查,但会增加一些代码量。

如果您有一个面板

public class MyPanel extends JPanel implements ActionListener
...
    button1.addActionListener(this);
    button2.addActionListener(this);
    checkbox1.addActionListener(this);
    timer3.addActionListener(this);

    public void actionPerformed(ActionEvent e)
    {
        if(e.getSource() == button1)
        else...
        ... //potentially many elses
    }

因为actionPerformed方法同时处理了许多不同的事件,所以很难准确地看到发生了什么。拥有一个面板:

可以帮助您更好地组织代码并使其更易于阅读和理解。
public class MyPanel extends JPanel
...
    button1.addActionListener(new ButtonListener());
    button2.addActionListener(new ButtonListener());
    checkbox1.addActionListener(new CheckBoxListener());
    timer3.addActionListener(new TimerListener());

    private class TimerListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            //do stuff related only to timers
        }
    }

现在,如果您的定时器有问题,您可以轻松地识别出存在问题的类。 更重要的是,在大规模上,它使您的代码更易读。如果其他人想要处理此类并需要修复定时器的事件处理,则不必搜索您的if语句以查找具有定时器逻辑的部分。

6
我认为,任何事情都比让一个类继承Swing组件并实现监听器要好,因为这会给类带来太多不同的责任,并使其容易创建可怕的开关板监听器。我尝试使用匿名内部监听器调用来自单独控制类的方法。这样,我可以分离出责任,并更轻松地测试每个类的行为。顺便说一句,这是一个好问题。

3
是的,分离关注点是最大的优势。嵌套(或匿名)内部类只有一个工作要做。这使得跟踪其整个行为变得非常容易。例如,如果你有一个面板拥有数十个调用一个actionPerformed方法的对象,那么这将使该方法变得更加庞大,难以理解或维护。如果你因某个目的而修改该方法,那么你就有可能意外地影响到该方法处理的其他职责。 - Kaffiene
感谢您的评论,也许还有点赞。如果是您的话,您一定帮我突破了3000个赞。恭喜! :) - Hovercraft Full Of Eels

2
如果您扩展一个组件并实现了一个或多个监听器,那么在构造函数中添加监听器是很有诱惑力的。这可能会暴露一个不完整构建的对象的引用,有时被称为逃逸的this。仅在EDT上工作可以减轻风险;但匿名内部类可以进一步减少它。反射或间接暴露的问题仍然存在。

我不确定使用匿名内部类是否会解决这个问题。在页面后面http://www.ibm.com/developerworks/java/library/j-jtp0618.html#3中,描述了如果一个子类依赖于事件,则匿名内部类仍可能经历竞态条件。我能想到的唯一真正避免这种情况的方法可能是使您的GUI类final(在某些情况下肯定可行),但链接并没有详细说明其他解决方法... - donnyton
好的观点;这并不是万能药。正如Joshua Bloch所指出的那样,“为继承进行设计和文档编写,否则禁止继承”。 - trashgod
我想了解下投票,这样我就可以澄清答案。 - trashgod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接