使用GUI的内部类的标准?

Ard*_*oja 5 java standards swing inner-classes

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

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

对我来说最重要的是它有效,但我想知道并理解这些事情背后的标准做法,如果可能的话.

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

class ControllerWindow extends JFrame{
    ...
    MapPanel drawPanel = new MapPanel();
    ...
}
Run Code Online (Sandbox Code Playgroud)

和一个单独的类:

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){}
}
Run Code Online (Sandbox Code Playgroud)

也可能是这种情况,将两个类放在同一个文件中是可以接受的吗?我没有设想使用MapPanel除了以外的任何东西ControllerWindow.

Rob*_*b H 8

通常使用匿名内部类作为事件侦听器,因为代码通常非常简单(因此单独的类可能过度杀伤)并且使处理程序代码"接近"注册侦听器的代码可以提高尝试理解的人的可读性您的代码,因为与事件相关的所有代码都在一个地方.

编辑:对于只实现一个侦听器方法的类尤其如此.对于像MouseListener这样的多方法接口,可能不那么正确,因为实现完整接口的类将更加冗长.

  • 对于像'MouseListener`这样的接口,有像MouseAdapter这样的类,只允许你覆盖你真正关心的方法. (3认同)

Ash*_*Ash 4

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

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

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

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