我正在研究Java Swing以及如何使用适配器模式处理事件,而不是覆盖处理事件的所有方法。
我找到了这个简短的例子,我想知道我是否理解了它:
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class Sketcher {
JFrame window = new JFrame("Sketcher");
public Sketcher() {
window.setBounds(30, 30, 300, 300);
window.addWindowListener(new WindowHandler());
window.setVisible(true);
}
class WindowHandler extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.out.println("closing");
window.dispose(); // Release the window resources
System.exit(0); // End the application
}
}
public static void main(String[] args) {
new Sketcher();
}
}
我的理解是:
类包含一个 main 方法,该方法只是创建一个新的 Sketcher 实例。
草绘器实例创建一个新的 JFrame 对象,该对象只在监视器上显示一个帧。
因此,当我创建一个新的草绘器时,会创建一个新的 JFrame 对象。
在这里,我有我的第一个疑问(这是Java属的疑问(:
为什么我不在 Sketcher 类的构造函数中创建 JFrame windos 对象?
无论如何,在构造函数中,我为 JFrame 对象设置了一些属性,并向这个 JFrame 添加一个 WindowListener。
现在,addWindowListener 是一个新的 WindowHandler 对象,它是处理 windows 事件的自定义对象。
现在我有两种可能性来处理这些事件:
使用经典侦听器:在这种情况下,我必须为 JFrame 上可能发生的所有可能事件实现一个特定的侦听器
使用适配器(如本例所示(,因此在本例中,我使用名为 WindowHandler 的内部类来扩展类 WindowAdapter。类 WindowAdapter 包含所有可能的 JFrame 事件的 void 方法。因此,在窗口处理程序中,我只能定义我想要处理的方法,而不是所有方法。
是我的理由吗?这是一个很好的教程示例还是它提出了一些现在我看不到的问题?
嘟嘟
安德里亚
你的推理是正确的,但这里有一些注意事项:
-
你问了为什么我不在 Sketcher 类的构造函数中创建 JFrame 窗口对象?
编译器正在为你做一些工作;它实际上将JFrame的初始化放在你的构造函数中。您也可以将 JFrame 初始化显式放置在构造函数中。
-
您的
WindowHandler
类不必是内部类;它可以是实现WindowListener
或扩展WindowAdapter
的任何类。 -
AWT 和 Swing 中的
XXXAdapter
类只是提供相关接口的无操作便利实现的类的命名约定。它们并不是真正的适配器(见下文(。 -
您的
main
实现不必在框架的类中;它可以在任何类中。
通常,我们不喜欢在构造函数中创建一堆东西,尤其是在可能存在副作用的情况下。最好提供单独的构造和初始化方法。
特别是对于 Swing,通常会对组件进行子类化,以提供应用程序(包括 JFrames(所需的 UI 专用化。但要保持业务逻辑独立。
尽管 swing 类被命名为 WindowAdapter
,但它实际上并没有适应适配器模式意义上的任何内容。它提供的是WindowListener
接口所有方法的默认无操作实现,它允许开发人员仅覆盖他/她感兴趣的方法。
所以我想说这更多的是对overriding
的研究,而不是适应;后者通常用于使两个不兼容的API一起工作。