【问题标题】:Advantages to Nested Classes For Listeners in GUIsGUI 中侦听器嵌套类的优势
【发布时间】:2011-02-22 23:08:47
【问题描述】:

对于规模相当大的项目,有人告诉我,当您有扩展 JPanel 的类时,最佳做法是使用嵌套类来实现侦听器。例如,我可以有一个扩展 JPanel 的类 FactoryScreen,并有一个实现所有必要侦听器的嵌套类 FactoryScreenBrain。

我一直无法很好地解释以这种方式封装我的类的具体好处或坏处,直到现在,我一直只有扩展 JPanel 和实现侦听器的类。有人可以为此提供一些指导吗?

【问题讨论】:

  • 不必要地扩展JPanel(或JFrameThread)不是最佳做法。但是,GUI 编程和良好实践往往无法满足

标签: java user-interface swing listener encapsulation


【解决方案1】:

为您的听众提供内部类使所有这些听众的目的非常明确。它有时也可以避免许多 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
        }
    }

现在,如果您的计时器有问题,您可以轻松识别出问题的班级。

更重要的是,在大范围内,它使您的代码更具可读性。如果其他人想要在这个类上工作并且他们需要使用计时器修复事件处理,他们不必搜索您的 ifs 来找到具有计时器逻辑的部分。

【讨论】:

    【解决方案2】:

    我认为任何事情都比让一个类扩展一个 Swing 组件并实现一个监听器要好,因为它赋予了类太多不同的职责,并为创建可怕的交换机监听器设置了一个。我尝试使用从单独的控件类调用方法的匿名内部侦听器。这样我就可以划分职责,并且可以更轻松地单独测试每个类的行为。

    顺便说一句,问得好。

    【讨论】:

    • 是的。最大的胜利是关注点的分离。嵌套(或匿名)内部类只有一项工作要做。使跟踪其整个行为变得非常容易。例如,如果您有一个面板,其中有几十个对象调用一个 actionPerformed 方法,它会使该方法更大,更难理解或维护。例如,如果您出于某个目的更改该方法,那么您可能会意外影响该方法处理的其他职责。
    • 感谢您的评论,以及可能的赞成票。如果是你,你一定要推我3000多。谢谢! :)
    【解决方案3】:

    如果您扩展一个组件并实现一个或多个侦听器,则很容易在构造函数中添加侦听器。这可能会暴露对未完全构造对象的引用——有时称为escaped this。只在 EDT 上工作可以降低风险;但是匿名内部类可以进一步减少它。来自反射或indirect exposure 的问题仍然存在。

    【讨论】:

    • 我不确定使用匿名内部类是否能解决问题。稍后在页面ibm.com/developerworks/java/library/j-jtp0618.html#3 描述了如果子类依赖于事件,匿名内部类如何仍会经历竞争条件。我能想到的真正避免这种情况的唯一方法可能是使您的 GUI 类成为最终类(在某些情况下绝对可行),但该链接并未真正详细说明解决此问题的其他方法......
    • 好点;这不是灵丹妙药。正如 Joshua Bloch 所说,“为继承设计和记录,否则禁止它。”
    • 我想了解否决票,所以我可以澄清答案。
    猜你喜欢
    • 2021-10-30
    • 2021-02-07
    • 2011-06-17
    • 2013-02-05
    • 2018-11-26
    • 2023-03-24
    • 2020-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多