Java WindowAdapter适配器类

来源:互联网 发布:知乎果壳豆瓣 编辑:程序博客网 时间:2024/05/07 01:58

  并不是所有的事件处理都像按钮点击那样简单。在正规的程序中,往往希望用户在确认没有丢失所做工作之后再关闭程序。当用户关闭框架时,可能希望弹出一个对话框来警告用户没有保存的工作有可能会丢失,只有在用户确认之后才退出程序。

  当程序用户试图关闭一个框架窗口时,JFrame对象就是WindowEvent的事件源。如果希望捕获这个事件,就必须有一个适合的监听器对象,并将它添加到框架的窗口监听器列表中。

  窗口监听器必须是实现WindowListener接口的类的一个对象。在WindowListener接口中包含7个方法。当发生窗口事件时,框架将调用这些方法响应7个不同的事件。从它们的名字就可以得知其作用,唯一的例外是在Windows下,通常将iconified称为minimized。

public interface WindowListener extends EventListener {    /**     * Invoked the first time a window is made visible.     */    public void windowOpened(WindowEvent e);    /**     * Invoked when the user attempts to close the window     * from the window's system menu.     */    public void windowClosing(WindowEvent e);    /**     * Invoked when a window has been closed as the result     * of calling dispose on the window.     */    public void windowClosed(WindowEvent e);    /**     * Invoked when a window is changed from a normal to a     * minimized state. For many platforms, a minimized window      * is displayed as the icon specified in the window's      * iconImage property.     * @see java.awt.Frame#setIconImage     */    public void windowIconified(WindowEvent e);    /**     * Invoked when a window is changed from a minimized     * to a normal state.     */    public void windowDeiconified(WindowEvent e);    /**     * Invoked when the Window is set to be the active Window. Only a Frame or     * a Dialog can be the active Window. The native windowing system may     * denote the active Window or its children with special decorations, such     * as a highlighted title bar. The active Window is always either the     * focused Window, or the first Frame or Dialog that is an owner of the     * focused Window.     */    public void windowActivated(WindowEvent e);    /**     * Invoked when a Window is no longer the active Window. Only a Frame or a     * Dialog can be the active Window. The native windowing system may denote     * the active Window or its children with special decorations, such as a     * highlighted title bar. The active Window is always either the focused     * Window, or the first Frame or Dialog that is an owner of the focused     * Window.     */    public void windowDeactivated(WindowEvent e);}
  在Java中,实现一个接口的任何类都必须实现其中的所有方法;在这里,意味着需要实现7个方法。然而这里如果我们只对名为windowClosing的方法感兴趣。

  当然,可以这样定义实现这个接口的类:在windowClosing方法中增加一个对System.out.println("TerminatorListener--windowClosing");的调用,其它6个方法不做任何事情:

 

class TerminatorListener implements WindowListener {    public void windowClosing(WindowEvent e) {        System.out.println("TerminatorListener--windowClosing");    }    @Override    public void windowOpened(WindowEvent e) {        // throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowClosed(WindowEvent e) {        //throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowIconified(WindowEvent e) {        //throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowDeiconified(WindowEvent e) {        //throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowActivated(WindowEvent e) {        //  throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowDeactivated(WindowEvent e) {        //  throw new UnsupportedOperationException("Not supported yet.");    }}
  书写6个没有任何操作的方法代码显然是一种乏味的工作。鉴于简化的目的,每个含有多个方法的AWT监听器接口都配有一个适配器(adapter)类,这个类实现了接口中的所有方法,但每个方法没有做任何事情。这意味着适配器类自动地满足了Java实现相关监听器接口的技术需求。可以通过扩展适配器类来指定对某些事件的响应动作,而不必实现接口中的每个方法(ActionListener这样的接口只有一个方法,因此没必要提供适配器类)。

  下面使用窗口适配器。首先定义一个WindowAdapter类的扩展类,其中包含继承的6个没有做任何事情的方法和一个覆盖的方法windowClosing:

class TerminatorAdapter extends WindowAdapter {    public void windowClosing(WindowEvent e) {        System.out.println("TerminatorAdapter---windowClosing");    }}

  现在,可以将一个Terminator对象注册为事件监听器:

WindowListener listenerAdapter = new TerminatorAdapter();adapterFrame.addWindowListener(listenerAdapter);
  只要框架产生了窗口事件,就会通过调用7个方法之中的一个方法将事件传递给listener对象,其中6个方法没有做过任何事情;windowClosing方法调用System.exit(0)终止应用程序的执行。

  警告:如果在扩展适配器类时将方法名拼写错了,编译器不会捕获到这个错误。例如,如果在WindowAdapter类中定义一个windowIsClosing方法,就会得到一个包含8个方法的类,并且windowClosing方法没有做任何事情。

  创建一个扩展于WindowAdapter的监听器类是一个很好的改进,但是还可以继续改进。事实上,没有必要为listener对象命名。只需写成:

adapterFrame.addWindowListener(new WindowAdapter());
  不要就此止步!我们可以将监听器类定义为框架的匿名内部类。

adapterFrame.addWindowListener(new WindowAdapter() {     public void windowClosing(WindowEvent e) {         System.out.println("Terminator--windowClosing");     }});
  这段代码具有下列作用:

  定义了一个扩展于WindowAdapter类的无名类。

  将windowClosing方法添加到匿名类中。

  从WindowAdapter继承6个没有做任何事情的方法。

  创建这个类的一个对象,这个对象没有名字。

  将这个对象传递给addWindowListener方法。

完整示例代码如下:

import java.awt.EventQueue;import javax.swing.JFrame;import javax.swing.JPanel;import java.awt.event.WindowListener;import java.awt.event.WindowEvent;import java.awt.event.WindowAdapter;public class ListenerTest {    public static void main(String[] args) {        EventQueue.invokeLater(new Runnable() {            public void run() {                AdapterFrame adapterFrame = new AdapterFrame();                WindowListener listenerListener = new TerminatorListener();                adapterFrame.addWindowListener(listenerListener);                                WindowListener listenerAdapter = new TerminatorAdapter();                 adapterFrame.addWindowListener(listenerAdapter);                                adapterFrame.addWindowListener(new WindowAdapter() {                    public void windowClosing(WindowEvent e) {                        System.out.println("Terminator--windowClosing");                    }                });                adapterFrame.setVisible(true);            }        });    }}class AdapterFrame extends JFrame {    public AdapterFrame() {        setTitle("AdapterTest");        setSize(DEFAULT_WIDTH, DEFALUT_HEIGHT);        adapterPanel = new JPanel();        add(adapterPanel);    }    private JPanel adapterPanel;    public static final int DEFAULT_WIDTH = 300;    public static final int DEFALUT_HEIGHT = 200;}class TerminatorAdapter extends WindowAdapter {    public void windowClosing(WindowEvent e) {        System.out.println("TerminatorAdapter---windowClosing");    }}class TerminatorListener implements WindowListener {    public void windowClosing(WindowEvent e) {        System.out.println("TerminatorListener--windowClosing");    }    @Override    public void windowOpened(WindowEvent e) {        // throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowClosed(WindowEvent e) {        //throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowIconified(WindowEvent e) {        //throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowDeiconified(WindowEvent e) {        //throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowActivated(WindowEvent e) {        //  throw new UnsupportedOperationException("Not supported yet.");    }    @Override    public void windowDeactivated(WindowEvent e) {        //  throw new UnsupportedOperationException("Not supported yet.");    }}

运行结果:

关闭AdapterTest窗口,显示结果:

TerminatorListener--windowClosingTerminatorAdapter---windowClosingTerminator--windowClosing