5

我想知道内部类的标准做法(在 Java 中,但我想它适用于所有 OO 语言)。所以我有一个 JFrame 子类ControllerWindow,它包含一个MapPanel我绘制的 JPanel 子类(因此它需要覆盖paintComponent 方法)并且需要实现鼠标侦听器。我目前可行的解决方案是MapPanel在一个单独的类中实现 MouseListener 但是当我向前几天运行我课程的人展示这个时,他似乎认为(我们有一点语言障碍)这应该在一个内部类中在ControllerWindow或至少 MouseListener 应该是一个内部类。

所以我的问题是这里的标准解决方案是什么,将 MouseListener 放在内部类中,将 JPanel 放在不同的内部类中还是仍然在其单独的类中?在一个内部类中实现 MouseListener 的 JPanel?为什么?

对我来说最重要的是它有效,但如果可能的话,我想了解和理解这些东西背后的标准做法。

编辑:下面当前代码的非常简化的版本。

class ControllerWindow extends JFrame{
    ...
    MapPanel drawPanel = new MapPanel();
    ...
}

和一个单独的类:

class MapPanel extends JPanel implements MouseListener{

    ...

    public void paintComponent(Graphics g){
        ...//fillRects etc.
    }

    //MouseListener methods
    public void mouseReleased(MouseEvent e){
        requestFocus();
        ...
        repaint()
        ...
    }
    public void mousePressed(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mouseClicked(MouseEvent e){}
}

这也可能是可以接受将两个类放在同一个文件中的情况吗?我不打算将MapPanel其用于ControllerWindow.

4

5 回答 5

8

使用匿名内部类作为事件侦听器很常见,因为代码通常非常简单(因此单独的类可能会过大),并且保持处理程序代码“接近”注册侦听器的代码可以提高人们试图理解的可读性您的代码,因为与事件相关的所有代码都在一个地方。

编辑:对于仅实现一种侦听器方法的类尤其如此。对于像 MouseListener 这样的多方法接口可能不太正确,因为实现完整接口的类会更加冗长。

于 2009-12-12T18:14:56.837 回答
4

我认为您如何处理它有点武断(正如 Tom Hawtin 评论的那样,GUI 标准 = 泥浆),因为您要权衡类数量的复杂性与单个类的复杂性。如果您只想为演示生成代码,则单个文件可能是最简单的。如果您想要将代码投入生产并随着时间的推移修改/维护,那么抽象到不同的类几乎肯定是您想要的方式。

例如,如果您将 MapPanel 作为内部类嵌入到 ControllerWindow 中,然后想用不同类型的 MapPanel 替换它,那么您对 ​​ControllerWindow 进行了大规模更新,而不仅仅是将 MapPanel 换成不同的组件类型。

对于 MouseListener,如果它专门为该组件处理事件,我倾向于将它包含在 MapPanel 中(也就是说,如果只有 MapPanel“知道”单击的含义,它应该是处理该单击的那个)。我绝对不会把它放在 ControllerWindow 中,因为那时你从 MapPanel 中“泄漏”了实现细节。(我能想到的唯一情况:除了您的 MapPanel 之外,您还有多个面板类型,它们都需要以相同的方式响应点击,因此您可以让 ControllerWindow 来完成,而不是在每个面板中实现。但即便如此,我不确定代码是否应该在 ControllerWindow 中)。

MapPanel 的鼠标侦听器是否是 MouseListener 的内部类实现,或者 MapPanel 是否实现它(如您上面的代码中)可能归结为您喜欢哪种样式的问题。

于 2009-12-12T23:40:27.093 回答
1

如果内部类有更简单的语法会更好。

button1.click( function(event){ do something x...  } );
button2.click( function(event){ do something y...  } );
radio2.check ( function(event){ do something z... } );

java 7 可能会给我们类似的东西并改变整个情况。就像现在一样,使用大量匿名内部类可能会弄乱代码并使其无法阅读。您应该选择使您的代码美观和易读的任何样式。

于 2009-12-13T00:30:31.693 回答
0

由于多个事件处理要求,需要匿名内部类。匿名类可以写在任何地方,比如在类中、在方法中、在参数中。因此,最好不要为每个侦听器匿名创建许多类。

于 2009-12-12T18:24:37.960 回答
0

我发现这篇文章很有用: http ://www.retrologic.com/innerclasses.doc3.html

一般来说,当你需要使用方法指针时;将适配器类扩展为内部类以简化代码。

于 2011-01-06T16:59:22.477 回答