Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java GUI中侦听器嵌套类的优点_Java_User Interface_Swing_Listener_Encapsulation - Fatal编程技术网

Java GUI中侦听器嵌套类的优点

Java GUI中侦听器嵌套类的优点,java,user-interface,swing,listener,encapsulation,Java,User Interface,Swing,Listener,Encapsulation,对于大小适中的项目,我被告知,当您有扩展JPanel的类时,最佳实践是使用嵌套类来实现侦听器。例如,我可以有一个扩展JPanel的类FactoryScreen,还有一个嵌套的类FactoryScreenBrain,它实现了所有必要的侦听器 我一直无法很好地解释以这种方式封装我的类的具体好处或缺点,直到现在,我一直只有扩展JPanel和实现侦听器的类。有人能给我一些指导吗 我认为任何事情都比让一个类扩展Swing组件并实现监听器要好,因为它给了类太多不同的职责,并设置了一个用来创建可怕的交换机监听

对于大小适中的项目,我被告知,当您有扩展JPanel的类时,最佳实践是使用嵌套类来实现侦听器。例如,我可以有一个扩展JPanel的类FactoryScreen,还有一个嵌套的类FactoryScreenBrain,它实现了所有必要的侦听器


我一直无法很好地解释以这种方式封装我的类的具体好处或缺点,直到现在,我一直只有扩展JPanel和实现侦听器的类。有人能给我一些指导吗

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


顺便提一下,这是一个好问题。

为您的听众提供内部类使所有这些听众的目的非常明确。它有时还可以避免许多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来查找带有计时器逻辑的部分。

如果您扩展了一个组件并实现了一个或多个侦听器,则很容易在构造函数中添加侦听器。这可能会公开对未完全构造的对象(有时称为对象)的引用。仅在EDT上工作可降低风险;但是匿名内部类可以进一步减少它。反射或保留的问题。

不必要地扩展
JPanel
(或
JFrame
线程
)不是最佳做法。但是,GUI编程和良好实践往往不符合要求。这是最大的胜利,分离关注点。嵌套(或匿名)内部类只有一个作业要做。使跟踪其整个行为变得非常容易。例如,如果您有一个面板,其中有几十个对象调用一个actionPerformed方法,它会使该方法更大、更难理解或维护。例如,如果您为了一个目的更改该方法,那么您可能会意外地影响该方法处理的其他职责。谢谢您的评论,可能还有投票。如果是你,你一定把我推了3000多。格拉茨!:)我不确定使用匿名内部类是否能解决这个问题。接下来,本页将描述如果子类依赖于事件,匿名内部类如何仍然会经历竞争条件。我能想到的真正避免这种情况的唯一方法可能是使您的GUI类成为最终类(在某些情况下这是绝对可行的),但该链接并没有真正详细说明解决此问题的其他方法…这一点很好;这不是万灵药。正如Joshua Bloch所指出的,“为继承而设计和编制文档,否则就禁止继承。”我想了解否决票,以便澄清答案。