Java—事件和多线程机制
一 事件
1.1 事件源
图形用户界面上每个可能产生事件的组件称为事件源。
1.2 事件监听者
Java系统中注册的用于接收特殊事件的类。不同的事件对应着不同的监听者,要想事件被监听者监听并处理,则需先将事件源注册到监听者。
1.3 事件处理流程
事件源触发事件并将事件作为一个参数传递给监听者,监听者实现某个接口中的抽象方法,从而实现对事件的处理。Java的事件处理机制是一个委托事件模型。
事件源注册的方法如下:
public void addActionListener(ActionListener l)
添加特定的动作,监听接收来自事件源的动作事件,如果l为空,不会产生任何动作。
监听者实现的接口为ActionListener接口,接口ActionListener来自包java.awt.event。
在此接口中只有一个方法:
public void actionPerformed(ActionEvent e)
当事件对象e发生时,调用此方法。监听者就需要实现这个方法。
1.4 动作事件
ActionEvent包含一个事件,该事件为执行动作事件ACTION_PERFORMED。触发这个事件的动作为:
(1) 点击按钮。
(2) 双击列表中的选项。
(3) 选择菜单项。
(4) 在文本框中输入回车。
常用方法如下:
public String getActionCommand() 返回引发某个事件的命令按钮的名字,如果名字为空,那么返回标签值。
public void setActionCommand(String command) 设置引发事件的按钮的名字,默认设置为按钮的标签。
例:测试动作事件
- package test;
- import java.awt.*;
- import java.awt.event.*;
- import java.applet.*;
- public class UseButton extends Applet implements ActionListener{
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- String str = new String();
- Button b1; //声明按钮对象;
- Button b2;
- Color c;
- public void init()
- {
- b1 = new Button("按钮对象1");
- b2 = new Button("按钮对象2");
- //添加事件监听者
- b1.addActionListener(this);
- b1.setBackground(Color.yellow);
- b2.addActionListener(this);
- this.add(b1);
- this.add(b2);
- }
- public void start()
- {
- str = b1.getLabel();
- //repaint();
- }
- public void paint(Graphics g)
- {
- g.setColor(c);
- g.drawString("引发事件的对象的标签:" + str, 80,60);
- }
- //实现接口中的方法,响应动作事件
- public void actionPerformed(ActionEvent e)
- {
- String arg = e.getActionCommand();
- if(arg == "按钮对象1")
- {
- c = Color.red;
- str = "按钮对象1";
- }
- else if(arg == "按钮对象2")
- {
- c = Color.green;
- str = "按钮对象2";
- }
- repaint();
- }
- }
点击按钮对象1 ,点击按钮对象2
输出结果:
1.5 文本事件(TextEvent)
文本事件即代表文本区域中文本变化的事件TEXT_VALUE_CHANGED,在文本区域中改变文本内容。
public void addTextListener(TextListener l) 添加特定的文本事件,监听者接收来自文本对象的文本事件。如果l为空,那么不会抛出任何异常,而且也不会完成任何动作。
public interface TextListener extends EventListener 用于接收文本事件的监听者接口。当对象的文本发生变化时,调用监听者对象的方法。
接口中的方法为:
public void textValueChanged(TextEvent e) 当文本发生改变时调用。
public Object getSource() 发生事件的对象,从EventObject继承来的方法。
例:测试文本事件
- package test;
- import java.awt.*;
- import java.awt.event.*;
- import java.applet.Applet;
- public class UseTextEvent extends Applet implements ActionListener, TextListener{
- /**
- * @ YMM 2016/05/09
- */
- private static final long serialVersionUID = 1L;
- TextField tOld;
- TextArea tNew;
- Panel p;
- public void init()
- {
- tOld = new TextField(25);
- tNew = new TextArea("",8,25,TextArea.SCROLLBARS_NONE);;
- //添加事件监听者
- tOld.addActionListener(this);
- tOld.addTextListener(this);
- //设置界面
- p = new Panel(new BorderLayout());
- p.add(tOld,BorderLayout.NORTH);
- p.add(tNew,BorderLayout.SOUTH);
- add(p);
- }
- //响应文本事件
- public void textValueChanged(TextEvent e)
- {
- if(e.getSource() == tOld)
- tNew.setText(tOld.getText());
- }
- //响应动作事件
- public void actionPerformed(ActionEvent e)
- {
- if(e.getSource() == tOld)
- tNew.setText("");
- }
- };
1.6 选择事件(ItemEvent)
选择事件中包含以事件为代表的选择项,选中状态发生变化的事件ITEM_STATE_ CHANGED。引发的动作为:
(1) 改变列表类List对象选项的选中或不选中状态。
(2) 改变下拉列表类Choice对象选项的选中或不选中状态。
(3) 改变复选按钮类Checkbox对象的选中或不选中状态。
事件源对象注册的方法如下:
public void addItemListener(ItemListener l) 添加特定的项监听者,接收对象的选择项发生变化的事件。
public ItemSelectable getItemSelectable() ItemEvent事件的方法,返回产生事件的事件源对象。
public interface ItemListener extends EventListener 接收选项事件的监听者接口。当选项中事件发生时,调用监听对象的itemStateChanged方法。
public void itemStateChanged(ItemEvent e) 当用户选中一项或未选中一项时,调用这个方法。
- package test;
- import java.awt.*;
- import java.awt.event.*;
- import java.applet.*;
- public class UseItemEvent extends Applet implements ItemListener{
- /**
- * 2016/05/09 @author jftt
- */
- private static final long serialVersionUID = 1L;
- Checkbox cDisp; //复选按钮
- Button btnDisp; //
- Choice cFont; //下拉列表
- public void init()
- {
- cDisp = new Checkbox("红色");
- btnDisp = new Button("颜色显示");
- //setLayout(null);
- btnDisp.setSize(120,120);
- cFont = new Choice();
- cFont.add("10");
- cFont.add("12");
- cFont.add("14");
- //添加事件
- cDisp.addItemListener(this);
- cFont.addItemListener(this);
- add(cDisp);
- add(cFont);
- add(btnDisp);
- }
- //接口事件
- public void itemStateChanged(ItemEvent e)
- {
- Checkbox temp;
- Choice temp2;
- Font oldF;
- //复选框
- if(e.getItemSelectable() instanceof Checkbox)
- {
- temp = (Checkbox)(e.getItemSelectable());
- //选中为红色,否则为蓝色
- if(temp.getState())
- btnDisp.setBackground(Color.red);
- else
- btnDisp.setBackground(Color.yellow);
- }
- //组合框
- if(e.getItemSelectable() instanceof Choice)
- {
- oldF = btnDisp.getFont();
- temp2 = (Choice)(e.getItemSelectable());
- String s = temp2.getSelectedItem();
- String s1=oldF.getName();
- int s2=oldF.getStyle();
- //设置字体
- btnDisp.setFont(new Font(s1,s2,Integer.parseInt(s)));// 字体,样式(粗体,斜体等),字号
- }
- }
- }
1.7 调整事件(AdjustmentEvent)
调整事件包含一个事件,即ADJUSTMENT_VALUE_CHANGED事件,当操纵滚动条改变其滑块位置时引发动作。AjustEvent的方法如下:
public Adjustable getAdjustable() 返回引发事件的对象。
public int getValue() 返回调整事件中的当前值。
public void addAdjustmentListener(AdjustmentListener l) 添加调整监听者来接收来自对象的AdjustmentEvent实例。
public interface AdjustmentListener extends EventListener 接收调整事件的监听接口,有一个方法:
public void adjustmentValueChanged(AdjustmentEvent e) 可在调整改变时调用这个值。
例:测试调整事件。设置一个水平滚动条,取值为1~36,随着滑块的变化,滚动条的值将显示在文本区域中,并且字体大小也会跟随变化
- package test;
- import java.awt.*;
- import java.awt.event.*;
- import java.applet.*;
- public class UseAdjustmentEvent extends Applet implements AdjustmentListener{
- /**
- * @author YMM 2016/05/09
- */
- private static final long serialVersionUID = 1L;
- Scrollbar s;
- TextArea txtValue;
- Panel p;
- public void init() {
- s = new Scrollbar(Scrollbar.HORIZONTAL,0,1,10,36);
- //添加监听者
- s.addAdjustmentListener(this);
- txtValue = new TextArea(5,25);
- //界面布局
- p = new Panel(new BorderLayout());
- p.add(s,BorderLayout.NORTH);
- p.add(txtValue,BorderLayout.SOUTH);
- add(p);
- }
- public void adjustmentValueChanged(AdjustmentEvent e) {
- int value;
- Font oldF;
- if(e.getAdjustable() == s)
- {
- //得到滚动条的值
- value = e.getValue();
- //将值写入文本区域
- txtValue.setText(new Integer(value).toString());
- //按照滚动条的值设置字体
- oldF = txtValue.getFont();
- txtValue.setFont(new Font(oldF.getName(),oldF.getStyle(),value));
- }
- }
- }
1.8 鼠标事件(MouseEvent)
表明画布或界面组件中发生的鼠标事件,包含按下鼠标、释放鼠标、单击鼠标、进入部件的地理位置的鼠标事件和退出部件的地理位置的鼠标事件,以及鼠标移动事件(鼠标移动和鼠标拖动)。
鼠标使用addMouseListener方法注册,通过MouseListener接收鼠标事件;鼠标还可以使用addMouseMotionListener方法注册,通过MouseMotionListener监听者监听鼠标移动事件。
监听者中有具体的方法分别针对上述具体的鼠标事件,系统能够自动分辨鼠标事件的类型并调用相应的方法,所以只需编码实现相应的代码就可以了。
public int getButton() 返回哪个按钮发生变化。
public int getClickCount() 返回与这个事件相关的鼠标单击的次数。
public Point getPoint() 返回同源部件相对的事件发生的x、y位置。
public int getX() 返回同源部件相对的事件发生的x位置。
public int getY() 返回同源部件相对的事件发生的y位置。
例:测试按钮和画布的鼠标事件,包括单击、按下、进入和退出等
- package test;
- import java.awt.*;
- import java.awt.event.*;
- import java.applet.*;
- public class UseMouseEvent extends Applet implements MouseListener,MouseMotionListener{
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- Button btn;
- public void init()
- {
- btn = new Button("演示鼠标事件");
- add(btn);
- //给按钮添加鼠标事件和鼠标移动事件
- btn.addMouseListener(this);
- btn.addMouseMotionListener(this);
- //给画布添加鼠标事件和鼠标移动事件
- this.addMouseListener(this);
- this.addMouseMotionListener(this);
- }
- //单击事件
- public void mouseClicked(MouseEvent e)
- {
- Point p = new Point();
- if(e.getSource() == btn)//getSource()发生事件的对象,从EventObject继承来的方法。
- {
- if(e.getClickCount() == 1)
- {
- btn.setLabel("单击鼠标");
- }
- else if(e.getClickCount() == 2)
- {
- btn.setLabel("双击鼠标");
- }
- }
- else
- {
- if(e.getClickCount() == 1)
- {
- p = e.getPoint();
- showStatus(p.x + "," + p.y + "单击鼠标");
- }
- else if(e.getClickCount() == 2)
- {
- p = e.getPoint();
- showStatus(p.x + "," + p.y + "双击鼠标");
- }
- }
- }
- //进入事件
- public void mouseEntered(MouseEvent e)
- {
- if(e.getSource() == btn)
- btn.setLabel("进入Button");
- else
- showStatus("进入Applet");
- }
- public void mouseExited(MouseEvent e)
- {
- if(e.getSource() == btn)
- btn.setLabel("退出Button");
- else
- showStatus("退出Applet");
- }
- //按下事件
- public void mousePressed(MouseEvent e)
- {
- if(e.getSource() == btn)
- btn.setLabel("按下鼠标");
- else
- showStatus("按下鼠标");
- }
- //释放事件
- public void mouseReleased(MouseEvent e)
- {
- if(e.getSource() == btn)
- btn.setLabel("松开鼠标");
- else
- showStatus("松开鼠标");
- }
- //移动事件
- public void mouseMoved(MouseEvent e)
- {
- if(e.getSource() == btn)
- btn.setLabel("移动鼠标");
- else
- showStatus("移动鼠标,新位置" + e.getX() + "," + e.getY());
- }
- //拖动事件
- public void mouseDragged(MouseEvent e)
- {
- if(e.getSource() == btn)
- btn.setLabel("拖动鼠标");
- else
- showStatus("拖动鼠标");
- }
- }
1.9 键盘事件(KeyEvent)
键盘事件有三个:键盘按键按下,按键释放,按键被敲击。常用方法如下:
public char getKeyChar() 返回事件中键的字符。
public int getKeyCode() 返回整数键码。
public static String getKeyText(int keyCode) 返回描述这个键码的字符串,例如“HOME”、“F1”或者“A”等。
public interface KeyListener extends EventListener 用来接收键盘事件。使用方法addKeyListener注册。
针对键盘的三个事件接口提供相应的方法进行处理,具体方法如下:
public void keyPressed(KeyEvent e) 按键时引发事件处理。
public void keyReleased(KeyEvent e) 释放键时引发事件处理。
public void keyTyped(KeyEvent e) 键入键时引发事件处理。
例:
- package test;
- import java.applet.Applet;
- import java.awt.*;
- import java.awt.RenderingHints.Key;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyEvent;
- import java.awt.event.KeyListener;
- import java.awt.event.TextEvent;
- import java.awt.event.TextListener;
- public class UseKeyEvent extends Applet implements KeyListener,ActionListener, TextListener {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- Key key;
- Button btn;
- TextField txt;
- public void init()
- {
- btn = new Button("演示键盘事件");
- add(btn);
- btn.addKeyListener(this);
- this.addKeyListener(this);
- txt = new TextField(25);
- //添加事件监听者
- txt.addActionListener(this);
- txt.addTextListener(this);
- //设置界面
- add(txt,BorderLayout.NORTH);
- }
- @Override
- public void keyTyped(KeyEvent e) {//键入键时引发事件处理
- // TODO 自动生成的方法存根
- char ch = e.getKeyChar();
- if(ch =='Y' || ch == 'y')
- txt.setText ("同意");
- else if (ch == 'N' || ch == 'n')
- txt.setText ("反对");
- else
- txt.setText ("无效");
- }
- @Override
- public void keyPressed(KeyEvent e) {
- // TODO 自动生成的方法存根
- btn.setLabel("按键时引发事件处理");
- }
- @Override
- public void keyReleased(KeyEvent e) {
- // TODO 自动生成的方法存根
- btn.setLabel("释放键时引发事件处理");
- }
- @Override
- public void textValueChanged(TextEvent e) {
- // TODO 自动生成的方法存根
- }
- @Override
- public void actionPerformed(ActionEvent e) {
- // TODO 自动生成的方法存根
- }
- }
二 多 线 程 机 制
2.1 线程简介
线程(thread)就是进程中的一个执行线索。Java虚拟机允许进程中同时执行多个线程。每个线程都有一个优先级。具有较高优先级的线程先执行。
线程是操作系统分配 CPU 时间的基本实体。每一个应用程序至少有一个线程,也可以拥有多个线程。线程是程序中的代码流。多个线程可以同时运行并能共享资源。
线程与进程不同,每个进程都需要操作系统为其分配独立的地址空间,而同一进程中的各个线程是在同一块地址空间中工作。
在 Java 程序中,一些动态效果(如动画的实现、动态的字幕等)常利用多线程技术来实现。
线程存在一个生命周期,由以下方法体现:
(1) start()方法:启动一个线程。
(2) run()方法:定义该线程的动作。
(3) sleep()方法:使线程睡眠一段时间,单位为ms。
(4) suspend()方法:使线程挂起。
(5) resume()方法:恢复挂起的线程。
(6) yield()方法:把线程移到队列的尾部。
(7) stop()方法:结束线程生命周期并执行清理工作。
(8) destroy()方法:结束线程生命周期但不做清理工作。
其中最常用的是方法start()、run()、sleep()、stop()。
2.2 线程类和Runnable接口
2.2.1. 建立Thread类的子类
class myThread extends Thread
{
...
public void start()//启动线程
{
...
}
public void run()//运行线程
{
...
}
}
例:多线程实例,主函数给予调用
- public class MThread
- {
- public static void main(String[] args)
- {
- System.out.println("Hello World!");
- thread2 t1 = new thread2("线程实例1"); //创建线程实例
- t1.start(); //调用
- thread2 t2 = new thread2("线程实例2");
- t2.start();
- thread2 t3 = new thread2("线程实例3");
- t3.start();
- }
- }
- //自定义线程类thread2
- class thread2 extends Thread
- {
- Thread thread; //定义线程实例
- String str;
- //构造函数
- public thread2(String str)
- {
- this.str = str;
- }
- //启动线程
- public void start()
- {
- thread = new Thread(this);
- thread.start();
- }
- public void run()
- {
- int i = 0;
- while(thread != null)
- {
- try
- {
- //计数到5时睡眠10秒
- if(i == 5)
- sleep(10000);
- }
- catch(Exception e)
- {
- System.out.println(e.getMessage());
- }
- System.out.println(str);
- i++;
- }
- }
- };
2.2.2. 实现接口Runnable
public interface Runnable
Runnable接口可以由任意试图实现线程机制的类来实现。接口包含一个run方法。
public void run()
对象实现Runnable接口时,创建一个线程,启动线程导致对象run方法的调用。
实现接口Runnable进行多线程设计的方法较为常用。下面给出一个例子。
例:编写Applet,实现Runnable接口进行简单的动画演示:三幅图片依次上移
- package test;
- import java.applet.Applet;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.Toolkit;
- import javax.print.DocFlavor.URL;
- public class UseRunnable extends Applet implements Runnable{
- /**
- *
- */
- private static final long serialVersionUID = 1L;
- Thread t;
- Image imgs[];
- int high,h1,h2,h3;
- public void init()
- {
- high = getHeight()/3;
- h1 = high;
- h2 = high * 2;
- h3 = high * 3;
- imgs = new Image[3];
- for (int i = 0; i < 3; i ++)
- {
- /*java.net.URL url=getDocumentBase();
- imgs[i] = getImage(getDocumentBase(),(i+1) + ".jpg");*/
- imgs[i]=Toolkit.getDefaultToolkit().getImage("E:\\WorkSpace\\ecplise-luna\\JavaTest\\src\\test\\"+(i+1)+".jpg ");
- }
- }
- public void start()
- {
- t = new Thread(this);
- t.start();
- }
- public void stop()
- {
- t = null;
- }
- //实现接口的run方法,获得动画效果
- public void run()
- {
- while( t != null)
- {
- try
- {
- Thread.sleep(100);
- repaint();
- h1 --;
- //上移,到顶点时睡眠
- if(h1 == 0)
- {
- Thread.sleep(3000);
- h2 = high;
- }
- //上移,到顶点时睡眠
- h2 --;
- if(h2 == 0)
- {
- Thread.sleep(3000);
- h3 = high;
- }
- //上移,到顶点时睡眠
- h3--;
- if(h3 == 0)
- {
- Thread.sleep(3000);
- h1 = high;
- }
- }catch(InterruptedException e){
- System.out.println(e.getMessage());
- }
- }
- }
- public void paint(Graphics g)
- {
- //三幅图片依次显示
- g.drawImage(imgs[0],0,h1,this);
- g.drawImage(imgs[1],0,h2,this);
- g.drawImage(imgs[2],0,h3,this);
- }
- public void update(Graphics g)
- {
- paint(g);
- }
- }
Java—事件和多线程机制的更多相关文章
- java事件监听机制
1.简单的事件监听 package demo2; /* * java事件监听机制 */ import java.awt.*; import javax.swing.*; import java.awt ...
- java事件监听机制2
今天早上的两点收获: 1.addActionListener(其中的setActionCommand函数就是要对对象进行唯一性的标记,便于消息传来后进行处理.理论上actionlistener可以全部 ...
- JAVA事件监听机制的实现
今天学习了java的事件编程机制,略有体会,先在此记下心得. 第一,首先明确几个概念. 事件源:一个产生或者触发事件的对象.事件:承载事件源状态改变时的信息对象.事件监听器接口:实际上就是一个类,该类 ...
- Java事件监听机制与观察者设计模式
一. Java事件监听机制 1. 事件监听三要素: 事件源,事件对象,事件监听器 2. 三要素之间的关系:事件源注册事件监听器后,当事件源上发生某个动作时,事件源就会调用事件监听的一个方法,并将事件对 ...
- JAVA事件监听机制学习
//事件监听机制 import java.awt.*; import java.awt.event.*; public class TestEvent { public static void mai ...
- JAVA事件监听机制与实现
事件监听机制的实现:参考图:事件模型_ActionEvent 为了节省资源,系统无法对某个事件进行实时的监听.故实现的机制是当发生某个事件后,处理代码将被自动运行,类似钩子一般.(回调函数) 事件有许 ...
- java 事件监听机制组成
事件源(组件) 事件(Event) 监听器(Listener) 事件处理(引发事件后处理方式) 事件监听机制流程图 务必记牢: 确定事件源(容器或组件) 通过事件源对象的addXXXListener( ...
- java事件监听机制(自定义事件)
java中的事件机制的参与者有3种角色: 1.event object:事件状态对象,用于listener的相应的方法之中作为参数,一般存在与listerner的方法之中 2.event source ...
- 【转】java事件监听机制
java中的事件机制的参与者有3种角色: 1.event object:事件状态对象,用于listener的相应的方法之中作为参数,一般存在与listerner的方法之中 2.event source ...
随机推荐
- easyui DataGrid 工具类之 TableUtil class
import java.lang.reflect.InvocationTargetException;import java.util.ArrayList;import java.util.HashM ...
- ShowDoc部署手册
ShowDoc介绍 关于ShowDoc的介绍,请访问:http://blog.star7th.com/2015/11/1816.html 环境依赖 1.必需环境 PHP5.3以上版本.php-gd库 ...
- php 笔试题
1.用PHP打印出前一天的时间格式是2006-5-10 22:21:21 解:echo date(‘Y-m-d H:i:s’, strtotime(‘-1 day’)); 原因: format 字符说 ...
- (10) 深入了解Java Class文件格式(九)
转载:http://blog.csdn.net/zhangjg_blog/article/details/22432599 经过前八篇关于class文件的博客, 关于class文件格式的内容也基本上讲 ...
- cocos2dx && Lua 环境配置
需要的材料: 1.vs2013 2.python-2.7.3(2.7.x高于2.7的版本可能会出现错误) 3.Sublime Text 2(破解的) 4.cocos2dx-3.2 步骤: 1.安装vs ...
- Mark Down 尝试
Hello World iawriter sublime text
- python中的 descriptor
学好和用好python, descriptor是必须跨越过去的一个点,现在虽然Python书籍花样百出,但是似乎都是在介绍一些Python库而已,对Python语言本身的关注很少,或者即使关注了,但是 ...
- 【Treap】bzoj1588-HNOI2002营业额统计
一.题目 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司 ...
- win7的HOST文件夹具体位置
win7的HOST文件位置为C:\WINDOWS\system32\drivers\etc\文件夹下,快捷查看方法如下: 1.按win+r,输入C:\WINDOWS\system32\drivers\ ...
- widgets、dialogs与自动连接(auto-connect)
QMetaObject的自动连接设施(auto-connect facilities)可以自动将槽与信号连接起来,只需要声明和定义一个符合标准命名规则的槽函数 void on_<object n ...