zoukankan      html  css  js  c++  java
  • Java中用得比较顺手的事件监听

           第一次听说监听是三年前,做一个webGIS的项目,当时对Listener的印象就是个“监视器”,监视着界面的一举一动,一有动静就触发对应的响应。

    一、概述

          通过对界面的某一或某些操作添加监听,可以自发地调用监听函数/监听类,对操作作出反应。举个栗子:被监听的操作是“你惹你妈生气了”,添加的响应是“你妈给你爸打电话,你爸回家了,你爸打你一顿 ”。所以不管什么时候,只要“你惹你妈生气了”,都会触发这个操作的监听,最终结果是每次你都会被你爸打一顿。屡试不爽,无一例外。这就是事件监听,java.util.EventListener。

          Listener分很多种:ActionListener,MouseListener,PopMenuListener,windowListener等等。          

    二、监听事件实现方式

    1. 直接在控件中添加监听

    如:给“保存按钮”添加ActionListener监听

    1         saveCharaEditButton.addActionListener(new ActionListener() {
    2             
    3             @Override
    4             public void actionPerformed(ActionEvent e) {
    5                 // TODO Auto-generated method stub
    6                 save();
    7             }
    8         });

    2.写一个监听类,实现监听接口。

    添加事件监听时只需要 添加这个监听类就ok了。【PS:这个内部类与函数并列写就可以,不用另建类文件,只是前面注意不要加public修饰符。默认只能有一个public类。】

     1     public JPanel setRightPanel(){
     2         JPanel rightPanel = new JPanel();
     3         double[][] size = {{15,TableLayout.FILL,30,TableLayout.FILL,35},{10,30,10,TableLayout.FILL}};
     4         rightPanel.setLayout(new TableLayout(size));
     5         JButton saveCharaEditButton = new JButton("保存编辑");
     6         JButton enableCharaEditButton = new JButton("启用编辑");
     7         rightPanel.add(enableCharaEditButton, "1,1");
     8         rightPanel.add(saveCharaEditButton, "3,1");
     9         rightPanel.add(setCharaJCTablePanel(), "0,3,4,3");
    10         saveCharaEditButton.addActionListener(new saveEditToFloodCharacterValueListener());//添加监听
    11         return rightPanel;
    12     }
     1     class saveEditToFloodCharacterValueListener implements ActionListener{
     2 
     3         @Override
     4         public void actionPerformed(ActionEvent e) {
     5             // TODO Auto-generated method stub
     6             FloodCharacterValue floodCharacterValue = new FloodCharacterValue();            
     7             floodCharacterValue = FloodCharacterValue.transFldPropToFloodCharacterValue(editCharaFldprop);
     8             m_doc.m_floodExtractCharacterValue = floodCharacterValue;
     9         }
    10     }

     3. 添加适配器,也可以实现监听。(其实方法同1)

        首先说一下适配器和监听接口的不同:new一个监听接口,需要重载该接口下面的所有方法,你删除任何一个,都会报错;但是适配器可以只重载你需要的那个方法。

    以windowListener为例,给对话框dialog添加监听addWindowListerner,然后监听内容为窗口适配器WindowAdapter。对比如下:

    (1)监听接口【默认重载所有方法,功能需求单一时不推荐】

                                            dialog.addWindowListener(new WindowListener() {
                                                @Override
                                                public void windowOpened(WindowEvent e) {
                                                    // TODO Auto-generated method stub
                                                }
                                                @Override
                                                public void windowIconified(WindowEvent e) {
                                                    // TODO Auto-generated method stub
                                                }
                                                @Override
                                                public void windowDeiconified(WindowEvent e) {
                                                    // TODO Auto-generated method stub
                                                }
                                                @Override
                                                public void windowDeactivated(WindowEvent e) {
                                                    // TODO Auto-generated method stub
                                                }
                                                @Override
                                                public void windowClosing(WindowEvent e) {
                                                    // TODO Auto-generated method stub
                                                }
                                                @Override
                                                public void windowClosed(WindowEvent e) {
                                                    // TODO Auto-generated method stub
                                                }
                                                @Override
                                                public void windowActivated(WindowEvent e) {
                                                    // TODO Auto-generated method stub
                                                }
                                            });

    (2)添加适配器【可以只重载需要的方法,功能单一时推荐】

     1     dialog.addWindowListener(new WindowAdapter() {
     2         @Override
     3         public void windowClosed(WindowEvent e) {
     4             // TODO Auto-generated method stub
     5             JDialog dialog2 = (JDialog) e.getSource();
     6             set_infoSectionList(update_infoSectionListByProp(prop));
     7             if (basinCheckList != null && !basinCheckList.isEmpty() && basinCheckList.get(0).getCHECKED()==1) {
     8                 tableCharaShowPanel.updateData(schemeType, get_infoSectionList(), false);            
     9             }else {
    10                 tableCharaShowPanel.updateData(schemeType, get_infoSectionList(), true);            
    11             }
    12             super.windowClosed(e);
    13             dialog2.dispose();
    14         }
    15     });

    另外,关于添加哪些适配器,可以选择WindowAdapter,右键菜单中选择-resources-override/implement methods... - 勾选需要添加的方法即可。

    4. 添加全局控件的监听

    背景:leftSecTypeListrightSecTypeList,leftButtonrightButton 是this的全局控件变量。现在给他们添加鼠标点击监听.

    这种操作一般分为两步:

    (1)在初始化该控件的时候,添加参数为this的鼠标监听。

               leftSecTypeList.addMouseListener(this);

    (2)重写mouseClicked(MouseEvent e)函数,根据e.getSource() 判断是触发鼠标点击的是哪个控件,给出相应的反应。

     1     public JPanel createSelPanel(){
     2         JPanel panel = new JPanel();  
    *** 22 leftSecTypeList.addMouseListener(this); 23 rightSecTypeList.addMouseListener(this); 24 leftButton.addMouseListener(this); 25 rightButton.addMouseListener(this); 26 return panel; 27 }
     1     @Override
     2     public void mouseClicked(MouseEvent e) {
     3         // TODO Auto-generated method stub
     4         Object sourceObject = e.getSource();
     5         if (sourceObject == leftSecTypeList&& e.getClickCount() == 2) {
     6             HFSection section = leftSecTypeList.getSelectedItemType();
     9         }else if (sourceObject == rightSecTypeList&& e.getClickCount() == 2) {
    10             HFSection section = rightSecTypeList.getSelectedItemType();
    11         }else if (sourceObject == leftButton) {
    12 
    13         }else if (sourceObject == rightButton) {
    14     
    15         }
    16     

     5.利用类AbstractButton的set/get动作命令。

    Abstract直接已知子类:JButton, JMenuItem, JToggleButton

    void     setActionCommand(String actionCommand)设置此按钮的动作命令。

    string  getActionCommand() 返回此按钮的动作命令。

       //创建菜单Item的函数
       private JMenuItem createMenuItem(String text,String actionCommand) { JMenuItem item = new JMenuItem(text); item.setActionCommand(actionCommand);//设置此按钮的动作命令 item.addActionListener(new MenuActionListener()); return item; }
        //创建菜单
            private void initPopupMenu()
        {
            layerPopupMenu = new JPopupMenu();
            layerPopupMenu.add(createMenuItem("添加目录","addDir"));
            layerPopupMenu.add(createMenuItem("添加图层","addLayer"));
            layerPopupMenu.addSeparator();
            layerPopupMenu.add(createMenuItem("上移","up"));
            layerPopupMenu.add(createMenuItem("下移","down"));
        }    
        // 右键菜单操作命令
            class MenuActionListener implements ActionListener
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                String actionCommand = e.getActionCommand();
                if(actionCommand.equals("addDir")){   addDir();}
                else if(actionCommand.equals("addLayer")){    addLayer();}
                else if(actionCommand.equals("up")){  layerUp();}
                else if(actionCommand.equals("down")){  layerDown();}
            }    

    6. 以接口实现对按钮的监听响应

    1.在工具条面板中:(1)定义响应接口 (2)以接口定义响应变量 (3)定义按钮,监听响应为变量

    2.在调用文件中: 以implents方式实现 工具条面板中对应的接口变量

    //1-1 ControlBarPanel.java 定义接口
        public interface IBackwardActionPerformed {
            public void ActionPerformed(ActionEvent e);
        }
    
    //1-2 ControlBarPanel.java 以接口定义响应变量
    public IBackwardActionPerformed backwardActionPerformed;
    
    //1-3 ControlBarPanel.java 定义按钮,监听响应为变量
    backwardButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
            backwardActionPerformed.ActionPerformed(e);
        }
    });
    
    //2-1 MainForcastPanel.java 实现响应变量具体操作
    controlBarPanel.backwardActionPerformed = new BackwardBtnActionListener();
    
    //2-2 MainForcastPanel.java 实现响应变量具体操作
        class BackwardBtnActionListener implements IBackwardActionPerformed,Runnable {
            @Override
            public void ActionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                Thread thread = new Thread(this);
                new HFProgressPane1(thread, "正在计算中......", null, null);
            }
    
            @Override
            public void run() {
                // TODO Auto-generated method stub
                ************
            }
        }

     3. 方法6的详细代码

     1 public class ControlBarPanel extends JPanel implements ActionListener{
     2     private JButton jButton;
     3     public IActionPerformed iActionPerformed;
     4     
     5     public JPanel createPanel(){
     6         JPanel panel = new JPanel();
     7         panel.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
     8         jButton = new JButton("testButton");
     9         jButton.setMargin(new Insets(0, 0, 0, 0));
    10         jButton.addActionListener(new ActionListener() {
    11             @Override
    12             public void actionPerformed(ActionEvent e) {
    13                 // TODO Auto-generated method stub
    14                 iActionPerformed.ActionPerformed(e);
    15             }
    16         });
    17         panel.add(createForeTypePanel());
    18         panel.add(jButton);
    19         return panel;
    20     }
    21     
    22     public interface IActionPerformed {
    23         public void ActionPerformed(ActionEvent e);
    24      }    
    25 }
    26 
    27 public class ShowPanel extends JPanel {
    28     private ControlBarPanel controlBarPanel;
    29     //构造函数
    30     public ShowPanel() {
    31         controlBarPanel = new ControlBarPanel();
    32         controlBarPanel.iActionPerformed = new ActionListener();
    33         this.setLayout(new BorderLayout());
    34         this.add(controlBarPanel,BorderLayout.NORTH);
    35     }
    36     
    37     class ActionListener implements IActionPerformed{
    38         @Override
    39         public void ActionPerformed(ActionEvent e) {
    40             // TODO Auto-generated method stub
    41             function(e);
    42         }
    43     }    
    44 }

    7. 添加监听列表,然后通知所有监听。

    分为三步

    (1)定义变量:监听列表

    (2)定义函数:注册监听,删除监听

    (3)定义函数:通知所有监听

    代码如下:

     1     /**
     2      * 拖动完成后监听保存队列
     3      */
     4     private List dragOverListenerList =new ArrayList();
     5     
     6     /**
     7      * 注册监听事件
     8      */
     9     public void addDragOverListener(DragOverListener listener){
    10         synchronized (objSync) {
    11             dragOverListenerList.add(listener);
    12         }
    13     }
    14     
    15     /**
    16      * 删除监听
    17      * @param eventObject
    18      */
    19     public void removeDragOverListener(DragOverListener listener){
    20         synchronized (objSync) {
    21             dragOverListenerList.remove(listener);
    22         }
    23     }
    24     
    25     /**
    26      * 通知所有监听事件
    27      */
    28     private void notifyAllListener(){
    29         for(int i=0;i<dragOverListenerList.size();i++)
    30         {
    31             ((DragOverListener)dragOverListenerList.get(i)).actionPerform(new DragOverEvent(this));
    32         }
    33     }
    34     

    在需要调用监听的地方,添加通知监听事件的函数即可。

    四、小结

    以上是一些Java事件监听与使用方法的一些介绍,属于入门级别。高级应用后期再予以学习与记录。

                                               写于2017年1月6日

  • 相关阅读:
    java10-3 equals方法
    java10-2 toString()方法
    java10-1 Object类
    转载 实现类的封装性
    cocosstdio之字体之文本和FNT字体
    cocos之观察者模式应用实例
    c++双字符常量
    spring之ioc
    cocos2d-x之 利用富文本控件解析xhml标签(文字标签,图片标签,换行标签,标签属性)
    cocos2d-x之利用富文本控件遍历xml
  • 原文地址:https://www.cnblogs.com/xujingbo/p/6253681.html
Copyright © 2011-2022 走看看