资源描述
第八章图形用户界面,本章任务:了解什么是容器;了解什么是组件;了解如何创建与使用组件;如何使用布局管理器对组件进行管理;如何使用Java的事件处理机制控制组件。,本章主要内容,1.Swing与AWT组件2.Swing类的层次结构3.容器4.组件5.组件布局管理6.事件处理方机制,8.1Swing与AWT组件,Java语言提供的GUI编程类库只有抽象窗口工具箱(AWT:AbstractWindowToolkit)。使用AWT库在处理用户界面组件时,把组件的创建和行为都委托给本地计算机的GUI工具处理,使用AWT库在处理复杂图形时,在不同平台会有差别。Swing不需要使用本地计算机提供的GUI功能,Swing可以编写Java程序实现图形用户界面,可以接收来自键盘、鼠标和其他输入设备的数据输入。Swing的所有成员都是javax.swing包中的一部分。,8.2Swing类的层次结构,本节的内容主要介绍Swing类的层次关系。如图,显示了组件类的继承关系。,说明:,如图所示,Swing组件都是AWT的Container类的直接子类和间接子类,Container类是用来管理相关组件的类。Swing组件包含了两种类型的组件类:(1)顶层容器类;(2)轻量级组件类Jcomponent,它是一个抽象类,用于定义所有子类组件的一般方法,所有的Swing组件都是Jcomponent抽象类的子类。,8.3容器,8.3.1窗口容器JFrame是一个用来创建窗口的类,使用JFrame类可以创建出在用户桌面上显示的窗口,同时它也是一个顶层的容器框架,在其中可以添加各种组件。例8.1本例介绍的应用程序创建了一个可以移动、改变大小、最大化、可变成图标且可以关闭的窗口,运行程序可以弹出窗口对象,结果如图所示。,importjavax.swing.*;importjava.awt.*;publicclassJF0extendsJFramepublicJF0(Strings)super(s);/调用父类JFrame的构造方法,给窗口命名setBounds(200,200,500,400);/设置窗口位置、窗口大小setVisible(true);/设置窗口是否为可见try/设置外观,程序代码:,UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName();catch(Exceptione)setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);publicstaticvoidmain(Stringargs)JF0d=newJF0(主窗口);,运行结果显示:,创建的窗口对象,说明:,本程序中JF0类是继承自类JFrame的子类,所以在为其设计的构造JF0(Strings)方法中直接使用了类JFrame的一些主要方法。调用父类的构造方法super(s)为窗口指定名称,s可以在创建窗口对象时具体指定,例如“主窗口”。通过类JFrame的setBounds(200,200,500,400)方法设置窗口位置、窗口的大小。通过setVisible(true)方法用来指定窗口可见(参数为false时为不可见)。,通过UIManager.setLookAndFeel方法指定窗口的外观,怕有的系统不支持的问题设计了try语句解决出错问题。通过setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)设定窗口对象关闭动作。在主方法main中通过创建JF0类的对象d创建出窗口,同时通过构造方法指定其窗口名称为“主窗口”。JF0还通过构造方法提供了一个指定窗口名称的接口,可以在创建其对象时根据需要指定窗口名称。,说明:,8.3.2对话框容器,对话框(Dialog类)是GUI中很常见的窗口对象,有着广泛的应用。对话框和普通窗口最大的不同就是对话框是依附在某个窗口上的,一旦它所依附的窗口关闭了,对话框也要随着关闭。在对话框窗口中可以添加其他组件,所以它也是一个容器。,例8.2创建对话框的例子,程序运行结果如图所示。,importjavax.swing.*;publicclassJDextendsJDialogpublicJD(JFramef,Strings)super(f,s);/调用父类JDialog的构造方法,给对话框窗口命名setBounds(300,300,200,200);/设置对话框窗口大小位置setModal(false);/设置对话框窗口模式setVisible(true);/设置对话框窗口是否为可见,setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);publicstaticvoidmain(Stringargs)JF0f=newJF0(主窗口);/创建主窗口对象JDd=newJD(f,这是一个对话框窗口);/创建对话框对象,创建的对话框对象,运行结果显示:,8.3.3面板容器,面板(JPanel类)是一个无边框的容器,可以包容其他组件或另一个面板对象。使用面板的目的是为了分层次、分区域管理各种组件,使组件放置在精确的位置。面板与其他顶层容器不同,它是一个中间容器,它既是容器又是组件,它可以容纳其他组件,也可以添加到其他容器之中。一个窗口中可以添加多个面板对象。,例8.3创建含有面板窗口的例子,程序运行结果如图所示。,importjavax.swing.*;importjava.awt.*;importjava.awt.Color;publicclassJP1extendsJFramepublicJP1(JFramef,intx,inty,intw,inth)Containerc=getContentPane();/调用getContentPane()方法创建Container内容面板对象cc.setLayout(null);/设置不采用任何布局方式c.setBackground(Color.yellow);/设置面板的背景色为黄色f.add(c);/将内容面板c加入到窗口对象f中,JPanelp=newJPanel();/创建面板对象pp.setBounds(x,y,w,h);/设置面板p的位置、大小p.setBackground(Color.blue);/设置面板的背景色为蓝色c.add(p);/将面板p加入到窗口的内容面板c中publicstaticvoidmain(Stringargs)JP1f1=newJP1(newJF0(添加面板的窗口),100,50,200,200);,运行结果显示:,含有面板对象的窗口,说明:,面板对象p是通过JPanel类创建的,当容器不使用布局管理器时(setLayout(null)),它可以通过setBounds(x,y,w,h)方法设置其位置与大小,可以设置背景颜色、指定布局管理器。在main方法中创建了JP1类的对象d1,它是一个具有内容面板对象c、普通面板p的窗口对象。JP1还通过构造方法提供了一个指定普通面板p位置、大小的接口,可以在创建其对象时根据需要来确定。,8.4组件,组件(JComponent)是构成GUI的基本要素,通过对不同事件的响应来完成和用户的交互或组件之间的交互。组件一般作为一个对象放置在容器(Container)内,容器是能容纳和排列组件的对象,如Applet界面、面板、窗口等。通过容器的add方法可以把组件标签、按钮、文本框、菜单等加入到容器中。本节的内容主要介绍如何在容器中添加Swing组件。注意本节中所有组件使用的窗口对象都是通过例8.1中设计的自定义类LF0创建的。,8.4.1标签组件,1创建标签标签(JLabel)的功能是显示单行的字符串,可在屏幕上显示一些提示性、说明性的文字。,例8.4本例应用程序用来创建添加有不同标签的窗口,程序运行结果如图所示。,importjavax.swing.*;importjava.awt.*;publicclassJL1extendsJFrameprivateJLabellabel;publicJL1(JFramef,JPanelp)f.add(p);/将面板p加入到窗口f中label=newJLabel(显示文字的标签);/使用文本创建一个标签对象label.setFont(newFont(Serif,Font.PLAIN,20);/设置标签字体label.setToolTipText(这是标签对象);/设置标签的工具提示p.add(label);/将标签对象添加到面板对象p上publicstaticvoidmain(Stringargs)JL1f1=newJL1(newJF0(添加标签的窗口),newJPanel();,使用标签对象的窗口说明:本程序通过设计JL1类创建了一个包含JLabel标签对象label。通过其构造方法的参数传递了两个对象变量,一个是JF0类的窗口对象f,一个是普通面板p。,运行结果显示:,2.标签的构造方法,(1)JLabel()方法用来创建一个没有显示内容的标签对象。(2)JLabel(Stringtext)方法用来创建一个显示文字的标签对象,默认为居中排列。(3)JLabel(Stringtext,intalignment)方法除了用来创建一个显示文字为text的标签对象外,并指定其排列方式。排列方式有3种,分别用3个常量LEFT、CENTER和RIGHT表示左、居中和右对齐。(4)JLabel(Iconimage)方法用来创建一个显示为图标的标签对象,默认为居中排列。(5)JLabel(Iconimage,intalignment)方法用来创建一个显示为图标的标签对象,并指定其排列方式。,3.标签的常用方法,(1)voidsetText(Stringlabel)设置显示的字符串。(2)StringgetText()返回当前显示的字符串。(3)voidsetAlignment(intalignment)设置对齐方式。(4)voidsetFont(Fontf)设置显示的字符串的字体。(5)voidsetBackground(Colorc)设置显示的字符串的背景颜色。(6)voidsetForekground(Colorc)设置显示的字符串的颜色。,8.4.2按钮组件,Swing提供了标准按钮(JButton)组件,按钮可以带有文字标题与图标。1按钮的创建例8.5本例应用程序用来创建添加有不同按钮的窗口,程序运行结果如图所示。importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;publicclassJBextendsJFrameprivateJButtonbutton1,button2;publicJB(JFramef,JPanelp)f.add(p);/将面板p加入到窗口f中button1=newJButton(按钮1);/创建按钮对象button1.setFont(newFont(Serif,Font.PLAIN,20);,ImageIconimg1=newImageIcon(图片/1.gif);ImageIconimg2=newImageIcon(图片/2.gif);button2=newJButton(按钮2,img2);button2.setRolloverIcon(img1);button2.setFont(newFont(Serif,Font.PLAIN,14);/为组件注册监听器BHandlerh=newBHandler();button1.addActionListener(h);button2.addActionListener(h);/将各种组件添加到内容面板p.add(button1);p.add(button2);,publicstaticvoidmain(Stringargs)JBf1=newJB(newJF0(添加按钮的窗口),newJPanel();privateclassBHandlerimplementsActionListenerpublicvoidactionPerformed(ActionEventevent)JOptionPane.showMessageDialog(JB.this,你按了:+event.getActionCommand();在例8.5中,可以看到创建按钮对象的方式及控制使用方式。,运行结果显示:,编写本应用程序要在“程序/图片”目录下先保存两个名称为1.gif、2.gif的图片文件。在处理命令按钮的单击事件时,需要实现ActionListener事件接口类中的actionPerformed(ActionEventevent)方法。通过addActionListener(h)方法将监听器注册到命令按钮上。通过JOptionPane.showMessageDialog(JB.this,你按了:+event.getActionCommand()方法能够产生一个消息提示对话框。,注意:,2按钮的构造方法,(1)JButton()创建一个没有标题的按钮。(2)JButton(Stringtext)创建一个带标题的按钮。(3)JButton(Iconimage)创建一个有图标的按钮。(4)JButton(Stringtext,Iconimage)创建一个有标题、有图标的按钮。,8.4.3文本框组件,文本框(TextField)组件用来接收用户键盘输入的单行文本信息。1创建文本框与密码框,例8.6本例应用程序用来创建添加有不同文本框的窗口,程序运行结果如图所示。,importjavax.swing.*;publicclassJTextendsJFrameprivateJTextFieldt1,t2,t3;privateJPasswordFieldkl;publicJT(JFramef,JPanelp)f.add(p);/将面板p加入到窗口f中p.setLayout(newFlowLayout();p.setBackground(Color.YELLOW);t1=newJTextField(10);/创建文本框对象,宽度为10t2=newJTextField(请输入文本);/创建带有初始文本的文本框对象t2.setFont(newFont(Serif,Font.PLAIN,12);,t3=newJTextField(不可编辑的文本框,20);/创建带有初始文本的文本框,宽度为20t3.setFont(newFont(Serif,Font.PLAIN,12);t3.setEditable(false);/设置该文本框为不可编辑状态kl=newJPasswordField(口令,10);/创建密码框p.add(t1);p.add(t2);p.add(t3);p.add(kl);publicstaticvoidmain(Stringargs)JTd=newJT(newJF0(添加文本框的窗口),newJPanel();,创建不同的文本框,运行结果显示:,(1)JTextField()创建一个默认宽度的文本框。(2)JTextField(intcolumns)创建一个指定宽度的文本框。(3)JTextField(Stringtext)创建一个带有初始文本内容的文本框。(4)JTextField(Stringtext,intcolumns)创建一个带有初始文本内容并具有指定宽度的文本框。,2.文本框的构造方法,8.4.4文本区组件,与文本框组件只显示一行不同,文本区(JTextArea)可以显示大段的文本。1创建文本区例8.7本例应用程序用来创建添加有两个文本区组件的窗口,程序运行结果如图所示(见课本P162)。,(1)JTextArea()创建一个默认大小的文本区。(2)JTextArea(introws,intcolumns)创建一个指定行和列数的文本区。(3)JTextArea(Stringtext)创建一个带有初始文本内容的文本区。(4)JTextArea(Stringtext,introws,intcolumns)创建一个带有初始文本内容并具有指定行和列数的文本区。,2文本区的构造方法,(1)publicvoidappend(Stringstr)在文本区尾部添加文本。(2)publicvoidinsert(Stringstr,intpos)在文本区指定位置插入文本。(3)publicvoidsetText(Stringt)设定文本区内容,会将原来的内容清除。(4)publicintgetRows()返回文本区的行数。,3文本区的常用方法,(5)publicvoidsetRows(introws)设定文本区的行数。(6)publicintgetColumns()返回文本区的列数。(7)publicvoidsetColumns(intcolumns)设定文本区的列数。(8)publicvoidsetEditable(booleanb)设定文本区的读写状态。,8.4.5单选按纽组件,单选按钮包含一组按钮,按钮处于选中或未选中两种状态。用户通过按钮只能选择其中的一个选项。单选按钮由JRadioButton类与ButtonGroup类的对象共同构成。JRadioButton用于设置各个单选选项,ButtonGroup对象用于维护一组互斥单选选项的关系。例8.8本例应用程序用来创建包含有3个颜色单选按钮的窗口,根据选择可以显示不同的颜色,程序运行结果如图所示(见课本P164)。,8.4.6复选框,复选框(JCheckbox)同样存在选中或未选中两种状态。通过复选框用户可以一次做出多项选择。例8.9本例应用程序用来创建包含两个字体复选按钮的窗口,根据选择可以改变窗口中标签对象的字体,程序运行结果如图所示(见课本P165)。,下拉列表(JComboBox)与单选按钮类似,同样存在选中或未选中两种状态。使用下拉列表可以让用户在列表框的多个选项中选择一个选项。列表框的所有选项都是可见的。例8.10本例应用程序用来创建包含一个下拉老板组件的窗口,根据选择可以改变窗口中标签对象的字体,程序运行结果如图所示(见课本P166)。,8.4.7下拉列表组件,8.5组件布局管理,组件是由布局管理器对象来管理的,通过容器的setLayout方法可以调出布局管理器来确定组件的存放位置。本节的内容主要介绍如何使用布局管理器确定存放在容器中组件的摆放位置。注意本节中使用的窗口对象都是在自定义类中直接创建的(同样可以通过JF0类来创建,那样可以统一主界面)。,8.5.1顺序布局管理器,顺序布局(FlowLayout)管理器是最基本的布局管理器,是容器指定的一个默认的布局管理器。它负责把组件一个接一个地从左到右顺序排列,一行排满后就转到下一行继续排列。在顺序布局管理器领导下,一个组件通过容器的add方法就可以把自己加入到容器的组件队列中。但顺序布局管理器功能有限,不能很好地控制组件的排列,所以常用在组件较少的情况下。,8.5.2边界布局管理器,边界布局(BorderLayout)把容器(这里是Applet)分为五个区:北区、南区、东区、西区和中区。这几个区的分布规律是“上北下南,左西右东”,与地图的方位相同。组件可以指定自己放在那个区内,因为只有5个区,所以最多只能容纳5个组件,否则要采取其它布局方式。,例8.11本例应用程序用来创建一个使用边界布局管理器存放组件的窗口,程序运行结果如图所示。,importjavax.swing.JFrame;importjavax.swing.*;importjava.awt.*;publicclassBLextendsJFrameBorderLayoutbl=newBorderLayout();/创建BorderLayout布局管理器对象JButtonbN,bS,bW,bE,bC;publicBL()super(布局管理器);setSize(300,200);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);/创建5个按钮对象bN=newJButton(北);bS=newJButton(南);bE=newJButton(东);bW=newJButton(西);bC=newJButton(中);,Containerc=getContentPane();/创建内容面板c.setLayout(bl);/设置内容面板的布局管理器为布局管理器c.add(North,bN);c.add(South,bS);c.add(East,bE);c.add(West,bW);c.add(Center,bC);setVisible(true);publicstaticvoidmain(Stringargs)BLd=newBL();说明:在add方法中,第1个参数表示组件的摆放位置,必须从North、South、East、West、Center中选择一个。第2个参数是组件对象名。,运行结果显示:,边界布局管理器,8.5.3卡片布局管理器,卡片布局(CardLayout)管理器可以管理多个组件,它将组件像卡片一样叠放起来,每次只显示一个。因此需要使用某种方法翻阅这些卡片。例8.12本例应用程序用来创建的窗口分为两个层次,最底层为内容面板对象,在其上面使用边界布局管理器在中间存放了一个面板对象pane,在下方存放了一个名称为“选择卡片”的按钮对象button。程序运行结果如图所示。,运行结果显示:,使用卡片布局管理器的窗口,importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;publicclassCLextendsJFrameJPanelpane=newJPanel();JButtonbutton=newJButton(选择卡片);CardLayoutcard=newCardLayout();publicCL()super(使用卡片布局管理器的窗口);setSize(300,200);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);pane.setLayout(card);/为面板pane调出卡片布局管理器/通过循环语句直接将创建出的5个按钮对象添加到pane面板上for(inti=1;i=5;i+)pane.add(String.valueOf(i),newButton(卡片号为:+i);card.show(pane,String.valueOf(1);,Containerc=getContentPane();c.add(pane,BorderLayout.CENTER);/为内容面板c调出边界布局管理器c.add(button,BorderLayout.SOUTH);/在注册监听器同时创建ActionListener接口对象button.addActionListener(newActionListener()publicvoidactionPerformed(ActionEvente)card.next(pane););setVisible(true);publicstaticvoidmain(Stringarguments)CLct=newCL();,8.5.4网络布局管理器,网格布局(GridLayout)管理器把容器区域分成若干个网格,每个网格可以放置一个组件,这种布局方式对数量众多的组件很合适。例8.13本例应用程序用来创建的窗口在内容面板对象上使用网格布局管理器划分了3行3列,9个网格,存放了6个按钮对象,3个标签对象,程序运行结果如图所示(见课本P170)。如果要在网格之间添加间距,例如创建GridLayout(3,3,10,10)对象时设置网格之间距离为10个点距。,使用网格布局管理器的窗口,运行结果显示:,8.5.5组件的精确定位方式,存放组件也可以不用布局管理器,即使用setLayout(null)方法使布局管理器为空,这时可以使用setBounds(intx,inty,intw,inth)方法精确指出组件在容器中的存放位置。例8.14本例应用程序用来创建的窗口在内容面板对象上使用精确定位方式指定了组件的存放位置与大小,程序运行结果如图所示(见课本P170)。,使用精确定位方式指定组件的存放位置,运行结果显示:,8.6事件处理机制,在前面编写的程序中,对命令按钮、单选按钮、复选框等不同组件添加了监听器,当有单击、选择选项等事件发生时,会进行相应的处理。Java在处理事件问题上设计了Event类。本节的内容主要介绍Java有哪些类型的事件处理类,它们是如何解决事件问题的。,8.6.1Java的事件处理机制,1.事件在图形用户界面中,程序和用户的交互是通过组件响应各种事件来实现的。例如,用户单击了一个按钮,意味着发生了按钮的单击事件;选中下拉列表中的一个选项,意味着发生了一个选项事件。2.事件处理方法当发生事件时做出反应,需要编写一个或多个对应的事件处理方法,通过监听器对象可以对事件源对象进行监听,当监听到事件发生时,就可以调用事件处理方法处理事件问题。,3.事件处理模型,事件处理模型分为3个部分:事件源对象、事件监听器对象与事件对象。能产生事件的组件叫做事件源,如按钮。事件监听器注册在事件源对象(按钮或包含按钮的容器)上,用来监听事件是否发生,当事件发生时将调用事件处理方法解决问题。事件对象用来封装已发生的事件的信息,在事件发生后,将信息传递给事件处理方法进行处理。,事件监听器对象是一个实现了相应事件接口类所有事件方法的类。例如例8.5中BHandler类就是一个事件监听器类,它实现了单击事件接口类ActionListener的actionPerformed(ActionEvente)抽象方法,因此,可以通过BHandler类创建出事件监听器对象h。事件监听器对象具有两个功能,监听事件是否发生,发生后使用事件处理方法解决问题。事件对象是由系统自动创建的。,8.6.2Java的常用事件接口与接口方法,Java将所有组件可能发生的事件进行了分类,具有共同特征的事件被抽象为一个事件类Event或事件接口。它们用来处理该类组件发生的事件。事件接口类中定义了一些抽象的方法来统一处理某一类事件,因此在设计事件监听器类时必须实现或覆盖这些抽象处理方法。Java定义的常用事件类和事件接口如表所示(见课本P173)。,1通过自定义内部类创建监听器对象例8.15本程序在窗口上创建了一个按钮和一个标签,用鼠标单击按钮时,会听到一声响声。如图所示。执行单击事件的窗口,8.6.3事件处理机制的不同实现方式,importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;publicclassJB1extendsJFramepublicJB1(JFramef,JPanelp)f.add(p);/将面板p加入到窗口f中p.add(newLabel(按一下按钮可听到响声!,Label.CENTER);Buttonb=newButton(按钮);p.add(b);BHandlerh=newBHandler();/创建事件监听器对象b.addActionListener(h);/注册事件监听器对象,publicstaticvoidmain(Stringargs)JB1f1=newJB1(newJF0(单击按钮事件),newJPanel();privateclassBHandlerimplementsActionListenerpublicvoidactionPerformed(ActionEvente)Toolkit.getDefaultToolkit().beep();,说明:,(1)在应用程序头部要引入系统事件类包java.awt.event.*。(2)本程序在类JB1中设计了一个自定义内部类BHandler,在类中实现单击事件监听器接口ActionListener的actionPerformed事件接口方法,即编写事件处理代码以响应事件的发生。当单击按钮时,系统将产生ActionEvent事件对象e,事件监听器对象传递e给actionPerformed方法处理这个事件。(3)根据类BHandler可以创建监听器对象h并注册给按钮对象b。,单击事件类ActionEvent有以下一些常用方法:(1)publicStringgetActionCommand()可返回事件源的标签。如b的标签是“按钮”。(2)publicObjectgetSource()返回产生事件的对象名,如b。(3)publicintgetModifiers返回事件发生时功能控制键的状态,它们可能是功能键常数SHIFT_MASK、CTRL_MASK、ALT_MASK。,2在注册时通过匿名类直接创建监听器对象,例8.16本程序运行结果与图相同。仅用来说明创建监听器的方式。importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;publicclassJB2extendsJFramepublicJB2(JFramef,JPanelp)f.add(p);/将面板p加入到窗口f中p.add(newLabel(按一下按钮可听到响声!,Label.CENTER);Buttonb=newButton(按钮);,p.add(b);/注册事件监听器对象b.addActionListener(newActionListener()publicvoidactionPerformed(ActionEvente)Toolkit.getDefaultToolkit().beep(););publicstaticvoidmain(Stringargs)JB2f1=newJB2(newJF0(单击按钮事件),newJPanel();,说明:,在例8.16中使用了匿名类,匿名类是指在声明一个类时不给它命名的类。例8.16取消了例8.15中的ActionListener的子类BHandler的创建过程,直接将这个子类的实例化与初始化表达式newActionListener()作为参数传递给了按钮对象的addActionListener方法,并在方法的括号内实现了ActionListener接口类的actionPerforme方法。这是匿名类的一种典型使用方式。本程序通过给事件源添加监听器对象时,通过匿名类方式创建了监听器对象。,例8.17本程序运行结果与图8.16相同。仅用来说明创建监听器的方式。importjavax.swing.*;importjava.awt.*;importjava.awt.event.*;publicclassJB3extendsJFrameimplementsActionListenerpublicJB3(JFramef,JPanelp)f.add(p);/将面板p加入到窗口f中p.add(newLabel(按一下按钮可听到响声!,Label.CENTER);Buttonb=newButton(按钮);p.add(b);,3通过主类创建监听器对象,b.addActionListener(this);/注册事件监听器对象publicvoidactionPerformed(ActionEvente)Toolkit.getDefaultToolkit().beep();publicstaticvoidmain(Stringargs)JB3f1=newJB3(newJF0(单击按钮事件),newJPanel();说明:本程序通过给JB3添加ActionListener接口,并实现了接口的actionPerforme方法,所以JB3就成为了一个监听器对象。,上面的例子只是发生一种事件,如果在程序中有多个事件发生怎么办呢?可使用多个事件接口,然后实现各自的事件处理方法。看下面的例子。例8.18在窗口中用鼠标拖动画线。运行结果如图所示(见课本P176)。实现多个接口,4实现多个事件接口的方式,8.6.4事件适配器类与内部类,1.事件适配器类在例8.18程序中出现了多余的东西,即那些用不到的以空方法形式给出的方法。在java.awt.event包中还声明了一组带Adapter标记的类,称为适配器类。它们是一些抽象类,其中声明的方法与相应的接口的方法完全相同,也是空方法。但在继承它们创建新类时,可以不实现所有的方法,只要实现需要的方法即可。,为了更好地加强类之间的联系,在Java中可以把一个类声明为另一个类的成员,这样的类称为内部类(innerclass)或被包容类(nestedclass),例如:classEnclosingClass/主类staticclassNestedClass/被包容类classInnerClass/内部类,2.被包容类(内部类),被包容类可以无条件地使用主类的所有成员,包括私有成员。和类的其他成员一样,被包容类可以被声明为静态类,非静态被包容类称为内部类(innerclass),它们也可以声明为抽象类或最终类,这些和一般类的声明是完全相同的。下面通过例子说明内部类和适配器的使用方法。在例8.19中将例8.18用接口方法响应的鼠标事件,改写为使用内部类MouseHandler和MouseMotionHandler事件适配器来实现。,例8.19使用内部类与适配器改写的在窗口中用鼠标拖动画线的程序。importjava.applet.Applet;importjava.awt.*;importjava.awt.event.*;publicclassDrawLine1extendsAppletintx1,y1,x2,y2;publicvoidinit()addMouseListener(newM1();addMouseMotionListener(newM2();,publicvoidpaint(Graphicsg)g.drawLine(x1,y1,x2,y2);classM1extendsMouseAdapterpublicvoidmousePressed(MouseEvente)x1=e.getX();y1=e.getY();classM2extendsMouseMotionAdapterpublicvoidmouseDragged(MouseEvente)x2=e.getX();y2=e.getY();repaint();,例8.19在主类中添加了两个内部类M1和M2,前者继承抽象类MouseAdapter并实现了mousePressed方法,后者继承并实现了抽象类MouseMotionAdapter中的mouseDragged方法。使用时,直接将它们作为addMouseListener或addMouseMotionListener方法的参数,在参数传递中实现实例化对象,并作为事件监控者对发生的事件调用事件处理方法。由于它们都被设计为内部类,所以能自由访问主类的各个成员,实现和例8.18完全相同的功能,程序也更加简洁。,说明:,8.7创建容器与组件基本步骤小结,通过本章的应用程序可以总结出创建容器与组件的基本步骤如下:创建顶层容器(常用的为窗口对象)。创建内容面板,设置其背景颜色,设置其布局管理器。创建普通面板,设置其背景颜色,设置其位置、大小,设置其布局管理器。创建组件,设置其背景颜色,设置其位置、大小、字体等。将面板添加到窗口,将组件添加到指定面板。创建事件监听器,实现事件接口方法。给事件源注册监听器。,习题,图形用户界面与字符界面有什么不同?图形用户界面由什么构成?分析它们的作用。创建一个可以移动、改变大小、最大化、可变成图标、包含内容面板对象的且可以关闭的JFrame窗口类“题8_3”。在8-3题创建的窗口中添加标签、按钮、文本区组件,分别放置在窗口的上、左、中部位。为以上创建的窗口中的组件添加事件处理功能。要求在文本框中输入字符串,当按下回车键或单击按钮时,将输入的文字显示在文本区中。在上面创建的窗口的下部添加一个选项按钮,并能通过选择改变窗口的背景颜色。本章介绍了哪些Java布局方式?简述常用布局方式的特点。,什么是内部类?内部类有什么特点?什么是适配器?适配器有什么作用?编写一个模拟计算器的Applet,使用面板和网格布局,添加一个文本框,10个数字按钮(09),4个加减乘除按钮,一个等号按钮,一个清除按钮。要求将计算公式和结果显示在文本框中,如图所示。,
展开阅读全文