配色: 字号:
java浜嬩欢澶勭悊
2012-07-11 | 阅:  转:  |  分享 
  
Java程序设计语言--------事件处理计算机科学与技术学院GUI组件概述awt:Abstr
actWindowToolkit——抽象窗口工具集从Java1.0中出现。awt处理用户界面元素的方法是把这些元素的创建和
行为委托给每个目标平台(如windows,Linux)上的本地GUI处理。每个平台提供的图形界面元素都不一样。不同平台上的aw
t库存在不同Bug。awt的事件处理模型在Java1.1版进行了大的改动后,到目前的版本基本没变。swing:Java2.
0中出现。Swing组件全部是由纯Java编写的,用户界面元素都绘制在空白窗口上,绘制和行为都由swing类自己完成。各平台之间
唯一不同的就是最外层窗口的创建。总结:尽管awt的用户界面组件仍然可以用,但是建议最好不要使用。现在编写Java图形界面程序
,使用swing组件+awt事件处理模型。事件处理概述图形用户界面编程中,必须使用事件处理。支持GUI的操作环境会不断监
视事件,并把事件报告给正在运行的程序。这是多任务的需要。每个程序决定如何相应这些事件。Java的事件处理采用的是事件监听器方式
。事件监听器是一个实现了监听器接口的对象。事件源(如按钮组件)是一个能够注册监听器并为它们发送事件的对象。每个事件源拥有自己
的事件监听器,可以有多个。当事件源产生了一个事件后,事件源就会给所有监听器对象发送通知,即调用事件监听器对象的相应方法。事件的
信息被封装在一个对象中,不同事件源能够产生不同种类的事件。编程人员要做的就是编写事件监听器类,创建一个事件监听器对象,并注册到相
应的事件源。事件监听器编写编写事件处理程序的步骤如下:编写监听器类;在监听器类中实现接口中需要的方法;方法中可以使用A
ctionEvent对象判断事件;创建一个事件监听器对象;将该对象添加到事件源。见Example1.javaimport
java.awt.;importjava.awt.event.;importjavax.swing.;public
classExample1extendsJFrame{publicExample1(){ se
tSize(320,200); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ContainercontentPane=getContentPane(); JButtontestButton=
newJButton("Test"); testButton.addActionListener(newMyListener
1()); contentPane.setLayout(newBorderLayout()); contentPane.ad
d(testButton,BorderLayout.SOUTH);}}classMyListener1imp
lementsActionListener{publicvoidactionPerformed(ActionEv
ente){ JOptionPane.showMessageDialog(null, "ActionComma
nd:"+e.getActionCommand());}}事件源与监听器的关系一个事件源可以对应多个监听器。
一个监听器可以对应多个事件源。classMyListener2implementsActionListener{
publicvoidactionPerformed(ActionEvente){ Stringaction
Command=e.getActionCommand(); ColorbkColor=null; if(action
Command.equals("Red"))bkColor=newColor(255,0,0); elseif(acti
onCommand.equals("Green"))bkColor=newColor(0,255,0); elseif(
actionCommand.equals("Blue"))bkColor=Color.blue; getContentPan
e().setBackground(bkColor);}}见Example2.javaclassMyListe
ner1implementsActionListener{publicvoidactionPerformed(
ActionEvente){ JOptionPane.showMessageDialog(null, "Acti
onCommand:"+e.getActionCommand());}}myListener2myListen
er1事件监听器类的各种写法监听器类的声明:将事件监听器作为单独的类。将事件监听器作为组件的内部类。直接使用已有类(通常
是包含事件源的组件)作为事件监听器。使用匿名内部类。监听器类的实现:一个监听器类实现多个组件的监听器对象。通过类中的实例字
段来区分不同的监听器对象。一个监听器对象作为多个组件的监听器。在事件的响应方法中通过事件源区分不同的事件。publiccl
assExample1extendsJFrame implementsActionListener{publi
cvoidactionPerformed(ActionEvente){…}}见Example3.javaredButt
on.addActionListener(newActionListener() //匿名内部类监听器{ publ
icvoidactionPerformed(ActionEvente) { …… }});改变观感改变
观感使用两个静态方法:UIManager.setLookAndFeel(plaf)设置要使用的观感参数plaf为观感的名字,实
际为一个类名,可以为以下字符串:javax.swing.plaf.metal.MetalLookAndFeelcom.sun.
java.swing.plaf.windows.WindowsLookAndFeelcom.sun.java.swing.pla
f.motif.MotifLookAndFeelSwingUtilities.updateComponentTreeUI(pan
el)刷新要改变的组件参数panel给出面板中的一个组件即可刷新整个面板。见Example4.javatButton.add
ActionListener(newActionListener(){publicvoidactionPerfo
rmed(ActionEventaEvent){ try{ UIManager.setLookAnd
Feel(aPlafName); SwingUtilities.updateComponentTreeUI(Exam
ple4.this); }catch(Exceptione){ e.printStackTrace(); };
}});窗口事件ActionListener接口非常简单,用于按钮事件处理。相应的,WindowListene
r接口用于窗口事件处理。见Example5.javapublicclassExample5extendsJFrame
{publicExample5(){ … setDefaultCloseOperation(JFram
e.DO_NOTHING_ON_CLOSE); addWindowListener(newMyWindowListener()
);}privateclassMyWindowListenerimplementsWindow
Listener{ publicvoidwindowOpened(WindowEvente){} publi
cvoidwindowClosing(WindowEvente) {intresult=JOptionPa
ne.showConfirmDialog(……); if(result==JOptionPane.OK_OPT
ION)System.exit(0); } publicvoidwindowClosed(WindowEvente){}
publicvoidwindowIconified(WindowEvente){} publicvoidwindo
wDeiconified(WindowEvente){} publicvoidwindowActivated(Window
Evente){} publicvoidwindowDeactivated(WindowEvente){}
}}添加窗口事件监听器窗口事件监听器实现WindowListener接口要处理的窗口事件适配器类问题:仅仅需要处理关
闭窗口事件,但却要写另外六个空方法。解决方法:使用适配器类。适配器类是一个实现了某个接口,但其中所有方法都为空的类。每个具有
不止一个方法的监听器接口都对应有一个适配器类。编写监听器类时只需从适配器类派生一个子类即可。见Example6.javapr
ivateclassMyWindowListenerextendsWindowAdapter{ publicvoid
windowClosing(WindowEvente) {intresult=JOptionPane.sho
wConfirmDialog(……); if(result==JOptionPane.OK_OPTION)Sy
stem.exit(0); }}由实现接口改为继承自适配器类,从而不用再写另外六个无用方法。见Example6.ja
vaaddWindowListener(newWindowAdapter(){ publicvoidwindo
wClosing(WindowEvente) {intresult=JOptionPane.showConfi
rmDialog(……); if(result==JOptionPane.OK_OPTION)System.e
xit(0); }});也可写成匿名内部类WindowListenerWindowAdapterMyWin
dowAdapterJava事件概述Java中所有事件都从java.util.EventObject类继承而来。两个包中定义
了事件:java.awt.event:awt的事件、监听器及适配器定义。java.swing.event:专门用于swing组
件的附加事件。如何查找组件能够发出哪些事件:查找组件能够添加哪些事件监听器(addListener)根据方法参数查找相
应的接口,即可知道具体的事件含义java.awt.event包中定义了11个监听器接口、7个适配器类java.awt.even
t包中的11个监听器接口ActionListener WindowListenerAdjustmentListener Com
ponentListenerContainerListener FocusListenerItemListener KeyLi
stenerMouseListener MouseMotionListenerTextListenerjava.awt.ev
ent包中的7个适配器类WindowAdapter ComponenAdapterContainerAdapter Focus
AdapterKeyAdapter MouseAdapterMouseMotionAdapterawt事件虽然接口和类比较
多,但原理都一样。定义实现监听器接口的监听器类,在相应方法中添加事件处理代码。创建一个监听器类的对象,添加到事件源的监听器列表
中。awt事件分为语义事件和低级事件。语义事件是有明确意义的事件。ActionEvent:按钮按下、菜单选择、选择列表项、文
本域中按回车AdjustmentEvent:调整滚动条ItemEvent:从一组选择框或列表项中选择一个TextEvent:
文本域或文本框中内容发生变化低级事件是较小的基本事件。ComponentEvent:组件被显示、隐藏、改变位置、改变大小Ke
yEvent:键盘上的一个键被按下或者释放MouseEvent:鼠标按键的按下和释放,鼠标移动或拖动FocusEvent:组件
得到焦点或失去焦点WindowEvent:窗口被显示、隐藏、关闭、激活、图标化、还原ContainerEvent:容器中加入或
移除一个组件键盘事件键盘事件监听器KeyListener有三个方法:voidkeyPressed(KeyEvente):
对应于按键按下。voidkeyReleased(KeyEvente):对应于按键弹起。voidkeyTyped(KeyE
vente):结合上述两个事件,直接报告按了按键,用于不须区分按下和弹起的情况。键盘事件类KeyEvent的主要方法有:ch
argetKeyChar():得到按键对应的字符。intgetKeyCode():得到按键对应的扫描码。staticSt
ringgetKeyText(intkeyCode):将扫描码转化为说明字符串。如何处理键盘事件:(示例见KeyExampl
e.java)用按键的扫描码可以准确的确定按键。KeyEvent类中定义了所有按键的扫描码常量,如:VK_A,VK_SHIFT
,VK_F10,VK_ENTER,VK_LEFT,VK_NUMPAD1。判断SHIFT,CONTROL,ALT的状态可以
使用KeyEvent的isShiftDown,isControlDown,isAltDown方法。JPanel的键盘事件键
盘事件只在事件源组件获得输入焦点时触发。缺省情况下,JPanel因无法得到输入焦点,所以不能得到键盘事件。解决方法是:覆盖其i
sFocusTraversable方法,使其返回true,从而使JPanel可以得到输入焦点,接收键盘事件。主意,窗口中不能同时
出现其他能够获得输入焦点的组件。见KeyExample1.javaJPaneltestPanel=newKeyPane
l();//若将上面的KeyPanel()改为JPanel(),则无法接收键盘事件testPanel.addKeyListe
ner(…)classKeyPanelextendsJPanel{ publicbooleanisFocusTra
versable() { returntrue; }}销毁键盘事件问题:设计一个JTextField,用于输入电话
号码。要求只能输入数字,不能输入其他字符。解决方法:用KeyEvent的consume()方法销毁键盘事件,使其不能传递到组件
。销毁键盘事件要在键盘事件监听器的keyTyped方法中进行。见KeyExample2.javanumField.addK
eyListener(newKeyAdapter(){ publicvoidkeyTyped(KeyEvente)
{ charch=e.getKeyChar(); if(ch<''0''||ch>''9'')e.consum
e(); }});鼠标事件鼠标事件监听器MouseListener有五个方法:voidmousePressed(Mou
seEvente):对应于鼠标按键按下事件voidmouseReleased(MouseEvente):对应于鼠标按键释
放事件voidmouseClicked(MouseEvente):结合上述两个方法,直接报告鼠标点击事件,用于不须区分按下
或释放的情况。voidmouseEntered(MouseEvente):对应于鼠标移动进入组件voidmouseEx
ited(MouseEvente):对应于鼠标移出组件鼠标事件类MouseEvent的常用方法有:intgetButto
n():得到发生动作的按键(BUTTON1,BUTTON2,BUTTON3)。intgetClickCount():得到点
击次数,主要用于双击事件。PointgetPoint()(或intgetX(),intgetY()):得到事件发生时鼠标的
相对位置。intgetModifiers():得到鼠标按键和键盘组合键的状态。鼠标与键盘组合使用:(见MouseExamp
le.java)在鼠标事件中判断SHIFT,CONTROL,ALT的状态可以使用MouseEvent的isShiftDown,
isControlDown,isAltDown方法。一般鼠标事件的处理功能:执行以下操作,程序就退出:按住Shift键在
testButton左边50像素之内双击鼠标左键说明因为是双击事件,所以最后由鼠标点击事件触发,对应于mouseClicked
方法。见MouseExample.javapublicvoidmouseClicked(MouseEvente){
if(e.getButton()==MouseEvent.BUTTON1&& //鼠标左键 e.getClickCount(
)==2&& //双击 e.getX()<50&& //在testButton左边50像素 e.isShiftD
own()) //按下键盘Shift键 { System.exit(0); }}多个鼠标按键状态的判断功能:执行
以下操作,程序就退出:按住鼠标左键和右键按住键盘Ctrl键将鼠标从testButton移出说明因为事件由鼠标移出触发,所
以对应于mouseExited方法。见MouseExample.javapublicvoidmouseExited(Mou
seEvente) //鼠标移出testButton事件{ intmodifiers=e.getModifiers
(); //得到鼠标当前状态 intexitMask=MouseEvent.BUTTON3_MASK| //鼠标右键
MouseEvent.CTRL_MASK| //按下键盘Ctrl键 MouseEvent.BUTTON1_MASK; /
/鼠标左键 if((modifiers&exitMask)==exitMask) { System.exit(0);
}}设置鼠标图标功能:当鼠标移动到testButton上时,变为手形。当鼠标移出testButton后,变为箭头形状。
说明:有两种方法可以完成此功能1、直接调用testButton的setCursor方法设置按钮的鼠标图标。2、需要同时在mo
useEntered和mouseExited方法中设置窗口的鼠标图标。3、鼠标的形状见Cursor类的文档。方法2、见Mous
eExample.javapublicvoidmouseEntered(MouseEvente){ setCursor(
Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));}publicvoidmo
useExited(MouseEvente){ setCursor(Cursor.getPredefinedCursor(Cu
rsor.DEFAULT_CURSOR));}方法1、见MouseExample.javatestButton.setCur
sor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));鼠标移动事件鼠标移动事
件监听器MouseMotionListener有两个方法:voidmouseDragged(MouseEvente):对应于
鼠标的拖动,即鼠标在组件上按下,然后移动位置,可以移动出组件之外。voidmouseMoved(MouseEvente):对
应于鼠标的移动,即没有按钮按下,且鼠标只在组件内部移动位置。鼠标移动事件监听器的入口参数与MouseListener相同,也是M
ouseEvent类型。鼠标移动事件的处理:mouseDragged事件通常用于组件内部的某些物体形状、位置等改变。mous
eMoved事件通常用于组件内部鼠标光标的改变。在鼠标移动事件监听器中,可以使用MouseEvent的各种方法来获得鼠标的当前状态。(见MouseMoveExample.java)定时器事件定时器可以实现每隔一段时间触发一个事件:实现定时器使用javax.swing.Timer类。同时,还有一个java.util.Timer类,注意类名的区分。Timer类的主要方法:Timer(intdelay,ActionListenerlistener):构造函数voidstart():启动定时器voidstop():停止定时器见TimerExample.javaTimert=newTimer(1000,newActionListener() { publicvoidactionPerformed(ActionEvente) { infoLabel.setText(String.valueOf(counter++)); } });t.start();事件处理总结事件处理机制:事件源自动调用其事件监听器列表中的对象的方法。Java事件处理编程创建事件监听器类,在相应的方法中编写事件处理代码;声明一个事件监听器对象;将事件监听器对象添加到事件源的监听器列表。主要事件包括以下类型:组件产生的语义事件:按钮事件、窗口事件、……键盘事件鼠标事件:鼠标点击事件、鼠标移动事件定时器事件
献花(0)
+1
(本文系toceansoft首藏)