1、第9讲 GUI,9.1 图形用户界面设计概述,9.1.1 GUI概述 1、java.awt包 Java语言在java.awt包中提供了大量地进行GUI设计所使用的类和接口,包括绘制图形、设置字体和颜色、控制组件、处理事件等内容,AWT是Java语言进行GUI程序设计的基础。 2、javax.swing包Swing包是Java基础类库(Java Foundation Classes,JFC)的一部分。Swing提供了从按钮到可分拆面板和表格的所有组件。,Swing组件是Java语言提供的第二代GUI设计工具包,它以AWT为基础,在AWT内容的基础上新增或改进了一些GUI组件,使得GUI程序功能更
2、强大,设计更容易、更方便。“Swing“是开发新组件的项目代码名,现在,这个名字常用来引用新组件和相关的API。 AWT组件和对应的Swing组件,从名称上很容易记忆和区别。例如,AWT的框架类、面板类、按钮类和菜单类,被命名为Frame、Panel、Button和Menu。 而Swing对应的组件类被命名为JFrame、JPanel、JButton和JMenu。与AWT组件相比,Swing组件的名前多一个 “J” 字母。另外,AWT 组件在java.awt包中,而Swing组件在javax.swing包中。,3、Java Swing GUI应用程序中的基本步骤: (1)引入合适的包和类 一般
3、的Swing GUI应用程序应包含程序中的前三个引入语句,它们分别表示引入awt包、awt事件处理包和swing包。其他包按需引入。 由于Swing组件使用AWT的结构,包括AWT的事件驱动模式,所以,使用swing组件的程序一般需要使用awt包。 (2)使用缺省的观感或设置自己的观感(Look and Feel) (3)设置一个顶层的容器 (4)根据需要,使用缺省的布局管理器或设置另外的布局管理器 (5)定义组件并将它们添加到容器 (6)对组件或事件编码,9.1.2 容器、组件、布局和观感 1、容器(Container)和组件(Component) 一个Java的图形用户界面的最基本元素是组
4、件,组件是可以以图形化的方式显示在屏幕上并能与用户进行交互的对象,如一个按钮、一个文本框等。在Java语言中,通常将组件放在一定的容器内使用。 容器实际上是一种具有容纳其他组件和容器的功能的组件。抽象类Container是所有容器的父类,其中包含了很多有关容器的功能和方法。而Container类又是Java语言的组件类Component的子类。,组件,两种主要类型的容器是:窗口和面板 窗口是一个在显示屏上自由移动的窗口。 面板是 GUI 组件的一个容器,它必须在某些其他容器的环境中存在,如窗口或 Applet。 使用add() 方法添加组件。 Java 编程语言支持各种组件,如: Button
5、 Choice Label List Scrollbar TextComponent 等。 容器中组件的位置和大小是由布局管理器决定的。 必须对组件使用 setLocation()、setSize()或 setBounds()以在容器中找到它们。,2、布局管理器(Layout Manager) 为了使得图形用户界面具有良好的平台无关性,在Java语言中提供了布局管理器这个工具来管理组件在容器中的布局,而不使用直接设置组件位置和大小的方式。容器中的组件定位由布局管理器决定。每个容器都有一个缺省的布局管理器,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其相应的布局管理器。但也可以不用缺
6、省的布局管理器,在程序中指定其新的布局管理器。 Java平台提供多种布局管理器,常用的有FlowLayout、BorderLayout、GridLayout、CardLayout、BoxLayout和GridBagLayout等。 使用不同的布局管理器,组件在容器上的位置和大小都是很不一样的。,3、观感(Look and Feel) Java swing的一个重要特征是它的可插入的“观感”体系。一个Swing应用程序或一个最终用户可指明所需要的观感,使得Swing应用程序的外观和行为都可以被定制。Swing运行一个缺省的Java观感(也称为Metal观感),还实现了模仿Motif和Window
7、s的观感。这样,一个Swing程序可拥有Java程序的独特外观,也可以拥有熟悉的Windows操作系统外观。 在下面的四个图中分别显示了Windows、Motif、Metal和Nimbus四种观感。 一般在应用程序的Frame的构造方法中或在Applet的init方法中进行观感的设置。,Windows观感,Motif观感,Java(Metal)观感,Nimbus观感,9.1.3 事件处理 在一个GUI程序中,为了能够接收用户的输入、命令的按键和鼠标操作,程序系统首先应该能够识别这些操作并做出相应的响应。通常一个键盘和鼠标操作将引发一个系统预先定义好的事件,用户程序只要编写代码定义每个事件发生时
8、程序应做出何种响应即可。这些代码会在它们对应的事件发生时由系统自动调用,这就是GUI程序中事件和事件响应的基本原理。 在Java语言中,除了键盘和鼠标操作,系统的状态改变也可以引发事件。,可能产生事件的组件称为事件源,不同事件源上发生的事件种类是不同的。若希望事件源上引发的事件被程序处理,需要将事件源注册给能够处理该事件源上那种事件类型的监听器。监听器具有监听和处理某类事件的功能,它可以是包容事件源的容器,也可以是另外的对象。也就是说,事件源和事件处理是分开的,一般组件都不处理自己的事件,而将事件处理委托给外部的处理实体,这种事件处理模型称为授权处理模型。 事件的行为多种多样,由不同的监听器处
9、理。编写事件处理程序首先应确定关注的事件属于何种监听器类型。,在AWT中,提供11种标准的监听器类型,见表9.1。,在确定监听器类型后,要用事件源类的注册方法来注册一个监听器类的对象。这样,事件源产生的事件会传送给已注册的处理该类事件的监听器对象,该对象将自动调用相应的事件处理方法来处理该事件。具体的注册方法是:用监听器类的对象作为参数调用事件源本身的addXxxListener()方法。该方法的参数是一个监听器类的对象,有多种形式。例如: (1)分离的监听器类,该类通常为继承相应事件适配器类的子类,类中包含了事件处理方法。参数是该类的一个对象。 (2)实现监听器接口,参数为this,表示本对
10、象就是一个监听器类的对象。在本类中包含事件处理方法。 (3)有名内部类,参数形式为继承事件适配器类的子类对象,在子类中包含事件处理方法。 (4)匿名内部类,参数形式为用new开始的一个无名的类定义。其中包含事件处理方法。,9. 2 框架与面板 Frame(框架)有以下特性: 它们是 Window 的子类 具有标题和重调大小的角 最初是看不见的,使用 setVisible(true) 可以显示框架 具有如缺省布局管理器一样的 BorderLayout 使用 setLayout() 方法更改缺省布局管理器 Panel(面板)为组件提供一个空间。 使子面板能够具有自己的布局管理器。 创建面板之后,它
11、必须被添加到窗口或框架中。 现行Java中GUI编程:使用Swing组件。当前一般使用JFrame和JPanel。,创建框架的示例:,声明框架容器对象,初始化框架对象,设置框架的大小,使框架可见,import java.awt.*; public class FrameExample private Frame f;public FrameExample() f = new Frame(“Hello Out There!“); public void launchFrame() f.setSize(170,170);f.setBackground(Color.blue);f.setVisibl
12、e(true); public static void main(String args) FrameExample guiWindow = new FrameExample();guiWindow.launchFrame(); ,面板(续),以下代码段帮助您创建一个小的黄色面板,并将它添加到框架中: public Panel pan; public Frame f; f=new Frame( “Im with panel”); pan = new Panel(); public void launchFrame() f.setSize(200,200);f.setLayout(null);
13、/ 使用缺省布局pan.setSize(100,100);pan.setBackground(Color.yellow);f.add(pan);f.setVisible(true); ,声明面板对象,初始化面板对象,设置面板的大小,为面板指定黄色,将面板添加到框架,9.3 布局管理器,在容器中所有组件的布局(位置和大小)由布局管理器来控制。在Java语言中提供了FlowLayout、BorderLayout、GridLayout、CardLayout和GridBagLayout等多种布局管理器。 缺省地,Panel使用FlowLayout,而Applet、Dialog和Frame等使用Bord
14、erLayout。如果不希望使用缺省的布局管理器,则可使用所有容器的父类Container的setLayout方法来改变缺省的布局管理器。,窗口、框架和对话框类的缺省布局管理器是BorderLayout。 同样,面板和 Applet 的缺省布局管理器是 FlowLayout。,FlowLayout 的一个简单示例: public class LayoutExample private Frame f; private Button b1; private Button b2; public LayoutExample() f = new Frame(“GUI example“); b1 = n
15、ew Button(“Press Me“); b2 = new Button(“Dont press Me“); public void launchFrame() f.setLayout(new FlowLayout(); f.add(b1); f.add(b2); f.pack(); f.setVisible(true); public static void main(String args) LayoutExample guiWindow = new LayoutExample(); guiWindow.launchFrame(); ,初始化组件,声明组件,在框架上添加组件,设置 Fl
16、owLayout,上述代码将显示以下的输出结果:,BorderLayout 管理器具有以下特性: Frame 类的缺省布局 组件被添加到某些特定区域 重调大小的行为如下所示: 水平调整北、南和中央区域 垂直调整东、西和中央区域 使用不带有任何参数结构的构造器并在组件之间安装一个没有间隔的新的 BorderLayout:setLayout(new BorderLayout(); BorderLayout 构造器指定 hgap和 vgap可用来表明组件之间的间隔:BorderLayout(int hgap,int vgap); 组件必须被添加到 BorderLayout 管理器中已命名的区域:f.
17、add(button1,BorderLayout.NORTH);,import javax.swing.*; import java.awt.*; public class BorderLayoutExamplepublic static void main(String args)JFrame f=new JFrame();Container contentPane=f.getContentPane();/取得框架的内容窗格contentPane.add(new JButton(“North“),BorderLayout.NORTH);/将名为North的按钮添加到内容窗格中的NORTH位置
18、contentPane.add(new JButton(“South“),BorderLayout.SOUTH);contentPane.add(new JButton(“West“),BorderLayout.WEST);contentPane.add(new JButton(“East“),BorderLayout.EAST);contentPane.add(new JButton(“Center“),BorderLayout.CENTER);f.setSize(300,200);f.show(); ,GridLayout 管理器的特性是: 组件是从左到右,从上到下添加的。 所有区域的大小
19、都相等。 构造器指定行数和列数,例如: f.setLayout ( new GridLayout( 3,2); 在 Java 程序中使用该语句能够帮助您获得以下的输出结果:,import javax.swing.*; import javax.swing.border.*; public class LabelExamplepublic static void main(String args) JFrame f=new JFrame();JPanel p=new JPanel();/创建一个看起来风化形式的边框对象Border border= BorderFactory.createEtch
20、edBorder();,JLabel labText=new JLabel(“文本标签“); /显示文本 labText.setBorder(border); ImageIcon icon = new ImageIcon(“image/greenflag20.gif“); /显示图像 JLabel labImage=new JLabel(icon); labImage.setBorder(border); /设置标签边框形式JLabel labTextImage =new JLabel(“文本图象标签“, icon,SwingConstants.LEFT); /显示文本和图像labTextIm
21、age.setHorizontalTextPosition(SwingConstants.LEFT); /设置文字显示在图象的左侧 labTextImage.setBorder(border);,String htmlText=“n” + /定义HTML格式的字符串“Color and font test:n“ +“n“ +“White Colorn“ +“Red Colorn“ +“Black Colorn“ +“Small Sizen“ +“Large Sizen“ +“italicn” + /斜体“boldn” + /粗体“n“;JLabel labHTML=new JLabel(htmlText);labHTML.setBorder(border);p.add(labText);p.add(labImage);p.add(labTextImage);p.add(labHTML); f.getContentPane().add(p);f.setSize(300,250);f.show(); ,实现一个登录窗体,当点击登录按钮后,弹出第二个窗体。,