版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java开发综合实战STYLEREFbt1a项目六STYLEREFbt1bGUI事件处理项目六GUI事件处理思政目标把握客观事物之间的联系和发展规律,具体问题具体分析。遵循实事求是的原则,构建包含防范机制、处置机制和善后机制在内的教育应对机制。技能目标掌握Java的事件处理模式。能够对GUI中的常用事件进行处理。项目导读创建了图形用户界面后,由于组件本身并没有实现任何交互功能,因此要实现用户与应用程序的交互,还要处理组件上发生的事件。Java采用事件处理机制响应用户的操作请求,即程序的运行过程是不断地响应各种事件的过程,事件的产生顺序决定了程序的执行顺序,事件处理是图形用户界面应用程序的重要组成部分,是实现各种操作功能的重要途径。任务1认识事件处理机制任务引入小白创建了进销存管理系统的操作界面,但单击界面上的按钮没有反应。在Java中,该怎样响应用户在图形用户界面的操作呢?知识准备事件处理机制专门用于响应用户的操作,例如,响应用户的单击鼠标、按下键盘键、选择列表项等操作。一、事件处理模式在学习如何使用事件处理机制之前,首先必须很好地掌握事件对象、事件源、事件监听器、事件处理器这4个概念。1.事件对象封装GUI组件上发生的特定事件的类对象,通常是用户的一次操作,如单击按钮、按下按键等。2.事件源能够产生事件的对象都可以称为事件源,通常是产生事件的组件,如文本框、按钮、下拉式列表等。3.事件监听器负责监听事件源上发生的事件,以便对发生的事件进行处理。事件源通过调用相应的方法将某个对象注册为自己的监听器。例如,对于文本框,这个方法是addActionListener(监听器)。对于注册了监听器的文本框,在文本框获得输入焦点后,如果用户按回车键,Java运行环境就自动用ActionEvent类创建一个对象,即发生了ActionEvent事件。也就是说,事件源注册监听器之后,相应的操作就会导致相应事件的发生,并通知监听器,监听器就会做出相应的处理。4.事件处理器负责接收事件对象并进行相应处理的方法,包含在一个事件监听器类中。事件监听器实质上就是一个实现特定类型监听器接口的类对象,为了处理事件源发生的事件,监听器这个对象会自动调用一个方法来处理事件。那么监听器去调用哪个方法呢?创建监听器对象的类必须声明实现相应的接口,即必须在类体中重写接口中所有方法,那么当事件源发生事件时,监听器就自动调用被类重写的接口方法处理事件。上述4个概念彼此之间联系紧密,在整个事件处理机制中起着非常重要的作用。事件处理模式如图6-1所示。图6-1事件处理模式综上,在程序中,如果要实现事件的监听处理机制,首先要定义一个实现了事件监听器接口的类,例如ActionListener。然后通过addActionListener()方法为事件源注册事件监听器对象。当事件源发生事件产生事件对象时,便会触发事件监听器对象,由事件监听器调用相应的方法来处理相应的事件。二、事件类当发生一个事件时,该事件用一个事件对象表示,事件对象有对应的事件类。不同的事件类描述不同类型的用户动作。Java将事件分为两个类别:低级事件与语义事件。绝大部分与图形用户界面有关的事件类都位于java.awt.event包中,其中包含了各种事件类别的监听接口。javax.swing.event包中定义了与Swing事件有关的事件类,例如DocumentEvent类。1.低级事件低级事件是指来自键盘、鼠标和与窗口操作有关的事件。例如,关闭窗口、移动鼠标、获取焦点或敲击键盘等。java.awt.event包中的低级事件类如表6-1所示。表6-1低级事件类事件类名说明FocusEvent组件获得或失去焦点时产生的事件MouseEvent鼠标按下、释放、拖动、移动时产生的事件KeyEvent键盘按键按下或释放时产生的事件WindowEvent对窗口操作产生的事件2.语义事件语义事件是指与组件有关的事件。例如,单击按钮、在文本域中输入文本、拖动滚动条、选择列表项等。java.awt.event包中常用的语义事件类如表6-2所示。表6-2常用的语义事件类事件类名说明ActionEvent单击按钮、选中菜单项、在文本框中按Enter键时产生的事件AdjustmentEvent调节滚动条位置时产生的事件ItemEvent选择复选框、单击列表框、选择列表项时产生的事件任务2常用事件任务引入大致了解了事件处理的基本流程之后,勤于思考的小白又有了新的问题:Java提供了哪些事件,这些事件如何触发呢?如果只需要对某个事件监听类中的单个事件进行监听,而不关心其他的事件,能不能只重写该事件对应的方法呢?知识准备Java中的常用事件包括窗体事件、鼠标事件、键盘事件、动作事件、选项事件、焦点事件和文档事件。每个事件类都对应着一个监听器接口,比如窗体事件类WindowEvent对应着WindowListener接口。一个类只要实现了某个监听器接口就是一个监听器类了。监听器接口中定义了一些方法,监听器类可以具体实现其中部分或是所有的方法,事件被引发后就会执行这些方法。一、窗体事件(WindowEvent)大部分GUI应用程序都需要使用Window(窗体)对象作为最外层的容器,窗体对象都可以发生窗体事件,如窗体的打开、关闭、激活、图标化等。在应用程序中,触发窗体事件时,WindowEvent类创建一个窗体事件对象。该对象调用getWindow()方法可以获取发生窗体事件的窗口。在对窗体事件进行处理时,首先需要定义一个实现了WindowListener接口的类作为窗体监听器,然后通过addWindowListener()方法将窗体对象与窗体监听器绑定。WindowListener接口中有7个不同的方法,如表6-3所示,不同的窗体事件触发时,窗体监听器调用不同的方法。
表6-3WindowListener接口的方法方法说明publicvoidwindowActivated(WindowEvente)窗口从非激活状态到激活时调用publicvoidwindowDeactivated(WindowEvente)窗口从激活状态到非激活状态时调用publicvoidwindowClosing(WindowEvente)窗口被关闭时调用publicvoidwindowClosed(WindowEvente)窗口关闭后调用publicvoidwindowIconified(WindowEvente)窗口图标化(最小化)时调用publicvoidwindowDeiconified(WindowEvente)窗口从最小化恢复到正常状态时调用publicvoidwindowOpened(WindowEvente)窗口打开时调用案例——关闭窗口本案例创建一个窗口,首先定义一个实现了WindowListener接口的类作为窗体监听器,然后为“关闭”按钮注册监听器,实现单击“关闭”按钮关闭窗口的操作。通过本案例,帮助读者进一步了解事件处理模式和流程。(1)在Eclipse中新建一个名为EventDemo的Java项目。在其中添加一个名为MyWindowListener的类,用作窗口监听器类。(2)在编辑器中编写代码,使类MyWindowListener实现WindowListener接口,并实现windowClosing()方法,用于处理关闭窗口的事件。具体代码如下:importjava.awt.Window;importjava.awt.event.WindowEvent;importjava.awt.event.WindowListener;publicclassMyWindowListenerimplementsWindowListener{ publicvoidwindowClosing(WindowEvente){//实现windowClosing()方法 Windowwin=e.getWindow(); win.setVisible(false); win.dispose(); } //实现WindowListener接口中的其他方法,由于不需要,所以留空 publicvoidwindowActivated(WindowEvente){} publicvoidwindowClosed(WindowEvente){} publicvoidwindowDeactivated(WindowEvente){ } publicvoidwindowDeiconified(WindowEvente){ } publicvoidwindowIconified(WindowEvente){} publicvoidwindowOpened(WindowEvente){ }}上述的代码在实现WindowListener接口的windowClosing()方法时,首先接受事件源产生并传递的WindowEvent类创建的窗体事件对象e,该对象调用getWindow()方法获取发生窗体事件的窗口。然后调用setVisible()方法设置窗口不可见,调用dispose()方法释放窗口资源。这里要再次提请读者注意的是,在实现WindowListener接口时,应实现该接口中的所有方法,即使不需要所有的方法。本实例将其他方法体留空,但不能省略。(3)在项目中添加一个名为WindowEventTest的类,用于将窗体对象与窗体监听器进行绑定,并测试触发窗体事件的效果。(4)在类体中编写主方法,实例化一个JFrame窗体对象,设置窗体位置和大小以及可见性,然后为窗体对象注册监听器。具体代码如下:importjavax.swing.JFrame;publicclassWindowEventTest{ publicstaticvoidmain(String[]args){ JFramejf=newJFrame("测试窗口"); //建立新窗体 jf.setBounds(300,200,260,160); //设置窗体的位置和大小 jf.setVisible(true); //设置窗体可见 //为窗口组件注册监听器 MyWindowListenerwl=newMyWindowListener(); jf.addWindowListener(wl); }}在上面的代码中,使用addWindowListener()方法为事件源jf注册事件监听器对象wl。当事件源发生事件时,便会触发事件监听器对象,由事件监听器调用相应的方法来处理相应的事件。(5)运行WindowEventTest.java,即可在指定位置弹出一个指定大小的窗口,如图6-2所示。单击窗口右上角的“关闭”按钮,即可关闭窗口。图6-2运行结果提示:本例没有指定“关闭”按钮的处理方式。默认情况下,会调用setDefaultCloseOperation(HIDE_ON_CLOSE)方法,调用任意已注册的WindowListener对象后隐藏当前窗体。二、事件适配器在Java中,当一个类实现一个接口时,必须实现接口中所有的方法,即使不需要其中的某些方法也需要实现,这在实际应用中会导致很多代码多余但又无法省略,如上例所示。这种情况下,可以使用适配器的设计模式代替接口处理事件,在实现类和接口之间增加一个过渡的抽象类,子类继承抽象类就可以根据自己的需要重写需要的方法。Java在事件处理中提供了很多的Adapter(适配器)类,处理事件的接口多于一个方法时,Java相应地就提供一个适配器类,方便用户进行事件处理的实现,例如WindowAdapter、MouseAdapter、KeyAdapter、MouseMotionAdapter和FocusAdapter。适配器已经实现了相应的接口,因此,可以使用适配器的子类创建的对象作为监听器,在子类中重写所需要的接口方法即可。案例——使用WindowAdapter本案例修改上一个案例,使用适配器做监听器,只处理窗口关闭事件,因此只需重写windowClosing()方法即可。(1)打开MyWindowListener.java,引入java.awt.event.WindowAdapter包,然后修改代码,使MyWindowListener类继承WindowAdapter,然后删除其他重写的方法。修改后的代码如下所示:importjava.awt.Window;importjava.awt.event.WindowAdapter;importjava.awt.event.WindowEvent;//继承WindowAdapter类publicclassMyWindowListenerextendsWindowAdapter{ //重写windowClosing()方法 publicvoidwindowClosing(WindowEvente){ Windowwin=e.getWindow(); win.setVisible(false); win.dispose(); }}(2)运行WindowEventTest.java,即可在指定位置弹出一个指定大小的窗口。单击窗口右上角的“关闭”按钮,即可关闭窗口。三、鼠标事件(MouseEvent)在图形用户界面中,用户会经常使用鼠标在组件上进行各种操作,例如鼠标按下、释放、单击、拖动等,这些操作被定义为鼠标事件。几乎所有的组件都可以产生鼠标事件,JDK中使用MouseEvent类表示鼠标事件,该事件会导致MouseEvent类自动创建一个事件对象。处理鼠标事件时,首先需要实现MouseListener接口(或MouseMotionListener接口)或继承适配器MouseAdapter类(或MouseMotionAdapter类)定义监听器,然后调用addMouseListener()方法(或addMouseMotionListener()方法)将监听器绑定到事件源对象。MouseListener接口中有5个不同的方法,如表6-4所示,用于处理5种不同的鼠标事件。表6-4MouseListener接口的方法方法说明publicvoidmousePressed(MouseEvente)在组件上按下鼠标键时调用publicvoidmouseReleased(MouseEvente)在组件上释放鼠标键时调用publicvoidmouseEntered(MouseEvente)鼠标进入组件时调用publicvoidmouseExited(MouseEvente)鼠标离开组件时调用publicvoidmouseClicked(MouseEvente)在组件上单击鼠标时调用鼠标的操作分为左键单击、双击、右键点击和中键(滚轮)点击。MouseEvent类中定义了很多常量和方法来标识鼠标动作,如表6-5所示。表6-5MouseEvent类的常用方法及常量方法说明publicintgetButton()以数字形式返回按下的鼠标键publicintgetClickCount()获取鼠标被单击的次数publicstaticStringgetMouseModifiersText(intmodifiers)以字符串形式返回鼠标按下的键信息publicintgetX()获取鼠标指针在事件源坐标系中的x坐标publicintgetY()获取鼠标指针在事件源坐标系中的y坐标publicstaticfinalintBUTTON1表示鼠标左键的常量publicstaticfinalintBUTTON2表示鼠标滚轴的常量publicstaticfinalintBUTTON3表示鼠标右键的常量MouseMotionListener接口中有2个不同的方法,如表6-6所示,分别用于处理拖动鼠标和移动鼠标事件。表6-6MouseMotionListener接口中的方法方法说明publicvoidmouseDragged(MouseEvente)拖动鼠标时(不必在事件源上)调用publicvoidmouseMoved(MouseEvente)在事件源上移动鼠标时调用案例——拖动按钮本案例定义一个继承JFrame并实现MouseMotionListener接口的类作为窗体监听器,通过重写mouseDragged()方法,实现鼠标拖动按钮的操作。(1)在项目EventDemo中新建一个类MyMouseListener,该类继承JFrame创建窗体,并实现MouseMotionListener接口。(2)在类体中定义类MyMouseListener的构造方法,构造一个窗体和按钮,并为按钮注册鼠标事件监听器。然后重写mouseDragged()方法和mouseMoved()方法。具体代码如下:importjava.awt.Component;importjava.awt.event.MouseEvent;importjava.awt.event.MouseMotionListener;importjavax.swing.JButton;importjavax.swing.JFrame;publicclassMyMouseListenerextendsJFrameimplementsMouseMotionListener{privatestaticfinallongserialVersionUID=1L;publicJButtonbutton=newJButton("拖动我"); //实例化按钮intx,y,a,b; //坐标变量publicMyMouseListener(){ super.setTitle("测试按钮"); //设置窗口标题 super.setLayout(null); //取消使用布局管理器 button.setSize(80,40); //设置按钮尺寸 super.add(button); //在窗口中添加按钮 button.addMouseMotionListener(this); //注册监听器 super.setBounds(300,300,280,160); //设置窗口位置和大小 super.setVisible(true); //设置窗口可见}publicvoidmouseDragged(MouseEvente){//重写拖动鼠标触发的鼠标事件 Componentcom=null; //定义一个空组件 //判断事件源是否为组件实例,如果是,则赋值给com if(e.getSource()instanceofComponent){ com=(Component)e.getSource(); //获取组件的坐标 a=com.getBounds().x; b=com.getBounds().y; //获取鼠标在事件源中的位置坐标 x=e.getX(); y=e.getY(); //将按钮坐标设置为鼠标指针所在位置 a=a+x; b=b+y; com.setLocation(a,b); }}publicvoidmouseMoved(MouseEvente){ } }上面的代码重写mouseDragged()方法时,使用坐标变换实现组件的拖动。先获得组件的左上角在容器坐标系统中的坐标(a,b),再获得鼠标指针在组件坐标系中的坐标(x,y),然后计算得到鼠标指针在容器坐标系统中的位置,并设置组件的位置。(3)在项目EventDemo中新建一个类MouseEventTest,在该类中定义主方法,实例化MyMouseListener类对象。具体代码如下所示:publicclassMouseEventTest{ publicstaticvoidmain(String[]args){ newMyMouseListener(); }}(4)运行MouseEventTest.java,弹出如图6-3所示的窗口。在按钮上按下鼠标左键拖动,即可将按钮拖动到鼠标指针所在位置,如图6-4所示。图6-3运行窗口图6-4拖动按钮四、键盘事件(KeyEvent)键盘操作也是很常用的用户交互方式,例如按下、释放或敲击键盘按键等,这些操作被定义为键盘事件。JDK使用KeyEvent类表示键盘事件,处理KeyEvent事件的监听器对象需要实现KeyListener接口或者继承KeyAdapter类。KeyListener接口中有3个方法,如表6-7所示。表6-7KeyListener接口中的方法方法说明publicvoidkeyPressed(KeyEvente)组件处于激活状态时,按下键盘上某个键时调用publicvoidKeyReleased(KeyEvente)释放键盘上按下的键时调用publicvoidkeyTyped(KeyEvente)键被按下又释放时调用键盘上的按键众多,KeyEvent类提供了一些方法用于标识触发键盘事件的键,如表6-8所示。表6-8KeyEvent类的常用方法方法说明publicchargetKeyChar()返回触发keyTyped事件的字符publicintgetKeyCode()返回输入字符的键码值publicstaticStringgetKeyText(intkeycode)返回描述指定键码值的信息键盘按键的键码值可参见API文档中KeyEvent类的说明。案例——字符转码本案例通过监听键盘事件,在文本区中输出在文本框中输入的字符的键码。(1)在项目EventDemo中新建一个名为MyKeyListener的类。该类继承JFrame并实现KeyListener接口。(2)引入包,在类体中定义一个标签,一个文本框,一个文本区域以及一个滚动面板。接下来编写构造方法创建窗体,然后重写KeyListener接口中的keyPressed()方法和keyReleased()方法。具体代码如下:importjava.awt.FlowLayout;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassMyKeyListenerextendsJFrameimplementsKeyListener{privatestaticfinallongserialVersionUID=1L;//创建标签和文本框JLabellabel_1=newJLabel("字符:");JTextFieldtext=newJTextField(6);//创建带滚动条的文本区JTextAreacode=newJTextArea(6,20);JScrollPanesp=newJScrollPane(code);//构造方法publicMyKeyListener(){ super.setTitle("测试键盘事件"); //设置窗口标题 super.setBounds(300,300,280,200); //设置窗口位置和大小 super.setLayout(newFlowLayout()); //设置布局管理器 //在窗体中添加组件 super.add(label_1); super.add(text); text.addKeyListener(this); //注册监听器 //设置总是显示滚动条 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); super.add(sp); code.setEditable(false); //设置文本区不可编辑 //设置窗口可见和关闭方式 super.setVisible(true); super.setDefaultCloseOperation(EXIT_ON_CLOSE);}//重写keyPressed()方法,在文本区输出按下的键及对应的键码publicvoidkeyPressed(KeyEvente){ code.append("键"+e.getKeyChar()+"的键码是:"+e.getKeyCode()+"\n");}//重写keyReleased()方法,释放按键时清空文本框publicvoidkeyReleased(KeyEvente){ text.setText(null);}publicvoidkeyTyped(KeyEvente){}}(3)在项目中新建一个类KeyEventTest,在该类中定义主方法,实例化MyKeyListener类对象。具体代码如下所示:publicclassKeyEventTest{ publicstaticvoidmain(String[]args){ newMyKeyListener(); }}(4)运行KeyEventTest.java,弹出窗口。按下键盘上的按键,即可在文本区中看到输出的键码信息,如图6-5所示。图6-5运行结果五、动作事件(ActionEvent)动作事件不代表某个具体的动作,只是表示一个动作发生了,而不需要关心使用哪种方式触发事件。例如,触发一个按钮的单击事件时,可以使用鼠标单击,也可以按键盘上的Enter键,不管使用哪种方式,只要对按钮进行了操作,就会触发动作事件。JDK使用ActionEvent类表示动作事件,文本框、按钮、菜单项、密码框和单选按钮都成为ActionEvent事件的事件源,触发ActionEvent事件。处理动作事件时,首先需要实现ActionListener接口定义监听器,然后调用addActionListener()方法将实现ActionListener接口的类的实例注册为事件源的监听器。ActionListener接口中只定义了一个方法publicvoidactionPerformed(ActionEvente),在发生操作时调用。ActionEvent类常用的方法如表6-9所示。表6-9ActionEvent类的常用方法方法说明publicObjectgetSource()返回产生这个事件的事件源对象publicStringgetActionCommand()返回与此动作相关的命令字符串案例——大小写转换本案例通过监听文本框和按钮的动作事件,将文本框中输入的字符全部转换为大写字母后,在文本区中输出。(1)在项目EventDemo中新建一个名为MyActionListener的类。该类继承JFrame并实现ActionListener接口。(2)引入包,在类体中定义一个文本框,一个按钮,一个文本区以及一个滚动面板。接下来编写构造方法创建窗体,然后重写ActionListener接口中的actionPerformed()方法。具体代码如下:importjava.awt.FlowLayout;importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassMyActionListenerextendsJFrameimplementsActionListener{privatestaticfinallongserialVersionUID=1L;//创建文本框和按钮JTextFieldtext=newJTextField(20);JButtonbutton=newJButton("转换");//创建带滚动条的文本区JTextAreashow=newJTextArea(6,25);JScrollPanesp=newJScrollPane(show);publicMyActionListener(){ super.setTitle("测试动作事件"); //设置窗口标题 super.setBounds(300,300,320,200); //设置窗口位置和大小 super.setLayout(newFlowLayout()); //设置布局管理器 //在窗体中添加组件 super.add(text); text.addActionListener(this); //注册监听器 button.addActionListener(this); //注册监听器 super.add(button); //设置总是显示滚动条 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); super.add(sp); show.setEditable(false); //设置文本区不可编辑 //设置窗口可见和关闭方式 super.setVisible(true); super.setDefaultCloseOperation(EXIT_ON_CLOSE);}publicvoidactionPerformed(ActionEvente){ Stringstr_in=text.getText(); //获取文本框中的字符串 Stringstr_out=str_in.toUpperCase(); //将字符串转换为大写 show.append(str_in+"大写:"+str_out+"\n"); //将转换结果追加到文本区}}(3)在项目中新建一个类ActionEventTest,在该类中定义主方法,实例化MyActionListener类对象。具体代码如下所示:publicclassActionEventTest{ publicstaticvoidmain(String[]args){ newMyActionListener(); }}(4)运行ActionEventTest.java,弹出如图6-6(a)所示的窗口。在文本框中输入字符,然后按Enter键,或单击“转换”按钮,即可在文本区中看到转换为大写的字符串,如图6-6(b)所示。(a)(b)图6-6运行结果六、选项事件(ItemEvent)在应用程序中,勾选复选框或取消选中复选框,就会触发选项事件。JDK使用ItemEvent类表示选项事件。除了复选框,下拉列表框、菜单项等组件都可以触发ItemEvent事件。处理选项事件时,首先需要实现ItemListener接口定义监听器,然后调用addItemListener()方法将实现ItemListener接口的类的实例注册为事件源的监听器。ItemListener接口中只有一个方法publicvoiditemStateChanged(ItemEvente),在选择项发生改变时调用。ItemEvent类常用的方法如表6-10所示。表6-10ItemEvent类的常用方法方法说明publicObjectgetSource()返回产生这个事件的事件源对象publicObjectgetItem()返回受事件影响的对象publicintgetStateChange()返回状态更改的类型,值为常量值。SELECTED值为1,表示选择项改变;DESELECTED值为2,表示选择项未改变publicStringparamString()返回标识此项事件的参数字符串,常用于程序调试案例——录入用户信息本案例通过监听下拉列表框的ItemEvent事件和按钮的ActionEvent事件,将用户界面输入、选择的信息在文本区中输出。(1)在项目EventDemo中新建一个名为UserInfo的类。该类继承JFrame并使用网格包布局管理器(GridBagLayout)排布组件,制作用户界面。具体代码如下:importjava.awt.GridBagConstraints;importjava.awt.GridBagLayout;importjava.awt.Insets;importjavax.swing.ButtonGroup;importjavax.swing.JButton;importjavax.swing.JComboBox;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JRadioButton;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassUserInfoextendsJFrame{ //创建组件 JLabellabel=newJLabel("姓名:"); JTextFieldname=newJTextField(10); JRadioButtonrb1=newJRadioButton("男"); JRadioButtonrb2=newJRadioButton("女"); ButtonGroupgender=newButtonGroup();//创建一个按钮组gender,用于管理单选按钮 //创建下拉列表框 JLabellabel_edu=newJLabel("学历:"); String[]edu_list={"本科","大专","硕士","博士","其他"}; JComboBox<String>edu=newJComboBox<String>(edu_list); //创建按钮和带滚动条的文本框 JButtonbutton=newJButton("确定"); JTextAreashow=newJTextArea(5,20); JScrollPanesp=newJScrollPane(show); //构造方法 publicUserInfo(){ super.setTitle("测试选项事件"); //设置窗口标题 super.setBounds(300,300,300,300); //设置窗口位置和大小 init(); //调用成员方法初始化界面 } voidinit(){ //定义监听器类,实现ItemListener接口,用于监听下拉列表框的选项事件 MyItemListenerselect=newMyItemListener(); //定义监听器类,实现ActionListener接口,用于监听按钮的动作事件 PrintListenersubmit=newPrintListener(); //调用监听器类中的成员方法,传递组件参数 select.setJComboBox(edu); select.setButton(submit); submit.setJTextField(name); submit.setJTextArea(show); submit.setRadioButtons(rb1,rb2); //创建GridBagLayout布局管理器 GridBagLayoutlayout=newGridBagLayout(); super.setLayout(layout); //在窗体中添加组件 super.add(label); super.add(name); gender.add(rb1); gender.add(rb2); super.add(rb1); super.add(rb2); super.add(label_edu); super.add(edu); //设置总是显示滚动条 sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); super.add(sp); edu.addItemListener(select); //注册监听器 super.add(button); super.add(label_edu); super.add(edu); super.add(button); button.addActionListener(submit); //注册监听器 //使用GridBagLayout布局管理器排列组件 GridBagConstraintsconstraints=newGridBagConstraints(); constraints.gridx=0;//起始点为第1列 constraints.gridy=0;//起始点为第1行 layout.setConstraints(label,constraints); constraints.gridx=1;//起始点为第2列 constraints.gridy=0;//起始点为第1行 layout.setConstraints(name,constraints); constraints.gridx=1; constraints.gridy=1; layout.setConstraints(rb1,constraints); constraints.gridx=2; constraints.gridy=1; layout.setConstraints(rb2,constraints); constraints.gridx=0; constraints.gridy=2; layout.setConstraints(label_edu,constraints); constraints.gridx=1; constraints.gridy=2; layout.setConstraints(edu,constraints); constraints.gridx=1;//起始点为第2列 constraints.gridy=3;//起始点为第4行 constraints.insets=newInsets(10,0,0,0);//设置组件上方留白 layout.setConstraints(button,constraints); constraints.gridx=0;//起始点为第1列 constraints.gridy=4;//起始点为第5行 constraints.gridwidth=3; //占据3列 constraints.insets=newInsets(10,0,0,0);//设置组件上方留白 layout.setConstraints(sp,constraints); //设置窗口可见和关闭方式 super.setVisible(true); super.setDefaultCloseOperation(EXIT_ON_CLOSE); }}(2)在项目中添加一个名为MyItemListener.java的类,该类作为下拉列表框组件的监听器类,实现ItemListener接口。具体代码如下:importjava.awt.event.ItemEvent;importjava.awt.event.ItemListener;importjavax.swing.JComboBox;publicclassMyItemListenerimplementsItemListener{ //定义变量,用于传递组件参数 JComboBox<String>choice; PrintListeneroutput; publicvoidsetJComboBox(JComboBox<String>box){ choice=box; } publicvoidsetButton(PrintListenersubmit){ output=submit; } //实现itemStateChanged()方法 publicvoiditemStateChanged(ItemEvente){ Stringedu=choice.getSelectedItem().toString(); output.setEdu(edu); }}(3)在项目中添加一个名为PrintListener.java的类,该类作为按钮组件的监听器类,实现ActionListener接口。具体代码如下:importjava.awt.event.ActionEvent;importjava.awt.event.ActionListener;importjavax.swing.JRadioButton;importjavax.swing.JTextArea;importjavax.swing.JTextField;publicclassPrintListenerimplementsActionListener{ JTextFieldname; JTextAreaoutput; JRadioButtonrb1,rb2; Stringedu; publicvoidsetJTextField(JTextFieldtxt){ name=txt; } publicvoidsetRadioButtons(JRadioButtonrb_m,JRadioButtonrb_w){ rb1=rb_m; rb2=rb_w; } publicvoidsetJTextArea(JTextAreaarea){ output=area; } publicvoidsetEdu(Strings){ edu=s; } //实现actionPerformed()方法,获取界面信息并输出 publicvoidactionPerformed(ActionEvente){ output.append("用户名:"+name.getText()+"\n"); //判断单选按钮的选中状态并输出对应的按钮标签 if(rb1.isSelected()) output.append("性别:"+rb1.getText()+"\n"); elseif(rb2.isSelected()) output.append("性别:"+rb2.getText()+"\n"); output.append("学历:"+edu+"\n"); }}(4)在项目中添加一个名为ItemEventTest的测试类,编写主方法实例化UserInfo类对象,测试界面效果。具体代码如下:publicclassItemEventTest{ publicstaticvoidmain(String[]args){ newUserInfo(); }}(5)运行ItemEventTest.java,即可弹出图形用户界面。在文本框中输入字符串,选中某个单选按钮,在下拉列表框中选择某个列表项,然后单击“确定”按钮,即可在界面下方的文本区中显示用户输入、选择的信息,如图6-7所示。图6-7运行结果七、焦点事件(FocusEvent)FocusEvent类表示焦点事件,每个GUI组件都能够作为焦点事件的事件源,也就是每个组件在获得焦点或者失去焦点时都会产生焦点事件。例如将光标焦点移出一个文本框,或者将焦点返回给文本框,等等。处理焦点事件时,首先需要实现FocusListener接口定义监听器,然后调用addFocusListener()方法将实现FocusListener接口的类的实例注册为事件源的监听器。FocusListener接口中有2个方法,用于处理焦点改变的事件,如表6-11所示。表6-11FocusListener接口中的方法方法说明publicvoidfocusGained(FocusEvente)组件焦点从无到有时调用publicvoidfocusLost(FocusEvente)组件焦点从有到无时调用通过单击组件可以使得该组件有输入焦点,同时也使得其他组件变成无输入焦点。一个组件也可调用publicbooleanrequestFocusInWindow()方法获得输入焦点。焦点事件有持久性和暂时性两个级别。当焦点直接从一个组件移动到另一个组件时,会发生持久性焦点变更事件;如果失去焦点是暂时的,例如窗口拖放时失去焦点,拖放结束后就会自动恢复焦点,这就是暂时性焦点变更事件。利用FocusEvent类中的publicBooleanisTemporary()方法可以返回焦点变更的级别,返回true表示暂时性的,返回false表示持久性的。案例——输入序列号本案例通过监听文本框的焦点事件,模拟某些软件输入序列号。序列号要在3个文本框中依次输入,每个文本框中只能输入4个字符,多出4个字符时光标自动定位到下一个文本框中。(1)在项目EventDemo中新建一个名为SerialNumber的类。该类继承JFrame并使用流式布局管理器(FlowLayout)排布组件,制作用户界面。具体代码如下:importjava.awt.FlowLayout;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JLabel;importjavax.swing.JTextField;publicclassSerialNumberextendsJFrame{ privatestaticfinallongserialVersionUID=1L; //声明窗口组件:3个文本框,2个标签和1个按钮 JTextFieldtext[]=newJTextField[3]; JLabellabel[]=newJLabel[2]; JButtonbutton; FListenerfocus; //声明监听器 //构造方法初始化用户界面 publicSerialNumber(){ setTitle("测试焦点事件"); //设置窗口标题 setBounds(300,300,300,120); //设置窗口位置和大小 setLayout(newFlowLayout()); //设置窗口布局 focus=newFListener(); //创建监听器对象 //创建文本框和标签组件,并为每个文本框注册监听器 for(inti=0;i<3;i++){ text[i]=newJTextField(6); text[i].addFocusListener(focus); text[i].addKeyListener(focus); add(text[i]); if(i<2){ label[i]=newJLabel("-"); add(label[i]); } } button=newJButton("确定"); add(button); //设置窗口可见及关闭方式 setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); }}(2)在项目中添加一个名为FListener的类,实现FocusListener接口和KeyListener接口。在类体中重写focusGained()方法和keyPressed()方法,分别用于处理文本框获得焦点的事件和在文本框中键入字符的事件。具体代码如下:importjava.awt.event.FocusEvent;importjava.awt.event.FocusListener;importjava.awt.event.KeyEvent;importjava.awt.event.KeyListener;importjavax.swing.JTextField;publicclassFListenerimplementsFocusListener,KeyListener{ publicvoidfocusGained(FocusEvente){ JTextFieldtxt=(JTextField)e.getSource(); //文本框获取事件源 txt.setText(null); //文本框获取焦点,则清空文本框 } publicvoidfocusLost(FocusEvente){ } publicvoidkeyPressed(KeyEvente){ JTextFieldtxt=(JTextField)e.getSource(); //文本框获取事件源 intlen=txt.getText().length(); if(len>=3) //达到指定长度,就将焦点转移到下一个组件 txt.transferFocus(); } publicvoidkeyReleased(KeyEvente){} publicvoidkeyTyped(KeyEvente){} }(3)在项目中添加一个名为FocusEventTest的测试类,编写主方法实例化SerialNumber类对象,测试界面效果。具体代码如下:publicclassItemEventTest{ publicstaticvoidmain(String[]args){ newSerialNumber(); }}(4)运行SerialNumber.java,即可弹出图形用户界面,焦点默认位于第一个文本框中,如图6-8(a)所示。在第一个文本框中输入字符达到4个时,光标自动转移到第二个文本框,同样的方法进入第三个文本框,如图6-8(b)所示。(a)(b)图6-8运行结果八、文档事件(DocumentEvent)DocumentEvent接口用于处理文档事件。能够产生文档事件的事件源有文本框(JTextField)、密码框(JPasswordField)、文本区(JTextArea),但这些组件不能直接触发DocumentEvent事件。用户进行文本编辑操作时,文本内容发生变化,使得这些组件所维护的文档模型中的数据发生变化,从而触发DocumentEvent事件。也就是说,是文本编辑组件所维护的文档触发DocumentEvent事件,组件对象调用getDocument()方法可以获取文本区所维护的文档。处理文档事件时,首先需要实现DocumentListener接口定义监听器,然后调用addDocumentListener()方法将实现DocumentListener接口的类的实例注册为事件源的监听器。DocumentListener接口包含在javax.swing.event包中,定义了3个方法,用于处理文档内容改变的事件,如表6-12所示。表6-12DocumentListener接口中的方法方法说明publicvoidchangedUpdate(DocumentEvente)文本编辑区的内容改变时调用publicvoidremoveUpdate(DocumentEvente)删除文本编辑区的内容时调用publicvoidinsertUpdate(DocumentEvente)在文本编辑区插入内容时调用案例——实时排序本案例通过监听文本区所维护的文档模型中的数据的焦点事件,对输入的字符串进行实时排序。(1)在项目EventDemo中新建一个名为SortString的类。该类继承JFrame并使用流式布局管理器(FlowLayout)排布组件,制作用户界面。具体代码如下:importjava.awt.FlowLayout;importjavax.swing.JFrame;importjavax.swing.JScrollPane;importjavax.swing.JTextArea;publicclassSortStringextendsJFrame{ privatestaticfinallongserialVersionUID=1L;JTextAreainput,output; DocListenertextChanged; publicSortString(){ init(); //调用成员方法初始化界面 setTitle("测试文档事件"); //设置窗口标题 setBounds(300,300,500,240); //设置窗口位置和大小 //设置窗口可见及关闭方式 setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); } publicvoidinit(){ setLayout(newFlowLayout()); //设置布局管理器 input=newJTextArea(10,20); output=newJTextArea(10,20); output.setLineWrap(true); //文本自动换行 output.setWrapStyleWord(true); //以单词为界自动换行 output.setEditable(false); //文本区不可编辑 //添加滚动条 add(newJScrollPane(input)); add(newJScrollPane(output)); textChanged=newDocListener(); //创建监听器 //调用方法传递组件参数 textChanged.setInput(input); textChanged.setOutput(output); //为文本区input的维护文档注册监听器 (input.getDocument()).addDocumentListener(textChanged); }}(2)在项目中添加一个名为DocListener的类,实现DocumentListener接口。在类体中编写成员方法传递组件参数,并实现DocumentListener接口的所有方法。具体代码如下:importjava.util.Arrays;importjavax.swing.JTextArea;importjavax.swing.event.DocumentEvent;importjavax.swing.event.DocumentListener;publicclassDocListenerimplementsDocumentListener{ JTextAreain,out; publicvoidsetInput(JTextAreainput){ in=input; } publicvoidsetOutput(JTextAreaoutput){ out=output; } //重写DocumentListener接口的所有方法 publicvoidchangedUpdate(DocumentEvente){ Stringstr=in.getText(); //获取第一个文本区的内容 //以逗号为分隔符,拆分文本区的字符串并保存到字符串数组中 Stringwords[]=str.split(","); Arrays.sort(words); //对数组元素按字典序排序 out.setText(null); //清空第二个文本区的内容 //在文本区中输出排序后的数组元素 for(inti=0;i<words.length;i++) out.append(words[i]+"\n"); } publicvoidremoveUpdate(DocumentEvente){ changedUpdate(e); //调用方法 } publicvoidinsertUpdate(DocumentEvente){ changedUpdate(e); //调用方法 }}(3)在项目中添加一个名为DocumentEventTest的测试类,编写主方法实例化SortString类对象,测试界面效果。具体代码如下:publicclassItemEventTest{ publicstaticvoidmain(String[]args){ newSortString(); }}(4)运行DocumentEventTest.java,即可弹出图形用户界面。在左侧文本区中字符串,右侧文本区中即可实时显示输入的字符串(去除分隔符“,”),如图6-9所示。继续输入或修改输入的字符串,右侧的文本区中将实时拆分字符串,并将拆分后的字符子串按字典序进行升序排列,如图6-10所示。图6-9运行结果1图6-10运行结果2项目总结项目实战在上一章的项目实战中已实现了进销存管理系统的图形用户界面,本节将为主操作界面、商品入库界面、商品出库界面以及商品查询界面的组件注册监听器、编写事件处理程序,监听并处理组件的各种事件。修改商品信息界面的组件操作读者可参照本节的实现代码自行完成。(1)复制并粘贴“进销存管理系统V5.0”,在CopyProject对话框中修改项目名称为“进销存管理系统V6.0”,然后单击Copy按钮关闭对话框。(2)打开MainFrame.java,为各个功能按钮注册监听器,处理单击该按钮进入相应界面的操作。相关代码如下:……//为“商品入库”按钮注册监听器,使用匿名内部类处理按钮单击事件 inBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ InFrameaddGoods=newInFrame(); addGoods.setVisible(true); //显示商品入库界面 MainFrame.this.dispose(); //退出主界面,并释放相应的屏幕资源 }});……//为“商品出库”按钮注册监听器,使用匿名内部类处理按钮单击事件 outBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ OutFrameoutGoods=newOutFrame(); outGoods.setVisible(true); //显示商品出库界面 MainFrame.this.dispose(); //退出主界面,并释放相应的屏幕资源 }});……//为“修改商品”按钮注册监听器,使用匿名内部类处理按钮单击事件 modifyBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ //读者自行完成 }});……//为“查询商品”按钮注册监听器,使用匿名内部类处理按钮单击事件 searchBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ SearchFramesearchGoods=newSearchFrame(); searchGoods.setVisible(true); //显示查询商品界面 MainFrame.this.dispose(); //退出主界面,并释放相应的屏幕资源 }});……//为“退出”按钮注册监听器,使用匿名内部类处理按钮单击事件 exitBtn.addActionListener(newActionListener(){ publicvoidactionPerformed(ActionEvente){ MainFrame.this.dispose(); //退出主界面,并释放相应的屏幕资源 }});……为便于代码维护,将各种操作的功能代码放在一个单独的文件中。(3)在PackageExplorer窗格中右击项目名称,从弹出的快捷菜单中选择New→Package命令,新建一个名为controller的包。然后在该包中添加一个名为Controllers的类,用于管理商品入库、出库、修改和查询的操作代码。具体代码如下所示:packagecontroller;importjavax.swing.JOptionPane;importmodel.Goods;publicclassControllers{ staticfinalintMAXNUM=100;//最大容量 staticintproductNum=0; //商品种类 staticGoods[]products=newGoods[MAXNUM]; //商品名称列表 //商品入库 publicbooleanaddGoods(Goodsgoods){ try{ products[productNum++]=goods; //商品信息入库 returntrue; }catch(ArrayIndexOutOfBoundsExceptione){ JOptionPane.showMessageDialog(null,"超出库存容量上限,不能入库!"); productNum--; } returnfalse; } //商品出库 publicbooleanoutGoods(Goodsgoods){ //查找要修改信息的商品 inti=findProduct(goods.getName()); //商品索引号 if(i==productNum){ //没有找到指定的商品 JOptionPane.showMessageDialog(null,"指定的商品不存在!"); returnfalse; } else{ intpro_num=goods.getNum(); //如果出库量大于等于库存,则输出提示,并删除对应的记录 if(pro_num>=products[i].getNum()){ JOpt
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 骨科围手术期伤口护理
- 高压氧治疗与心理健康:护理干预的重要性
- 肿瘤患者的肿瘤标志物监测
- 胸外科患者术后伤口感染的防控
- 骨质疏松症患者的药物治疗监测与护理
- 饮食与护理:过敏与饮食管理
- 麦粒肿患者的心理调适
- 2026年航空航天工程人才紧缺岗位
- 2026年运输企业安全管理法律法规汇编与解读
- 2026年铝合金牌号与状态表示方法
- 2026年中国化工经济技术发展中心招聘备考题库参考答案详解
- 2026年甘肃省兰州市辅警招聘试卷带答案
- 2026年高校教师资格证之高等教育学考试题库附参考答案(能力提升)
- 启德留学合同范本
- 自考《唐宋诗词鉴赏》考前密押120题及答案含解析
- 医疗器械质量记录管理制度
- 国企智联招聘题库及答案
- T-SZRCA 011-2025 人形机器人专用线缆技术规范
- 《星级饭店访查规范》
- 白鹤滩工程施工方案设计
- 起重吊装作业安全管理培训
评论
0/150
提交评论