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

一、概述

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

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

二、监听事件实现方式

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

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

         saveCharaEditButton.addActionListener(new ActionListener() {

             @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
save();
}
});

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

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

     public JPanel setRightPanel(){
JPanel rightPanel = new JPanel();
double[][] size = {{15,TableLayout.FILL,30,TableLayout.FILL,35},{10,30,10,TableLayout.FILL}};
rightPanel.setLayout(new TableLayout(size));
JButton saveCharaEditButton = new JButton("保存编辑");
JButton enableCharaEditButton = new JButton("启用编辑");
rightPanel.add(enableCharaEditButton, "1,1");
rightPanel.add(saveCharaEditButton, "3,1");
rightPanel.add(setCharaJCTablePanel(), "0,3,4,3");
saveCharaEditButton.addActionListener(new saveEditToFloodCharacterValueListener());//添加监听
return rightPanel;
}
     class saveEditToFloodCharacterValueListener implements ActionListener{

         @Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
FloodCharacterValue floodCharacterValue = new FloodCharacterValue();
floodCharacterValue = FloodCharacterValue.transFldPropToFloodCharacterValue(editCharaFldprop);
m_doc.m_floodExtractCharacterValue = floodCharacterValue;
}
}

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)添加适配器【可以只重载需要的方法,功能单一时推荐】

     dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
JDialog dialog2 = (JDialog) e.getSource();
set_infoSectionList(update_infoSectionListByProp(prop));
if (basinCheckList != null && !basinCheckList.isEmpty() && basinCheckList.get(0).getCHECKED()==1) {
tableCharaShowPanel.updateData(schemeType, get_infoSectionList(), false);
}else {
tableCharaShowPanel.updateData(schemeType, get_infoSectionList(), true);
}
super.windowClosed(e);
dialog2.dispose();
}
});

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

4. 添加全局控件的监听

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

这种操作一般分为两步:

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

leftSecTypeList.addMouseListener(this);

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

     public JPanel createSelPanel(){
JPanel panel = new JPanel();  
***
leftSecTypeList.addMouseListener(this);
rightSecTypeList.addMouseListener(this);
leftButton.addMouseListener(this);
rightButton.addMouseListener(this);
return panel;
}
     @Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
Object sourceObject = e.getSource();
if (sourceObject == leftSecTypeList&& e.getClickCount() == 2) {
HFSection section = leftSecTypeList.getSelectedItemType();
}else if (sourceObject == rightSecTypeList&& e.getClickCount() == 2) {
HFSection section = rightSecTypeList.getSelectedItemType();
}else if (sourceObject == leftButton) { }else if (sourceObject == rightButton) { }

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的详细代码

 public class ControlBarPanel extends JPanel implements ActionListener{
private JButton jButton;
public IActionPerformed iActionPerformed; public JPanel createPanel(){
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0));
jButton = new JButton("testButton");
jButton.setMargin(new Insets(0, 0, 0, 0));
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
iActionPerformed.ActionPerformed(e);
}
});
panel.add(createForeTypePanel());
panel.add(jButton);
return panel;
} public interface IActionPerformed {
public void ActionPerformed(ActionEvent e);
}
} public class ShowPanel extends JPanel {
private ControlBarPanel controlBarPanel;
//构造函数
public ShowPanel() {
controlBarPanel = new ControlBarPanel();
controlBarPanel.iActionPerformed = new ActionListener();
this.setLayout(new BorderLayout());
this.add(controlBarPanel,BorderLayout.NORTH);
} class ActionListener implements IActionPerformed{
@Override
public void ActionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
function(e);
}
}
}

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

分为三步

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

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

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

代码如下:

     /**
* 拖动完成后监听保存队列
*/
private List dragOverListenerList =new ArrayList(); /**
* 注册监听事件
*/
public void addDragOverListener(DragOverListener listener){
synchronized (objSync) {
dragOverListenerList.add(listener);
}
} /**
* 删除监听
* @param eventObject
*/
public void removeDragOverListener(DragOverListener listener){
synchronized (objSync) {
dragOverListenerList.remove(listener);
}
} /**
* 通知所有监听事件
*/
private void notifyAllListener(){
for(int i=0;i<dragOverListenerList.size();i++)
{
((DragOverListener)dragOverListenerList.get(i)).actionPerform(new DragOverEvent(this));
}
}

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

四、小结

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

                                           写于2017年1月6日

Java中用得比较顺手的事件监听的更多相关文章

  1. Java swing(awt):事件监听机制的实现原理+简单示例

    (1)实现原理 事件监听机制的实现: 参考图:事件模型_ActionEvent 为了节省资源,系统无法对某个事件进行实时的监听.故实现的机制是当发生某个事件后,处理代码将被自动运行,类似钩子一般.(回 ...

  2. Java 界面编程【03】事件监听

    当你把界面都设计好了,总需要添加相应的执行动作给组件,在JAVA中有相应的时间处理机制,叫做“监听器”,给组件添加相应执行动作的过程叫做“注册”,其中的“监听器”是一个接口,里面包含了相应的执行函数, ...

  3. cocos2d-x 事件分发机制 ——触摸事件监听

    cocos2d-x 3.0 出来已经好久了,也已经用3.0写了几个小游戏,感觉3.0的事件触发机制太赞了,随这里总结一下.也算是对知识的一种回顾和加深理解. 3.0的事件分发机制中.须要也只须要通过创 ...

  4. JAVA 图形开发之计算器设计(事件监听机制)

    /*文章中用到的代码只是一部分,需要源码的可通过邮箱联系我 1978702969@qq.com*/ 前段时间刚帮同学用MFC写了个计算器,现在学到JAVA的图形开发,就试着水了一个计算器出来.(可以说 ...

  5. JAVA事件监听机制与实现

    事件监听机制的实现:参考图:事件模型_ActionEvent 为了节省资源,系统无法对某个事件进行实时的监听.故实现的机制是当发生某个事件后,处理代码将被自动运行,类似钩子一般.(回调函数) 事件有许 ...

  6. 4.JAVA之GUI编程事件监听机制

    事件监听机制的特点: 1.事件源 2.事件 3.监听器 4.事件处理 事件源:就是awt包或者swing包中的那些图形用户界面组件.(如:按钮) 事件:每一个事件源都有自己特点有的对应事件和共性事件. ...

  7. java 事件监听 - 鼠标

    java 事件监听 - 鼠标 //事件监听 //鼠标事件监听 //鼠标事件监听有两个实现接口 //1.MouseListener 普通的鼠标操作 //2.MouseMotionListener 鼠标的 ...

  8. java 事件监听 - 键盘

    java 事件监听 - 键盘 //事件监听 //键盘事件监听,写了一个小案例,按上下左右,改变圆形的位置,圆形可以移动 import java.awt.*; import javax.swing.*; ...

  9. java 事件监听 - 控件

    java 事件监听 //事件监听 //事件监听,写了一个小案例,点击按钮改变面板的颜色. import java.awt.*; import javax.swing.*; import java.aw ...

随机推荐

  1. iOS可视化动态绘制八种排序过程

    前面几篇博客都是关于排序的,在之前陆陆续续发布的博客中,我们先后介绍了冒泡排序.选择排序.插入排序.希尔排序.堆排序.归并排序以及快速排序.俗话说的好,做事儿要善始善终,本篇博客就算是对之前那几篇博客 ...

  2. ASP.NET MVC5+EF6+EasyUI 后台管理系统(71)-微信公众平台开发-公众号管理

    系列目录 思维导图 下面我们来看一个思维导图,这样就可以更快了解所需要的功能: 上一节我们利用了一个简单的代码例子,完成了与微信公众号的对话(给公众号发一条信息,并得到回复) 这一节将讲解公众号如何设 ...

  3. webpack学习总结

    前言 在还未接触webpack,就有几个疑问: 1. webpack本质上是什么? 2. 跟异步模块加载有关系吗? 3. 可否生成多个文件,一定是一个? 4. 被引用的文件有其他异步加载模块怎么办? ...

  4. BI分析受阻?FineBI推出SPA螺旋式分析新功能!

    过去,企业级的数据分析通常会有这么几种场景,业务部门托信息部门分析数据,结果报表一出,唇枪舌剑争论你我高低,数据不准,指标不对.信息部门欠缺业务概念,业务部门不懂技术逻辑,数据分析之路,暂时搁浅. 后 ...

  5. Android Studio开发RecyclerView遇到的各种问题以及解决(二)

    开发RecyclerView时候需要导入别人的例子,我的是从github导入的,下载下github的压缩包之后解压看你要导入的文件是priject还是Module.(一般有app文件夹的大部分是pro ...

  6. Android studio使用git教程

    ①下载Git工具,配置到Android studio中 http://git-scm.com/downloads ------------------------------------------- ...

  7. Linux不能上网ping:unknown host问题怎么解决?

    Linux不能上网提示ping:unknown host 检查步骤 Linux系统跟windows平台有所不同的是,为了更好的做网络服务应用.Linux下多用于网络服务器,而且操作界面是字符界面.对于 ...

  8. 闲话Promise机制

    Promise的诞生与Javascript中异步编程息息相关,js中异步编程主要指的是setTimout/setInterval.DOM事件机制.ajax,通过传入回调函数实现控制反转.异步编程为js ...

  9. 用C表达面向对象语言的机制——C#版

    PS:本文PDF版在这里(格式更好看一些).最新的源代码请在本页面文末下载,PDF中的链接不是最新的. 用C表达面向对象语言的机制——C#版 我一直认为,面向对象语言是对面向过程语言的封装.如果是这样 ...

  10. ADO.NET Entity Framework 在哪些场景下使用?

    在知乎回答了下,顺手转回来. Enity Framework已经是.NET下最主要的ORM了.而ORM从一个Mapping的概念开始,到现在已经得到了一定的升华,特别是EF等对ORM框架面向对象能力的 ...