第十四章GUI编程图形用户界面(Graphicsuserinterface,GUI)是指用图形的方式,借助菜单、按钮等标准界面元素和鼠标操作,帮助用户方便地向计算机系统发出指令、启动操作,并将系统运行的结果以图形方式显示给用户的技术。由于用户界面设计质量的好坏直接影响软件的使用,Java语言对此也十分重视,几乎在JDK每个新的版本中,都增加了一定的GUI程序设计新技术或功能,Java语言的GUI发展始终保持着较好的连贯性和兼容性。目前Java主要提供了两个处理图形用户界面的类库:java.awt和javax.swing。AWT:抽象窗口工具集(AbstractWindowsToolkit),由于Java代码可以在不同的系统平台运行,而不同平台的图形界面外观设计各有差异,所以Java程序的图形用户界面在不同的平台上可能出现不同的运行效果,其外观取决于具体的平台,所以称AWT是一个抽象的工具集。Swing:Swing是在AWT的基础上构建的,提供了比标准AWT组件更强大和灵活的功能。与AWT组件不同的是,Swing组件不是由特定的平台代码实现,而是纯粹的Java代码,因此能够实现与平台的无关(此类组件一般被称为轻量级组件)。利用GUI类库设计和实现图形用户界面的工作主要有两个:一是应用的外观设计,即创建组成图形界面的各部件,指定其位置和属性关系,根据需要进行排列,从而构成完整的图形用户界面的物理外观;二是与用户的交互处理,包括定义图形用户界面的事件以及各部件对不同时间的响应处理。那现在开始就先讲AWT。AWT类包含在java.awt包中,主要包括用户界面组件、事件处理模型、图形和图像工具、布局管理器等。Java.awt包中的主要类及组件类的继承关系如图先来个最简单的例子1.publicclassTestPanel2.{3.publicstaticvoidmain(String[]args)4.{5.Framef=newFrame(测试窗口);6.//创建一个Panel对象7.Panelp=newPanel();8.//相Panel对象中添加两个组件9.p.add(newTextField(20));10.p.add(newButton(单击我));11.f.add(p);12.//设置窗口的大小、位置13.f.setBounds(30,30,250,120);14.//将窗口显示出来(Frame对象默认处于隐藏状态)15.f.setVisible(true);16.}17.}然后我讲下布局管理器AWT中分为FlowLayoutBorderLayoutCardLayoutGridLayoutGridBagLayout这五种Swing的话再加上BoxLayout顺序布局(FlowLayout)是Panel容器的缺省布局策略,即将加入容器中的组件依次从左至右,从上至下排列,适用于组件个数较少的情况。1.publicclassTestFlowLayout2.{3.publicstaticvoidmain(String[]args)4.{5.Framef=newFrame(测试窗口);6.//设置Frame容器使用FlowLayout布局管理器7.f.setLayout(newFlowLayout(FlowLayout.LEFT,20,5));8.//向窗口中添加10个按钮9.for(inti=0;i10;i++)10.{11.f.add(newButton(按钮+i));12.}13.//设置窗口为最佳大小14.f.pack();15.//将窗口显示出来(Frame对象默认处于隐藏状态)16.f.setVisible(true);17.}18.}pack()方法非常有用,能讲窗口调整到最佳大小边界布局(BorderLayout)是Frame,Dialog,ScrollPane的缺省布局。区域布局将容器分为东西南北中五个区域,加入组件时,应通过字符串East/West/South/North/Center来标记组件的方位。1.publicclassTestBorderLayout2.{3.publicstaticvoidmain(String[]args)4.{5.Framef=newFrame(测试窗口);6.//设置Frame容器使用BorderLayout布局管理器7.f.setLayout(newBorderLayout(30,5));8.f.add(newButton(南),BorderLayout.SOUTH);9.f.add(newButton(北),BorderLayout.NORTH);10.//默认添加到中间11.f.add(newButton(中));12.f.add(newButton(东),BorderLayout.EAST);13.f.add(newButton(西),BorderLayout.WEST);14.//设置窗口为最佳大小15.f.pack();16.//将窗口显示出来(Frame对象默认处于隐藏状态)17.f.setVisible(true);18.}19.}卡片布局(CardLayout)将容器中的每一个组件当作一个卡片,一次仅有一个卡片可见,最初显示容器时,加入到容器的第一个组件可见。1.publicclassTestCardLayout2.{3.Framef=newFrame(测试窗口);4.String[]names={第一张,第二张,第三张,第四张,第五张};5.Panelpl=newPanel();6.CardLayoutc=newCardLayout();7.publicvoidinit()8.{9.pl.setLayout(c);10.for(inti=0;inames.length;i++)11.{12.pl.add(names[i],newButton(names[i]));13.}14.Panelp=newPanel();15.//控制显示上一张的按钮16.Buttonprevious=newButton(上一张);17.previous.addActionListener(newActionListener()18.{19.publicvoidactionPerformed(ActionEvente)20.{21.c.previous(pl);22.}23.});24.//控制显示下一张的按钮25.Buttonnext=newButton(下一张);26.next.addActionListener(newActionListener()27.{28.publicvoidactionPerformed(ActionEvente)29.{30.c.next(pl);31.}32.});33.//控制显示第一张的按钮34.Buttonfirst=newButton(第一张);35.first.addActionListener(newActionListener()36.{37.publicvoidactionPerformed(ActionEvente)38.{39.c.first(pl);40.}41.});42.//控制显示最后一张的按钮43.Buttonlast=newButton(最后一张);44.last.addActionListener(newActionListener()45.{46.publicvoidactionPerformed(ActionEvente)47.{48.c.last(pl);49.}50.});51.//控制根据Card名显示的按钮52.Buttonthird=newButton(第三张);53.third.addActionListener(newActionListener()54.{55.publicvoidactionPerformed(ActionEvente)56.{57.c.show(pl,第三张);58.}59.});60.p.add(previous);61.p.add(next);62.p.add(first);63.p.add(last);64.p.add(third);65.f.add(pl);66.f.add(p,BorderLayout.SOUTH);67.f.pack();68.f.setVisible(true);69.}70.publicstaticvoidmain(String[]args)71.{72.newTestCardLayout().init();73.}74.}75.网格布局(GridLayout)将容器划分为n*m的大小相同的小格,每格区间可摆放一个组件。向容器中增加组件时,按从左至右,从上至下的顺序依次存放.eg1.publicclassTestGridLayout2.{3.publicstaticvoidmain(String[]args)4.{5.Framef=newFrame(计算器);6.Panelp1=newPanel();7.p1.add(newTextField(30));8.f.add(p1,BorderLayout.NORTH);9.Panelp2=newPanel();10.//设置Panel使用GridLayout布局管理器11.p2.setLayout(newGridLayout(3,5,4,4));12.String[]name={0,1,2,3,4,5,13.6,7,8,9,+,-,*,/,.};14.//向Panel中依次添加15个按钮15.for(inti=0;iname.length;i++)16.{17.p2.add(newButton(name[i]));18.}19.f.add(p2);20.//设置窗口为最佳大小21.f.pack();22.//将窗口显示出来(Frame对象默认处于隐藏状态)23.f.setVisible(true);24.}25.}网格包布局(GridBagLayout)这个功能最强大,但用起来太麻烦了。将视图分为多个单元,可以指定每个组件占用的单元GridBagConstraints类-参数:gridx,gridy:组件的位置gridwidth,gridheight:组件覆盖的网格单元个数insets:组件和包含它的网格单元之间的距离weightx,weighty:视图大小变化时,组件的情况,标准为100,0为组件占用空间不变fill:填充方式,4种anchor:组件在网格单元中的位置,CENTER/NORTH/NORTHWEST。eg1.publicclassTestGridBag2.{3.privateFramef=newFrame(测试窗口);4.privateGridBagLayoutgb=newGridBagLayout();5.privateGridBagConstraintsgbc=newGridBagConstraints();6.privateButton[]bs=newButton[10];7.publicvoidinit()8.{9.f.setLayout(gb);10.for(inti=0;ibs.length;i++)11.{12.bs[i]=newButton(按钮+i);13.}14.//所有组件都可以横向、纵向上扩大15.gbc.fill=GridBagConstraints.BOTH;16.gbc.weightx=1;17.addButton(bs[0]);18.addButton(bs[1]);19.addButton(bs[2]);20.//该GridBagConstraints控制的GUI组件将会成为横向最后一个元素21.gbc.gridwidth=GridBagConstraints.REMAINDER;22.addButton(bs[3]);23.//该GridBagConstraints控制的GUI组件将横向上不会扩大24.gbc.weightx=0;2