Java中用得比較順手的事件監聽

       第一次據說監聽是三年前,作一個webGIS的項目,當時對Listener的印象就是個「監視器」,監視着界面的一舉一動,一有動靜就觸發對應的響應。html

1、概述

      經過對界面的某一或某些操做添加監聽,能夠自發地調用監聽函數/監聽類,對操做做出反應。舉個栗子:被監聽的操做是「你惹你媽生氣了」,添加的響應是「你媽給你爸打電話,你爸回家了,你爸打你一頓 」。因此無論何時,只要「你惹你媽生氣了」,都會觸發這個操做的監聽,最終結果是每次你都會被你爸打一頓。屢試不爽,無一例外。這就是事件監聽,java.util.EventListener。
java

      Listener分不少種:ActionListener,MouseListener,PopMenuListener,windowListener等等。          
web

2、監聽事件實現方式

1. 直接在控件中添加監聽

如:給「保存按鈕」添加ActionListener監聽ide

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... - 勾選須要添加的方法便可。this

4. 添加全局控件的監聽

背景:leftSecTypeListrightSecTypeList,leftButtonrightButton 是this的全局控件變量。如今給他們添加鼠標點擊監聽.spa

這種操做通常分爲兩步:code

(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     

在須要調用監聽的地方,添加通知監聽事件的函數便可。

 

 

4、小結

以上是一些Java事件監聽與使用方法的一些介紹,屬於入門級別。高級應用後期再予以學習與記錄。

 

                                           寫於2017年1月6日

相關文章
相關標籤/搜索