第9章Java图形用户界面第9章Java图形用户界面教学提示:在Java的图形化程序设计中,需要有大量的组件来支持。Component是许多组件类的父类,它封装了组件通用的方法和属性,如组件大小、显示位置、前景色和背景色、边界、可见性等。容器(Container)也是一个类,它是Component的子类,它的主要功能是容纳其他组件和容器,而每个容器都有一个默认布局管理器。本章主要介绍:Java中常用的非容器组件类、容器组件类以及用于管理容器布局的布局管理器等,它们是进行图形化设计的基础,从类对象的创建、类的属性、事件类型等方面来综合掌握这些类的应用。本章通过介绍常用类的使用方法,使读者能够进行窗体的设计,并运用事件处理机制来处理事件。第9章Java图形用户界面9.1容器与基本控件9.2布局管理器9.3Java中键盘事件和鼠标事件9.4彩色列表框实例9.5课后练习9.1容器与基本控件9.1.1窗口9.1.2面板和画布9.1.3菜单9.1.4按钮9.1.5文本框和文本域9.1.6标签9.1容器与基本控件本节将重点介绍Java的窗口编程中几个常用的控件,熟悉和掌握它们将有利于很好地进行Windows程序开发。9.1.1窗口1.Frame的创建Frame类提供了两个构造方法来分别创建不带标题和带标题的Frame窗口。publicFrame():创建一个不可见的无标题Frame窗口。publicFrame(Stringtitle):创建一个不可见的指定标题的Frame窗口。9.1.1窗口2.Frame的常用方法由于Component、Container、Window和Frame依序存在父子类关系,除了可以继承其父类的非私有方法外,Frame类又提供了相应的方法来改变Frame窗口的属性,如表9-1所示。9.1.1窗口表9-1Frame类中常用的方法9.1.1窗口3.Frame与窗口事件Frame是一个带有标题和缩放角的窗口,有自己的外边框和标题,创建Frame时可以指定其窗口标题。每个Frame在其右上角都有3个控制图标,分别代表将窗口最大化、最小化和关闭的操作,其中,最大化和最小化操作Frame可自动完成,而关闭窗口的操作不能通过单击关闭图标实现,必须通过事件响应来关闭窗口,在前面含有窗口的示例中,都不能通过关闭按钮来退出程序,只能使用Ctrl+Alt+Del键来强行退出。9.1.1窗口窗口事件是由于窗口收到窗口级事件而产生的,该事件对应的接口名称是WindowListener,该接口的定义如下:publicinterfaceWindowListenerextendsEventListener{publicvoidwindowClosing(WindowEvente);//退出窗口的语句写在本方法中publicvoidwindowOpened(WindowEvente);//窗口打开时调用publicvoidwindowIconified(WindowEvente);//窗口图标化时调用publicvoidwindowDeiconified(WindowEvente);//窗口非图标化时调用publicvoidwindowClosed(WindowEvente);//窗口关闭时调用publicvoidwindowActivated(WindowEvente);//窗口激活时调用publicvoidwindowDeactivated(WindowEvente);//窗口非激活时调用}9.1.1窗口【例9.1】MyFrame类可以实现两种退出运行程序、关闭窗口的方法。一种是通过用户设置的Exit按钮,另一种是使用窗口关闭按钮。其中CloseFrame是用来关闭窗口的类。程序如下。importjava.awt.*;importjava.awt.event.*;publicclassMyFrameimplementsActionListener{publicstaticvoidmain(Stringargs[]){Framef=newFrame(Hello!);Buttonbutton=newButton(exit);f.setLayout(newFlowLayout());f.add(button);button.addActionListener(newMyFrame());//注册ActionListener监听器f.setBounds(0,0,260,120);f.addWindowListener(newCloseFrame());//注册WindowListener监听器f.setVisible(true);}//重写ActionListener接口中的actionPerformed()方法9.1.1窗口publicvoidactionPerformed(ActionEvente){if(e.getActionCommand()==exit)System.exit(1);}}//定义处理窗口事件的类CloseFrame,实现WindowListener接口classCloseFrameimplementsWindowListener{publicvoidwindowClosing(WindowEvente){System.exit(1);}//退出系统publicvoidwindowActivated(WindowEvente){}publicvoidwindowDeactivated(WindowEvente){}publicvoidwindowClosed(WindowEvente){}publicvoidwindowOpened(WindowEvente){}publicvoidwindowIconified(WindowEvente){}publicvoidwindowDeiconified(WindowEvente){}}该程序的运行结果如图9-1所示。9.1.1窗口图9-1运行结果(例9.1)9.1.2面板和画布1.面板和画布的创建Panel类提供了两个构造方法来创建面板对象。publicPanel():创建一个默认布局管理器的面板对象。publicPanel(LayoutManagerlayout):创建一个指定布局管理器的面板对象。面板对象创建之后,就可以运用容器对象的add()方法将该面板加入其他的容器中。当然也可以嵌套面板,即一个面板包含一个或多个其他的面板,例如:Panelpanel1=newPanel();Panelpanel2=newPanel();Panelpanel3=newPanel();panel1.Add(panel2);//把panel2和panel3加入panel1中panel1.Add(panel3);add(panel1);//加入当前小应用程序中9.1.2面板和画布画布组件可以通过下面的构造方法创建:publicCanvas()当程序运行后,将出现一块矩形区域的画布,Canvas组件默认尺寸为0×0,所以必须保证至少在画布中实现自己的尺寸方法。9.1.2面板和画布2.面板和画布的使用Canvas组件的常用方法为publicvoidpaint(Graphicsg),画布是一种通用组件,它本身不具有任何功能,也不处理任何事件,在用户使用画布时应该在程序中派生它的子类,并覆盖Canvas类的paint()方法,就可以在画布上面绘制有关的图形。Canvas组件监听各种鼠标、键盘事件。当在Canvas组件中输入字符时,必须先调用requestFocus()方法。画布和面板都可以“监听”所有适用于一个普通组件的事件,当然也可以引发键盘和鼠标事件,以允许以某种方式对用户输入作出反应。9.1.2面板和画布【例9.3】创建两个面板,每个面板含有两个组件,程序文件名MyPanel.java。程序如下。importjava.awt.*;classMyPanel{publicstaticvoidmain(Stringargs[]){Framef=newFrame(Hello!);Panelpanel1=newPanel();//定义并创建面板对象panel1Panelpanel2=newPanel();//定义并创建面板对象panel2Checkboxcheck1=newCheckbox(BOLD);Checkboxcheck2=newCheckbox(ITALIC);CheckboxGroupgroup=newCheckboxGroup();//定义并创建复选按钮组Checkboxcheck3=newCheckbox(red,group,false);Checkboxcheck4=newCheckbox(blue,group,false);//把复选按钮check1和check2添加到面板容器panel1panel1.add(check1);panel1.add(check2);//把复选按钮check3和check4添加到面板容器panel2panel2.add(check3);panel2.add(check4);f.setLayout(newFlowLayout());//把面板panel1和panel2添加到窗体中9.1.2面板和画布f.add(panel1);f.add(panel2);f.setBounds(0,0,280,150);f.setVisible(true);}}运行效果如图9-2所示。图9-2运行结果(例9.3)9.1.2面板和画布【例9.4】画布的实现和应用,程序文件名CanvasApp.java。程序如下。importjava.awt.*;importjava.awt.event.*;classCanvasApp{publicstaticvoidmain(Stringargs[]){Framef=newFrame(Hello!);//创建MyCanvas对象,并初始化画图颜色为红色MyCanvascv=newMyCanvas(Color.red);cv.setSize(100,100);//设置画布的大小f.setSize(200,200);f.add(cv);f.setLayout(newFlowLayout());f.setVisible(true);}}//定义画布MyCanvas类classMyCanvasextendsCanvas{ColormyColor;//定义画图的颜色对象//构造方法,初始化画图颜色publicMyCanvas(ColordrawColor){9.1.2面板和画布myColor=drawColor;}publicvoidpaint(Graphicsg){intdiameter,xPoint,yPoint;//定义圆的直径和圆的左上角坐标变量DimensioncurrentSize=getSize();//获取当前画布的尺寸//圆的直径取当前画布尺寸中的小值if(currentSize.widthcurrentSize.height)diameter=currentSize.height;elsediameter=currentSize.width;g.setColor(myColor);//设置绘图的颜色xPoint=(currentSize.width-diameter)/2;//左上角x坐标yPoint=(currentSize.height-diameter)/2;//左上角y坐标g.fillOval(xPoint,yPoint,diameter,diameter);//填充一个圆}}该程序的运行结果如