第12章图形用户界面基础•基础知识•界面布局•事件处理•匿名内部类•常用组件一、基础知识图形用户界面(GUI)是在图形化系统下应用程序呈现的可视化和可交互的界面。GUI以窗口(Window)作为界面的最基本元素,所有的界面要素都包含在其中。窗口一般来说都是矩形,可以嵌套包含。JavaGUI编程自身应用并不是很广,但是其使用了一种编程模型:模型-视图-控制器(Model-View-Controller,MVC)模型。该模型被广泛应用于各种程序设计中。Java有多种方式实现GUI,•最原始的称为AWT,相关类在包java.awt中•最为著名的是Swing,相关类在包javax.swing中AWT有着较大的局限性,最好的方法是Swing。Swing包含两种界面元素:组件和容器。•组件是独立的界面控件,例如按钮、文本框等。•容器是用于容纳组件的特殊组件。容器分为顶级容器和轻量级容器,•顶级容器是不能被其他容器包含的容器,有JFrame、JApplet、JWindow和JDialog。•轻量级容器用来包含和组织一组相关的组件,包括JPanel、JScrollPane、JRootPane等。二、界面布局界面布局指的是容器内组件的排列方式。容器对象通过setLayout方法设置其内部组件的布局。Swing常用的布局如下:•FlowLayout:组件从左到右,从上到下的顺序排列•BorderLayout:将容器分为东西南北中5个区域•GridLayout:容器分为单元格大小相同的网格•GridBagLayout:单元格大小不同,组件可以占据多个单元格•BoxLayout:在容器中按照水平或垂直方向排列•SpringLayout:组件根据相对位置排列•CardLayout:组件按照层叠的方式排列创建GUI的简单步骤:1.新建容器对象new2.设置容器属性set…3.设置容器布局方式,默认为BorderLayoutsetLayout4.设置容器约束…Constrants5.创建组件对象new6.设置组件属性set…7.将组件对象加入容器中add,早期版本为getContentPane().add8.将容器设为可见setVisible(true)importjavax.swing.*;publicclassswingTest{publicstaticvoidmain(Stringargs[]){JFramefrm=newJFrame(Helloworld!);frm.setSize(500,120);frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//frm.setLayout(newBorderLayout(3,3));Stringdirection[]={East,West,South,North,Center};for(inti=0;i5;++i){JButtonbtn=newJButton(Hello,I'malabel+i+哈\t.);frm.add(direction[i],btn);}frm.setVisible(true);}}定义“关闭”按钮的行为BorderLayout为默认布局importjava.awt.FlowLayout;importjavax.swing.*;publicclassswingTest{publicstaticvoidmain(Stringargs[]){JFramefrm=newJFrame(Helloworld!);frm.setSize(400,120);frm.setLayout(newFlowLayout());for(inti=0;i8;++i){JLabellbl=newJLabel(Hello,I'malabel.+i+哈.;frm.add(lbl);}frm.setVisible(true);}}importjava.awt.GridLayout;importjavax.swing.*;publicclassswingTest{publicstaticvoidmain(Stringargs[]){JFramefrm=newJFrame(Helloworld!);frm.setSize(500,120);frm.setLayout(newGridLayout(3,3));for(inti=0;i8;++i){JButtonbtn=newJButton(Hello,I'malabel.+i);frm.add(btn);}frm.setVisible(true);}}网格的行和列数,省略的话只有一行publicclassswingTest{publicstaticvoidmain(Stringargs[]){JFramefrm=newJFrame(Helloworld!);frm.setSize(500,200);frm.setLayout(newGridBagLayout());GridBagConstraintsct=newGridBagConstraints();ct.fill=GridBagConstraints.BOTH;//填充方式for(inti=0;i3;++i){ct.gridx=i;//列数ct.gridy=0;//行数ct.gridwidth=1;//宽度占用几个单元格JButtonbtn=newJButton(Hello,I'mabutton.+i);frm.add(btn,ct);}ct.gridx=0;ct.gridy=1;ct.gridwidth=3;设置组件位置和大小的约束条件ct.ipady=60;//标准高度之外的额外高度JButtonbtn1=newJButton(BigButton);frm.add(btn1,ct);JButtonbutton=newJButton(5);ct.gridx=1;ct.gridy=2;ct.gridwidth=2;ct.ipady=0;ct.weighty=1.0;//窗口缩放时单元格随之拉伸的程度0-1ct.anchor=GridBagConstraints.PAGE_END;//对齐方式ct.insets=newInsets(10,0,0,0);//上左下右的边距frm.add(button,ct);frm.setVisible(true);}}importjava.awt.BoxLayout;importjavax.swing.*;publicclassswingTest{publicstaticvoidmain(Stringargs[]){JFramefrm=newJFrame(Helloworld!);frm.setSize(400,120);frm.setLayout(newBoxLayout(frm.getContentPane(),BoxLayout.X_AXIS));for(inti=0;i8;++i){JButtonbtn=newJbutton(Hello,I'malabel.+i);frm.add(btn);}frm.setVisible(true);}}水平排列,Y_AXIS为垂直排列importjavax.swing.*;publicclassswingTest{publicstaticvoidmain(Stringargs[]){JFramefrm=newJFrame(Helloworld!);frm.setSize(300,150);SpringLayoutlayout=newSpringLayout();frm.setLayout(layout);JButtonleft=newJButton(left);frm.add(left);JButtonright=newJButton(right);frm.add(right);JButtondown=newJButton(down);frm.add(down);//设置第一个组件相对于容器的位置layout.putConstraint(SpringLayout.WEST,left,10,SpringLayout.WEST,frm);layout.putConstraint(SpringLayout.NORTH,left,25,SpringLayout.NORTH,frm);//设置第二个组件相对于第一个组件的位置layout.putConstraint(SpringLayout.WEST,right,10,SpringLayout.EAST,left);layout.putConstraint(SpringLayout.NORTH,right,25,SpringLayout.NORTH,frm);//设置第三个组件相对于第一个组件的位置layout.putConstraint(SpringLayout.WEST,down,10,SpringLayout.WEST,frm);layout.putConstraint(SpringLayout.NORTH,down,10,SpringLayout.SOUTH,left);frm.setVisible(true);}}importjava.awt.CardLayout;importjavax.swing.*;publicclassswingTest{publicstaticvoidmain(Stringargs[]){JFramefrm=newJFrame(Helloworld!);frm.setSize(400,120);frm.setLayout(newCardLayout());for(inti=0;i8;++i){JButtonbtn=newJButton(Hello,I'mabutton.+i);frm.add(btn);}frm.setVisible(true);}}三、事件处理事件处理指的是交互式组件接受用户或系统行为,并进行处理。Swing的事件处理将组件、行为和处理进行分离,其中:•进行交互的组件称为事件源•在组件上发生的行为称为事件•负责对事件进行处理的对象称为监听者事件处理的流程是:1)建立指定事件的监听者对象2)为事件源加入(注册)监听者3)当指定事件发生时,监听者的方法处理接口描述ActionListener组件单击、回车等确认动作ItemListener某选择项被选择/取消选择TextListener文本内容改变MouseListener鼠标事件KeyListener键盘事件FocusListener焦点事件CompomentListener容器中的组件发生的事件WindowListener窗口事件ContainerListener容器中添加/删除组件事件不同类事件的监听者在Java中以不同的接口表示,具体事件由接口中的指定方法表示。建立监听者对象即是建立对应接口的实现类,并实现相应的方法处理指定的事件。例如,鼠标点击、确认等行为的监听者接口为ActionListener;键盘输入行为的监听者接口为KeyListener等。为了方便访问界面组件,监听者的实现类一般是包含组件的类。importjava.awt.event.*;publicclasslistenerTestimplementsActionListener{@OverridepublicvoidactionPerformed(ActionEvente){……}}publicclassswingTestimplementsActionListener{JLabellbl;publicswingTest(){JFramefrm=newJFrame();frm.setSize(400,200);lbl=newJLabel();frm.add(Center,lbl);JButtonbtn=newJButton(Clickme);btn.addActionListener(this);frm.add(South,btn);frm.setVis