第9章 图形用户界面 (gui)

180
1 第 9 第 第第第第第第 (GUI) 第第第第第第第第

Upload: trula

Post on 05-Jan-2016

211 views

Category:

Documents


0 download

DESCRIPTION

第9章 图形用户界面 (GUI). 面向对象程序设计. 目录. 9.1 Applet 概述 9.2 Applet 应用程序接口 9.3 绘图 9.4 Swing 基础 9.5 Swing 的特点和概念 9.6 Swing 组件 9.7 其它 Swing 特性 9.8 本章小结. 9.1 Applet 概述. Java Applet 一种嵌入 HTML 文档中的 Java 程序 与 Application 相比, Applet 具有明显的优点 web 浏览器提供了运行 Applet 所需要的许多功能 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第9章  图形用户界面 (GUI)

1

第 9 章 图形用户界面 (GUI)

面向对象程序设计

Page 2: 第9章  图形用户界面 (GUI)

面向对象程序设计

2

目录

9.1 Applet 概述 9.2 Applet 应用程序接口 9.3 绘图 9.4 Swing 基础 9.5 Swing 的特点和概念 9.6 Swing 组件 9.7 其它 Swing 特性 9.8 本章小结

Page 3: 第9章  图形用户界面 (GUI)

面向对象程序设计

3

9.1 Applet 概述

Java Applet– 一种嵌入 HTML 文档中的 Java 程序– 与 Application 相比, Applet 具有明显的优点

web 浏览器提供了运行 Applet 所需要的许多功能Applet 是在运行时通过网络从服务器端下载的,因而便于

软件的发布和及时更新– Applet 也有其局限性,

不能在客户机上读写当地文件 也不能连接除它所在的服务器以外的其它机器

Page 4: 第9章  图形用户界面 (GUI)

面向对象程序设计

4

在浏览器中加载一个 Applet ,功能是显示一个字符串“ This is a Java Applet !”

import java.awt.Graphics;import javax.swing.JApplet; public class Ex9_1 extends JApplet{ public void paint(Graphics g) { // 重载 JApplet 类的

paint 方法 // 参数是 Graphics 类的对象,是由浏览器传递过来的 super.paint(g); // 调用其超类 JApplet 类的 paint 方法 g.drawString("This is a Java Applet!",25,25); } }

9.1 Applet 概述 ( 续 ) ——例 9_1

Ap

ple

t

概述

Page 5: 第9章  图形用户界面 (GUI)

面向对象程序设计

5

在 Eclipse IDE 中运行

9.1 Applet 概述 ( 续 ) ——例 9_1 运行结果

Ap

ple

t

概述

Page 6: 第9章  图形用户界面 (GUI)

面向对象程序设计

6

编译 ex9_1.java 产生字节码文件 ex9_1.class 。接下来就需要编写一个 HTML 文件 ex9_1.html 来嵌入 ex9_1.class<html><applet code="Ex9_1.class" width="300"

height="45"></applet></html>

将 ex9_1.html 文件和 Ex9_1.class 文件放在同一个目录下。现在,在浏览器中打开这个 HTML 文件,当浏览器遇到 Applet 标记时,就会自动载入指定的 class 文件,就会实现在屏幕上绘制一串字符的效果

9.1 Applet 概述 ( 续 ) ——例 9_1 运行结果

Ap

ple

t

概述

Page 7: 第9章  图形用户界面 (GUI)

面向对象程序设计

7

9.2 Applet 应用程序接口

JApplet 类– 一个 applet 程序需要继承 javax.swing 包中的

JApplet 类,也可以继承老的 AWT 组件中的 Applet类, JApplet 类属于新的 Swing 组件

– 提供了 applet 在浏览器中运行需要具备的特定方法 浏览器载入时,要依次运行 init、 start、 paint

方法 离开浏览器页面时,执行 stop 退出浏览器时,执行 destroy

– 提供了所有这些方法的默认实现,所以我们在编写自己的 applet 时,就可以不必写出全部方法,只要继承这个 JApplet ,然后重写特定的方法来增加特殊功能

Page 8: 第9章  图形用户界面 (GUI)

面向对象程序设计

8

9.2 Applet应用程序接口

j ava. l ang. Obj ect j ava. awt. Component j ava. awt. Contai ner j ava. awt. Panel j ava. appl et. Appl et j avax.swing. JApplet

方法 调用时机和用途public void init()

当浏览器(即 Applet容器)载入某个Applet时,容器会自动创建这个 Applet类的一个实例,并调用它的 init方法

Ap

ple

t

应用程序接口

Page 9: 第9章  图形用户界面 (GUI)

面向对象程序设计

9

public void start() init方法执行结束之后,自动调用这个方法。另外,当浏览器用户在访问另一个网址之后重新返回 applet所在的HTML页时,将再次调用 start方法

public void paint(Graphics g)

start方法启动后调用此方法,另外每次需要重绘 applet时也将调用该方法。程序通常不直接调用 paint

public void repaint()

在响应用户和 Applet的交互时经常要用到。通常只是调用,而不重写这个方法。对于轻量级组件,它调用组件的 paint方法,对重量级组件它调用组件的 update方法,由 update调用 paint

public void stop() 用户离开 Applet所在的HTML页时调用该方法 ,它执行挂起 Applet所需的所有任务,例如停止动画和线程

public void destroy()

用户关闭浏览器窗口, Applet将从内存中移走的时候调用该方法

9.2 Applet应用程序接口( 续 )

Ap

ple

t

应用程序接口

Page 10: 第9章  图形用户界面 (GUI)

面向对象程序设计

10

import javax.swing.*;.import java.awt.*;

public class HelloSwingApplet extends JApplet { public void init() { JLabel label = new JLabel( "You are successfully running a Swing

applet!"); label.setHorizontalAlignment(JLabel.CENTER);

label.setBorder(BorderFactory. createMatteBorder(1,1,2,2,Color.black)); getContentPane().add(label,

BorderLayout.CENTER); }}

9.2 Applet应用程序接口( 续 ) ——HelloSwingApplet.java

Ap

ple

t

应用程序接口

Page 11: 第9章  图形用户界面 (GUI)

面向对象程序设计

11

9.3 绘图

图形环境和图形对象 颜色和字体 使用 Graphics 类绘图 使用 Graphics2D 类绘图

Page 12: 第9章  图形用户界面 (GUI)

面向对象程序设计

12

9.3.1 图形环境和图形对象

坐标– GUI 组件的左上角坐标默认为( 0 , 0 )– 从左上角到右下角,水平坐标 x 和垂直坐标 y 增加。– 坐标的单位是象素

Graphics 对象– Graphics 对象是专门管理图形环境的。 Graphics 类是一个

抽象类– 设计一个抽象类 Graphics 可以给程序员提供一个与平台无关

的绘图接口,因而程序员就可以以独立于平台的方式来使用图形。在各个平台上实现的 Java 系统将创建 Graphics 类的一个子类,来实现绘图功能,但是这个子类对程序员是透明的,也就是说我们只能看得到 Graphics 类,却不必关心其实现

– 在执行 paint 方法时,系统会传递一个指向特定平台的Graphics 子类的图形对象 g

Page 13: 第9章  图形用户界面 (GUI)

面向对象程序设计

13

9.3.2 颜色和字体

Java 中有关颜色的类是 Color 类,它在 java.awt 包中,这个类声明了用于操作 Java 程序中颜色的方法和常量

名称 描述public final static Color

GREEN 常量绿色

public final static Color RED 常量红色public Color(int r,int g,int b) 通过指定红、蓝、绿颜色分量

( 0 ~ 255),创建一种颜色public int getRed() 返回某颜色对象的红色分量值

(0~ 255)

Graphics: public void setColor(Color c)

Graphics类的方法,用于设置组件的颜色

Graphics: public Color getColor()

Graphics类的方法,用于获得组件的颜色

Page 14: 第9章  图形用户界面 (GUI)

面向对象程序设计

14

9.3.2 颜色和字体 Font类——有关字体控制,在 java.awt 包中

名称 描述public final static int

PLAIN一个代表普通字体风格的常量

public final static int BOLD

一个代表黑体字体风格的常量

public final static int ITALIC

一个代表斜体字体风格的常量

public Font(String name,int style,int size)

利用指定的字体、风格和大小创建一个 Font对象

public int getStyle() 返回一个表示当前字体风格的整数值public Boolean isPlain() 测试一个字体是否是普通字体风格Graphics: public Font

getFont()获得当前字体

Graphics: public void setFont(Font f)

设置当前字体为 f 指定的字体、风格和大小

Page 15: 第9章  图形用户界面 (GUI)

面向对象程序设计

15

9.3.3 使用 Graphics 类绘图

Graphics 类– 其对象可以绘制文本、线条、矩形、多边形、椭圆、弧等多种图

名称 描述public void

drawString(String str, int x, int y)

绘制字符串,左上角的坐标是( x,y)

public void drawLine(int x1, int y1, int x2, int y2)

在 (x1,y1)与 (x2,y2)两点之间绘制一条线段

public void drawRect(int x, int y, int width, int height)

用指定的width和 height绘制一个矩形,该矩形的左上角坐标为(x,y)

public void fillRect(int x, int y, int width, int height)

用指定的width和 height绘制一个实心矩形,该矩形的左上角坐标为 (x,y)

Page 16: 第9章  图形用户界面 (GUI)

面向对象程序设计

16

public void clearRect(int x, int y, int width, int height)

用指定的width和 height,以当前背景色绘制一个实心矩形。该矩形的左上角坐标为( x,y)

public void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

用指定的width和 height绘制一个圆角矩形,圆角是一个椭圆的 1/4弧,此椭圆由arcWidth、 arcHeight确定两轴长。其外切矩形左上角坐标为( x,y)

public void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight)

用当前色绘制实心圆角矩形,各参数含义同drawRoundRect。

public void draw3DRect(int x, int y, int width, int height, boolean b)

用指定的width和 height绘制三维矩形,该矩形左上角坐标是 (x,y), b 为 true时,该矩形为突出的, b 为 false时,该矩形为凹陷的。

public void fill3DRect(int x, int y, int width, int height, boolean b)

用当前色绘制实心三维矩形,各参数含义同draw3DRect。

9.3.3 使用 Graphics 类绘图

Page 17: 第9章  图形用户界面 (GUI)

面向对象程序设计

17

public void drawPolygon(int[] xPoints, int [] yPoints, int nPoints)

用 xPoints, yPoints数组指定的点的坐标依次相连绘制多边形,共选用前nPoints个点。

public void fillPolygon(int[] xPoints, int [] yPoints, int nPoints)

绘制实心多边形,各参数含义同drawPolygon。

public void drawOval(int x, int y, int width, int height)

用指定的width和 height,以当前色绘制一个椭圆,外切矩形的左上角坐标是 (x,y)。

public void fillOval(int x, int y, int width, int height)

绘制实心椭圆,各参数含义同drawOval。

public void drawArc(int x, int y,int width, int height, int startAngle, int arcAngle)

绘制指定width和 height的椭圆,外切矩形左上角坐标是 (x,y),但只截取从 startAngle开始,并扫过arcAngle度数的弧线。

public void fillArc(int x, int y,int width, int height, int startAngle, int arcAngle)

绘制一条实心弧线(即扇形),各参数含义同 drawArc

9.3.3 使用 Graphics 类绘图

Page 18: 第9章  图形用户界面 (GUI)

面向对象程序设计

18

用各种颜色绘制文字及各种图形import java.awt.*;

import javax.swing.*;

public class Ex9_2 extends JFrame {

public Ex9_2() {

super( “ 演示字体、颜色、绘图” ); // 调用基类构造方法 setSize( 480, 250 ); // 设置窗口大小 setVisible( true ); // 显示窗口}

public void paint( Graphics g ) {

super.paint( g ); // call superclass's paint method

g.setFont( new Font( "SansSerif", Font.BOLD, 12 ) );

g.setColor(Color.blue); // 设置颜色 g.drawString(" 字体 ScanSerif ,粗体, 12号,蓝色 ",20,50);

9.3.3 使用 Graphics 类绘图( 续 ) ——Ex9_2.java

Page 19: 第9章  图形用户界面 (GUI)

面向对象程序设计

19

g.setFont( new Font( "Serif", Font.ITALIC, 14 ) ); g.setColor(new Color(255,0,0)); g.drawString( " 字体 Serif ,斜体, 14号,红色 ", 250, 50 ); g.drawLine(20,60,460,60); // 绘制直线 g.setColor(Color.green); g.drawRect(20,70,100,50); // 绘制空心矩形 g.fillRect(130,70,100,50); // 绘制实心矩形 g.setColor(Color.yellow); g.drawRoundRect(240,70,100,50,50,50); // 绘制空心圆角矩

形 g.fillRoundRect(350,70,100,50,50,50); // 绘制实心圆角矩形 g.setColor(Color.cyan); g.draw3DRect(20,130,100,50,true); // 绘制突起效果空心矩形 g.fill3DRect(130,130,100,50,false); // 绘制凹陷效果实心矩形

9.3.3 使用 Graphics 类绘图( 续 ) ——Ex9_2.java

Page 20: 第9章  图形用户界面 (GUI)

面向对象程序设计

20

g.setColor(Color.pink); g.drawOval(240,130,100,50); // 绘制空心椭圆 g.fillOval(350,130,100,50); // 绘制实心椭圆 g.setColor(new Color(0,120,20)); g.drawArc(20,190,100,50,0,90); // 绘制一段圆弧 g.fillArc(130,190,100,50,0,90); // 绘制扇形 g.setColor(Color.black); int xValues[]={250,280,290,300,330,310,320,290,260,270}; int yValues[]={210,210,190,210,210,220,230,220,230,220}; g.drawPolygon(xValues,yValues,10); // 绘制空心多边形 int xValues2[]={360,390,400,410,440,420,430,400,370,380}; g.fillPolygon(xValues2,yValues,10); // 绘制实心多边形 }

9.3.3 使用 Graphics 类绘图( 续 ) ——Ex9_2.java

Page 21: 第9章  图形用户界面 (GUI)

面向对象程序设计

21

public static void main( String args[] ) { JFrame.setDefaultLookAndFeelDecorated(true); // 设置窗口的外观感觉为 Java 默认 Ex9_2 application = new Ex9_2();

application.setDefaultCloseOperation(JFrame.EXIT_ON_CL

OSE ); }} 运行结果

9.3.3 使用 Graphics 类绘图( 续 ) ——Ex9_2.java 运行结果

Page 22: 第9章  图形用户界面 (GUI)

面向对象程序设计

22

9.3.4 使用 Graphics2D 类绘图

Java2D API– 提供了高级的二维图形功能– 分布在 java.awt、 java.awt.image、 java.awt.color、

java.awt.font、 java.awt.geom、 java.awt.print和java.awt.image.renderable 包中

– 它能轻松使你完成以下功能: 绘制任何宽度的直线 用渐变颜色和纹理来填充图形 平移、旋转、伸缩、切变二维图形,对图像进行模糊、锐化

等操作 构建重叠的文本和图形

Page 23: 第9章  图形用户界面 (GUI)

面向对象程序设计

23

Graphics2D 类– 要想使用 Java2D API ,就必须通过一个该类的对象– 是Graphics 类的抽象子类– 事实上,所有的 paint 方法用于绘图操作的对象实际上是

Graphics2D 的一个子类实例,该实例传递给 paint 方法,并被向上转型为 Graphics 类的实例。要访问Graphics2D 功能,必须使用如下语句将传递给 paint 方法的 Graphics引用强制转换为 Graphics2D引用:Graphics2D g2d=(Graphics2D)g

9.3.4 使用 Graphics2D 类绘图 ( 续 )

Page 24: 第9章  图形用户界面 (GUI)

面向对象程序设计

24

实现例 9_1 的功能,使用 Java2D 使文字出现渐变色效果import java.awt.*;import javax.swing.*;public class Ex9_3 extends JApplet{ public void paint(Graphics g) { super.paint(g); Graphics2D g2d=(Graphics2D)g; g2d.setPaint(new GradientPaint(0,0,Color.red,180,45,Color.yellow)); g2d.drawString("This is a Java Applet!",25,25); }}

9.3.4 使用 Graphics2D 类绘图 ( 续 ) ——Ex9_3.java

Page 25: 第9章  图形用户界面 (GUI)

面向对象程序设计

25

9.3.4 使用 Graphics2D 类绘图 ( 续 ) ——Ex9_3.java 运行结果

Page 26: 第9章  图形用户界面 (GUI)

面向对象程序设计

26

9.4 Swing 基础

前面介绍了如何在屏幕上绘制普通的图形,但如果需要绘制一个按钮,并使其可以对点击事件作出响应,就需要使用 java Swing 提供的组件

其实前面我们已经用到的 JFrame、 JApplet都是Swing 组件,它们分别代表窗口组件和 Applet容器组件

Page 27: 第9章  图形用户界面 (GUI)

面向对象程序设计

27

9.4.1 JFC与 Swing

JFC– Java Foundation Classes( Java 基础类)的缩写– 是关于 GUI 组件和服务的完整集合– 作为 J2SE 的一个有机部分,主要包含 5 个部分

AWT( Abstract Window Toolkit) Java2DAccessibilityDrag & DropSwing

Swing– JFC 的一部分– 提供按钮、窗口、表格等所有的组件– 纯 Java 组件(完全用 Java 写的)

Sw

ing

基础

Page 28: 第9章  图形用户界面 (GUI)

面向对象程序设计

28

9.4.2 Swing与 AWT

早期版本的 AWT 组件– 在 java.awt 包里,包括Button、Checkbox、

Scrollbar 等,都是 Component 类的子类– 大部分含有 native code( 本地代码,在

Windows 中,要 Dll支持),所以随操作系统平台的不同会显示出不同的样子,而不能进行更改,是重量级组件 (heavyweight components)

– 没有弹性、缺乏效率

Sw

ing

基础

Page 29: 第9章  图形用户界面 (GUI)

面向对象程序设计

29

较新的 Swing 组件– 其名称都是在原来 AWT 组件名称前加上 J,例如

JButton、 JCheckBox、 JScrollbar 等,都是JComponent 类的子类

– Java1.2推出,架构在 AWT 之上,是 AWT 的扩展而不是取代– 完全是由 java语言编写的,其外观和功能不依赖于任何由宿主平

台的窗口系统所提供的代码,是轻量级组件( lightweight

components )– 可提供更丰富的视觉感受,被越来越多地使用

9.4.2 Swing与 AWT

Sw

ing

基础

Page 30: 第9章  图形用户界面 (GUI)

面向对象程序设计

30

在 Applet 中应用 Swing ,就是要将 Swing 组件加载到 Applet容器上(通常是 JApplet ),这通常在init 方法中完成

在 Application 中应用 Swing ,也是要将 Swing 组件加载到这个 Application 的顶层容器(通常是JFrame )中

9.4.3 在 Applet和Application 中应用 Swing

Sw

ing

基础

Page 31: 第9章  图形用户界面 (GUI)

面向对象程序设计

31

应用 Swing 组件的 Appletimport java.awt.*;import java.awt.event.*;import javax.swing.*;public class Ex9_4 extends JApplet{ public void init() { Container contentPane=getContentPane(); contentPane.setLayout(new GridLayout(2,1)); JButton button=new JButton("Click me"); final JLabel label=new JLabel(); contentPane.add(button); contentPane.add(label); button.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent event) { String information=JOptionPane.showInputDialog(“请

输入一串字符 "); label.setText(information); } } );/ / 创建监听器语句结束 }//init 方法结束 }

9.4.3在 Applet和 Application中应用 Swing (续 ) ——Ex9_4.java

Sw

ing

基础

Page 32: 第9章  图形用户界面 (GUI)

面向对象程序设计

32

9.4.3在 Applet和 Application 中应用 Swing (续 ) ——Ex9_4.java 运行结果

Sw

ing

基础

Page 33: 第9章  图形用户界面 (GUI)

面向对象程序设计

33

把 JApplet换成 JFrame ,将例9-4 的程序改为 Applicationimport javax.swing.*;import java.awt.event.*;import java.awt.*;public class Ex9_5{ public static void main(String[] args){ JFrame f=new JFrame(“Simple Swing Application”); Container contentPane=f.getContentPane(); contentPane.setLayout(new GridLayout(2,1)); JButton button=new JButton("Click me"); final JLabel label=new JLabel(); contentPane.add(button);//添加按钮 contentPane.add(label);//添加标签 button.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent event) { String information=JOptionPane.showInputDialog("请输入一串字符 ");

label.setText(information); } } ); f.setSize(200,100);// 设置大小 f.show();// 显示 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }}

9.4.3在 Applet和 Application 中应用 Swing (续 ) ——Ex9_5.java

Sw

ing

基础

Page 34: 第9章  图形用户界面 (GUI)

面向对象程序设计

34

9.4.3在 Applet和 Application 中应用 Swing (续 ) ——Ex9_5.java 运行结果

Sw

ing

基础

Page 35: 第9章  图形用户界面 (GUI)

面向对象程序设计

35

9.5 Swing 的特点和概念

Swing GUI 组件– javax.swing 包– 源于 AWT( package java.awt )的组件– 包括外观感觉

外观以及用户如何和程序交互– 轻量级组件

完全用 Java 写成,不是用当前平台的 GUI 功能– 某些 Swing 组件也是重量级的,外观和功能受到本地窗口系统的限制,如

java.awt.Windows 的子类 java.applet.Applet 的子类

Page 36: 第9章  图形用户界面 (GUI)

面向对象程序设计

36

9.5.1 Swing 的组件和容器层次

绝大多数 Swing 组件的继承层次

java.lang.Object

java.awt.Component

java.awt.Container

javax.swing.JComponent

Sw

ing

的特点和概念

Page 37: 第9章  图形用户界面 (GUI)

面向对象程序设计

37

9.5.1 Swing 的组件和容器层次( 续 )

JComponent 类是除了顶层容器以外所有 Swing 组件的基类,根据继承关系,我们可以在每个基类中找到大多数 GUI 组件的常见操作– Component 类

包含 paint、 repaint 方法,可以在屏幕上绘制组件大多数 GUI 组件直接或间接扩展 Component

– Container 类容纳相关组件 包括 add 方法,用来添加组件 包括 setLayout 方法,这个方法可用来设置布局,以帮助 Container 对象对其中的组件进行定位和设置组件大小

– JComponent 类——多数 Swing 组件的超类 可抽换的外观感觉,即可根据需求定制外观和感觉。快捷键 ( 通过键盘直接访问GUI 组件 ) 一般的事件处理功能

Sw

ing

的特点和概念

Page 38: 第9章  图形用户界面 (GUI)

面向对象程序设计

38

通常将 javax.swing 包里的 Swing 组件归为三个层次– 顶层容器 (Top-level containers)– 中间层容器 (intermediate container )– 原子组件 (Atom Component)

9.5.1 Swing 的组件和容器层次( 续 )

Sw

ing

的特点和概念

Page 39: 第9章  图形用户界面 (GUI)

面向对象程序设计

39

顶层容器– Swing 提供三个顶层容器的类

JFrame 实现单个主窗口JDialog 实现一个二级窗口 ( 对话框 )JApplet 在浏览器窗口中实现一个 applet

显示区域– 必须和操作系统打交道,所以都是重量级组件– 从继承结构上来看,它们分别是从原来 AWT 组

件的 Frame、Dialog和 Applet 类继承而来– 每个使用 Swing 组件的 Java 程序都必须至少

有一个顶层容器,别的组件都必须放在这个顶层容器上才能显现出来

9.5.1 Swing 的组件和容器层次( 续 ) ——顶层容器

Sw

ing

的特点和概念

Page 40: 第9章  图形用户界面 (GUI)

面向对象程序设计

40

中间层容器– 其存在的目的仅仅是为了容纳别的组件– 分为两类

一般用途的– JPanel– JScrollPane– JSplitPane– JTabbedPane– JToolBar

特殊用途的– JInternalFrame– JRootPane

– 可以直接从顶层容器中获得一个 JRootPane 对象来直接使用,而别的中间容器使用的时候需要新建一个对象

9.5.1 Swing 的组件和容器层次( 续 ) —— 中间层容器

Sw

ing

的特点和概念

Page 41: 第9章  图形用户界面 (GUI)

面向对象程序设计

41

原子组件– 通常是在图形用户界面中和用户进行交互的组件– 基本功能是和用户交互信息,而不像前两种组件那样是用来容纳别的组件的

– 根据功能的不同,可被分为三类 显示不可编辑信息的

JLabel、 JProgressBar、 JToolTip

有控制功能、可以用来输入信息的JButton、 JCheckBox、 JRadioButton、 JComboBox、 JList、 JMenu、 JSlider、 JSpinner、JTexComponent 等

能提供格式化的信息并允许用户选择的 JColorChooser、JFileChooser、 JTable、 JTree

9.5.1 Swing 的组件和容器层次( 续 ) ——原子组件

Sw

ing

的特点和概念

Page 42: 第9章  图形用户界面 (GUI)

面向对象程序设计

42

三层容器结构示例import javax.swing.*;import java.awt.*;public class Ex9_6{ public static void main(String[] args){ JFrame.setDefaultLookAndFeelDecorated(true); JFrame frame=new JFrame("Swing Frame"); Container contentPane=frame.getContentPane(); JPanel panel=new JPanel();

panel.setBorder(BorderFactory.createLineBorder(Color.black,5));

9.5.1 Swing 的组件和容器层次( 续 ) ——例 9_6

Sw

ing

的特点和概念

Page 43: 第9章  图形用户界面 (GUI)

面向对象程序设计

43

panel.setLayout(new GridLayout(2,1)); JLabel label=new

JLabel("Label",SwingConstants.CENTER); JButton button=new JButton("Button"); panel.add(label); panel.add(button); contentPane.add(panel); frame.pack();// 对组件进行排列 frame.show();// 显示

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}}

Page 44: 第9章  图形用户界面 (GUI)

面向对象程序设计

44

程序说明– 首先创建一个 JFrame 类顶级容器– 然后获得顶级容器的内容面板 contentPane ,只有通过它才能加入

其他组件。– 然后创建一个 JPanel 类的中间容器 panel ,并设置边框以及布局– 然后创建原子组件 Label, button ,并将它们添加到中间容器上– 然后将中间容器通过内容面板添加到顶层容器上,并 /对组件进行排列

9.5.1 Swing 的组件和容器层次 ( 续 ) ——例 9_6 运行结果

Sw

ing

的特点和概念

Page 45: 第9章  图形用户界面 (GUI)

面向对象程序设计

45

9.5.1 Swing 的组件和容器层次( 续 ) ——Swing 组件列表

Box BoxLayout JButton

JCheckBox JCheckBoxMenuItem JComboBox

JComponent JDesktopPane JDialog

JEditorPane JFrame JInternalFrame

JLabele JLayeredPane JList

JMenu JMenuBar JRadioButtonMenuItem

JRootPane JScrollBar JScrollPane

JSeparator JSlider JSplitPane

JTabbedPane JTable JTextArea

JTextField JTextPane JToggleButton

JToolBar JToolTip JTree

JViewport JMenuItem JOptionPane

JPasswordField JPopupMenu JProgressBar

JRadioButton JWindow OverlayLayout

ProgressMonitor ProgressMonitorInputStream Timer

UIDefaults UIManager

Sw

ing

的特点和概念

Page 46: 第9章  图形用户界面 (GUI)

面向对象程序设计

46

9.5.2 布局管理 如何将下级组件有秩序地摆在上一级容器中

– 在程序中具体指定每个组件的位置 ( 需手工计算或需 Viusal 插件)

– 使用布局管理器( Interface LayoutManager )

布局管理器– 使用方法是通过调用容器对象的 setLayout 方法,并以某种布局

管理器对象为参数,例如:Container contentPane = frame.getContentPane();

contentPane.setLayout(new FlowLayout());– 使用布局管理器可以更容易地进行布局,而且当改变窗口大小时,

它还会自动更新版面来配合窗口的大小,不需要担心版面会因此混乱

Sw

ing

的特点和概念

Page 47: 第9章  图形用户界面 (GUI)

面向对象程序设计

47

9.5.2 布局管理 ( 续 )

在 Java 中有很多实现 LayoutManager 接口的类,经常用到的有以下几个– BorderLayout– FlowLayout– GridLayout– CardLayout– GridBagLayout– BoxLayout– SpringLayout– 上一节提到的内容面板( content pane )默认使用的就是

BorderLayout ,它可以将组件放置到五个区域:东、西、南、北、中

Sw

ing

的特点和概念

Page 48: 第9章  图形用户界面 (GUI)

面向对象程序设计

48

在该例中,引用了 SUN公司提供的几个的示例程序,演示了布局管理器的使用方法和效果– BorderLayoutDemo.java 及其运行效果

BorderLayout 以将组件放置到五个区域:东、西、南、北、中

9.5.2 布局管理 ( 续 ) ——例 9_7

Sw

ing

的特点和概念

Page 49: 第9章  图形用户界面 (GUI)

面向对象程序设计

49

– FlowLayoutDemo.java

FlowLayout是 JPanel 默认使用的布局管理器,它只是简单地把组件放在一行,如果容器不是足够宽来容纳所有组件,就会自动开始新的一行

9.5.2 布局管理 ( 续 ) ——例 9_7

Sw

ing

的特点和概念

Page 50: 第9章  图形用户界面 (GUI)

面向对象程序设计

50

– GridLayoutDemo.java GridLayout 将按照其构造方法中程序员提供的行数和列数将界面分为等大的若干块,组件被等大地按加载顺序放置其中

9.5.2 布局管理 ( 续 ) ——例 9_7

Sw

ing

的特点和概念

Page 51: 第9章  图形用户界面 (GUI)

面向对象程序设计

51

– CardLayoutDemo.javaCardLayout 可以实现在一个区域出现不同的组件布局,就像在一套卡片中选取其中的任意一张一样。它经常由一个复选框控制这个区域显示哪一组组件,可通过组合框像选择卡片一样选择某一种布局

9.5.2 布局管理 ( 续 ) ——例 9_7

Sw

ing

的特点和概念

Page 52: 第9章  图形用户界面 (GUI)

面向对象程序设计

52

– GridBagLayoutDemo.javaGridBagLayout把组件放置在网格中,这一点类似于

GridLayout ,但它的优点在于不仅能设置组件摆放的位置,还能设置该组件占多少行 / 列。这是一种非常灵活的布局管理器

9.5.2 布局管理 ( 续 ) ——例 9_7

Sw

ing

的特点和概念

Page 53: 第9章  图形用户界面 (GUI)

面向对象程序设计

53

– BoxLayoutDemo.javaBoxLayout 将组件放在单一的行或列中,和

FlowLayout 不同的是,它可以考虑到组件的对齐方式,最大、最小、优选尺寸

9.5.2 布局管理 ( 续 ) ——例 9_7

Sw

ing

的特点和概念

Page 54: 第9章  图形用户界面 (GUI)

面向对象程序设计

54

– SpringDemo.java SpringLayout 是一种灵活的布局管理器。它能够精确指定组件之间

的间距。组件之间的距离通过 Spring 类的对象来表示,每个 spring有四个属性,最小值,最大值,优选值和实际值。每个组件的spring 对象集合在一起就构成了 SpringLayout.Constraints 对象

9.5.2 布局管理 ( 续 ) ——例 9_7

Sw

ing

的特点和概念

Page 55: 第9章  图形用户界面 (GUI)

面向对象程序设计

55

9.5.3 事件处理

GUI 是由事件驱动的,一些常见的事件包括:– 移动鼠标– 单双击鼠标各个按钮– 单击按钮– 在文本字段输入– 在菜单中选择菜单项– 在组合框中选择、单选和多选– 拖动滚动条– 关闭窗口– ……

Swing 通过事件对象来包装事件,程序可以通过事件对象获得事件的有关信息

Sw

ing

的特点和概念

Page 56: 第9章  图形用户界面 (GUI)

面向对象程序设计

56

9.5.3 事件处理

Event Thread gets

an event

事件线程

JLabel

Jpanel

….

Create an Event Object

Processevent()

Callback()

用户程序 系统函数系统调用

系统程序 用户函数Callback

Page 57: 第9章  图形用户界面 (GUI)

面向对象程序设计

57

The delegation model( 委托模型) Events are organized into an event hierarchy( 层次结

构). Events are delivered (or fired) by event source( 事件

由事件源传递) . Events are handled by event listeners.

The same object may be both a source and a listener or source and a client.

9.5.3 事件处理

Page 58: 第9章  图形用户界面 (GUI)

面向对象程序设计

58

9.5.3 事件处理

Page 59: 第9章  图形用户界面 (GUI)

面向对象程序设计

59

Event types and representation

an event is represented by an event object that stores attributes and provides methods to deal with the event(事件是通过事件对象来表现的 ).

Component-level events( 构件事件) - Represent user or window-system actions such as mouse click, a key press, and so on.

Semantic events(语义事件 )- Represents higher-level functions or meanings of events., for examples push a button or double-clicking a text line( 一个语义事件可能由若干个构件级事件组合而成 ).

9.5.3 事件处理

Page 60: 第9章  图形用户界面 (GUI)

面向对象程序设计

60

Event Listeners Event handling, in an applet or a regular

applications, is done by establishing listener objects and registering them with event sources. An event source delivers event by calling fixed call-back methods in registered listener objects.

addXyzListener ;register listenerremoveXyzListener ;unregister a listener

9.5.3 事件处理

Page 61: 第9章  图形用户界面 (GUI)

面向对象程序设计

61

Writing Listeners with Adapter

9.5.3 事件处理

class MouseHandler extends MouseAdapter{

MouseHandler(Click2 ap){ app = ap; } public void mousePressed(MouseEvent e){ app.doDown();

}

public void mouseReleased(MouseEvent e){ app.doUp();

} private Click2 app;}

Page 62: 第9章  图形用户界面 (GUI)

面向对象程序设计

62

Event Handling summary Decide on the exact events form the

event sources you wish to handle.

For a component-level event, write a listener by extending an adapter, for example MouseAdapter( 或KeyAdapter 及其它 )

For a semantic event, write a listener by implementing a semantic event, for example ActionHandler.

9.5.3 事件处理

Page 63: 第9章  图形用户界面 (GUI)

面向对象程序设计

63

9.5.3 事件处理

Program the call-back method in the listener to handle the desired event. public void mousePressed(MouseEvent

e){{ app.doDown(); }

Register an instance of the listener with the appropriate event source.

lb.addMouseListener(new ClickHandler(this));

Page 64: 第9章  图形用户界面 (GUI)

面向对象程序设计

64

Object

EventObject

AWTEvent

ActionEvent

AdjustmentEvent

ItemEvent

TextEvent

InvocationEvent

AncestorEvent

ComponentEvent

HierarchyEvent

InputMethodEvent

InternalFrameEvent

ContainerEvent

FocusEvent

InputEvent

PaintEvent

WindowEvent

KeyEvent

MouseEvent

MenuKeyEvent

MouseWheelEvent MenuDragMouseEvent

9.5.3 事件处理 ( 续 ) ——Swing 组件的事件对象

Sw

ing

的特点和概念

Page 65: 第9章  图形用户界面 (GUI)

面向对象程序设计

65

编写事件处理程序时,要注意三个概念– 事件源

与用户进行交互的 GUI 组件,表示事件来自于哪个组件或对象

比如要对按钮被按下这个事件编写处理程序,按钮就是事件源

– 事件监听器负责监听事件并做出响应 一旦它监视到事件发生,就会自动调用相应的事件处理

程序作出响应– 事件对象

封装了有关已发生的事件的信息例如按钮被按下就是一个要被处理的事件,当用户按下按钮时,就会产生一个事件对象。事件对象中包含事件的相关信息和事件源

9.5.3 事件处理 ( 续 ) ——事件处理机制的三个部分

Sw

ing

的特点和概念

Page 66: 第9章  图形用户界面 (GUI)

面向对象程序设计

66

程序员应完成的两项任务– 为事件源注册一个事件监听器– 实现事件处理方法

9.5.3 事件处理 ( 续 ) —— 程序员应完成的两项任务

Sw

ing

的特点和概念

Page 67: 第9章  图形用户界面 (GUI)

面向对象程序设计

67

事件源– 提供注册监听器或取消监听器的方法– 维护一个已注册的监听器列表,如有事件发生,就会通知每个已注册的监听器

一个事件源可以注册多个事件监听器,每个监听器又可以对多种事件进行相应,例如一个 JFrame事件源上可以注册

– 窗口事件监听器,响应窗口关闭窗口最大化窗口最小化

– 鼠标事件监听器,响应鼠标点击鼠标移动

9.5.3 事件处理 ( 续 ) ——事件源

Sw

ing

的特点和概念

Page 68: 第9章  图形用户界面 (GUI)

面向对象程序设计

68

事件监听器– 是一个对象,通过事件源的 add×××Listener 方法被注册到某个事件源上

– 不同的 Swing 组件可以注册不同的事件监听器– 一个事件监听器中可以包含有对多种具体事件的专用处

理方法例如用于处理鼠标事件的监听器接口

MouseListener 中就包含有对应于鼠标压下、放开、进入、离开、敲击五种事件的相应方法mousePressed、mouseReleased、mouseEnte

red、mouseExited、mouseClicked ,这五种方法都需要一个事件对象作为参数

9.5.3 事件处理 ( 续 ) ——事件监听器

Sw

ing

的特点和概念

Page 69: 第9章  图形用户界面 (GUI)

面向对象程序设计

69

通常我们用到的事件对象有– ActionEvent

发生在按下按钮、选择了一个项目、在文本框中按下回车键– ItemEvent

发生在具有多个选项的组件上,如 JCheckBox、 JComboBox

– ChangeEvent 用在可设定数值的拖曳杆上,例如 JSlider、 JProgressBar 等

– WindowEvent 用在处理窗口的操作

– MouseEvent 用于鼠标的操作

9.5.3 事件处理 ( 续 ) ——事件对象

Sw

ing

的特点和概念

Page 70: 第9章  图形用户界面 (GUI)

面向对象程序设计

70

9.5.3 事件处理 ( 续 ) ——Swing事件源可能触发的事件及对应的事件监听器

事件源 事件对象 事件监听器

JFrameMouseEventWindowEvent

MouseEventListenerWindowEventListener

AbstractButton(JButton,

JToggleButton,JCheckBox,

JRadioButton)

ActionEventItemEvent

ActionListenerItemListener

JTextFieldJPasswordField

ActionEventUndoableEvent

ActionListenerUndoableListener

JTextAreaCareEventInputMethodEven

t

CareListenerInputMethodEventListene

r

JTextPaneJEditorPane

CareEventDocumentEventUndoableEventHyperlinkEvent

CareListenerDocumentListenerUndoableListenerHyperlinkListener

Sw

ing

的特点和概念

Page 71: 第9章  图形用户界面 (GUI)

面向对象程序设计

71

JComboBoxActionEventItemEvent

ActionListenerItemListener

JListListSelectionEventListDataEvent

ListSelectionListenerListDataListener

JFileChooser ActionEvent ActionListener

JMenuItem

ActionEventChangeEventItemEventMenuKeyEventMenuDragMouseEve

nt

ActionListenerChangeListenerItemListenerMenuKeyListenerMenuDragMouseListen

er

JMenu MenuEvent MenuListener

JPopupMenu PopupMenuEvent PopupMenuListener

9.5.3 事件处理 ( 续 ) ——Swing事件源可能触发的事件及对应的事件监听器

Sw

ing

的特点和概念

Page 72: 第9章  图形用户界面 (GUI)

面向对象程序设计

72

9.5.3 事件处理 ( 续 ) ——Swing事件源可能触发的事件及对应的事件监听器

JProgressBar ChangeEvent ChangeListener

JSlider ChangeEvent ChangeListener

JScrollBar AdjustmentEvent AdjustmentListener

JTableListSelectionEventTableModelEvent

ListSelectionListenerTableModelListener

JTabbedPane ChangeEvent ChangeListener

JTreeTreeSelectionEventTreeExpansionEvent

TreeSelectionListenerTreeExpansionListener

JTimer ActionEvent ActionListener

Sw

ing

的特点和概念

Page 73: 第9章  图形用户界面 (GUI)

面向对象程序设计

73

事件监听器接口– 例如 MouseListener 是一个接口,为了在程序中创建一个鼠标

事件监听器的对象,我们需要实现其所有五个方法,在方法体中,我们可以通过鼠标事件对象传递过来的信息(例如点击的次数,坐标),实现各种处理功能

事件监听器适配器类– 有时我们并不需要对所有事件进行处理,为此 Swing 提供了一

些适配器类 ×××Adapter ,这些类含有所有 ×××Listener 中方法的默认实现(就是什么也不做),因此我们就只需编写那些需要进行处理的事件的方法。例如,如果只想对鼠标敲击事件进行处理,如果使用 MouseAdapter 类,则只需要重写mouseClicked 方法就可以了

9.5.3 事件处理 ( 续 ) ——事件监听器接口和事件监听器适配器类

Sw

ing

的特点和概念

Page 74: 第9章  图形用户界面 (GUI)

面向对象程序设计

74

实现事件监听器接口– 这种方法需要实现接口中所有的方法,对我们不需要进行处理

的事件方法,也要列出来,其方法体使用一对空的花括号 继承事件监听器适配器类

– 只需要重写我们感兴趣的事件 使用匿名内部类

– 特别适用于已经继承了某个父类(例如 Applet 程序,主类必须继承 JApplet 类或 Applet 类),则根据 java 语法规则,就不能再继承适配器类的情况,而且使用这种方法程序看起来会比较清楚明了

9.5.3 事件处理 ( 续 ) ——三种实现事件处理的方法

Sw

ing

的特点和概念

Page 75: 第9章  图形用户界面 (GUI)

面向对象程序设计

75

创建一窗口,当鼠标在窗口中点击时,在窗口标题栏中显示点击位置坐标。方法一:实现 MouseListener 接口

import java.awt.event.*; // 载入 MouseListener 类所在的包import javax.swing.*; // 载入 JFrame 所在的包public class Ex9_8_1 implements MouseListener{ JFrame f; public Ex9_8_1() { f=new JFrame(); // 新建一窗口 f.setSize(300,150); f.show();

f.addMouseListener(this); // 为窗口增加鼠标事件监听器 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mouseClicked(MouseEvent e){ f.setTitle(" 点击坐标为 ("+e.getX()+", "+e.getY } public static void main(String[] args){ new Ex9_8_1();}}

9.5.3 事件处理 ( 续 ) ——例 9_8_1

Sw

ing

的特点和概念

Page 76: 第9章  图形用户界面 (GUI)

面向对象程序设计

76

继承 MouseAdapter 类import java.awt.event.*; // 载入 MouseAdapter 所在的包import javax.swing.*; public class Ex9_8_2 extends MouseAdapter{ JFrame f; public Ex9_8_2() { f=new JFrame(); f.setSize(300,150); f.show(); f.addMouseListener(this); f.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); } public void mouseClicked(MouseEvent e){ f.setTitle(" 点击坐标为 ("+e.getX()+", "+e.getY()+")"); } public static void main(String[] args){ new Ex9_8_2();}}

9.5.3 事件处理 ( 续 ) ——例 9_8_2

Sw

ing

的特点和概念

Page 77: 第9章  图形用户界面 (GUI)

面向对象程序设计

77

方法三:使用匿名内部类import java.awt.event.*; import javax.swing.*;public class Ex9_8_3{ JFrame f; public Ex9_8_3() { f=new JFrame(); f.setSize(300,150); f.show(); f.addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e){ f.setTitle(" 点击坐标为 ("+e.getX()+", "+e.getY()+")"); } }); // 为窗口添加鼠标事件监听器语句结束 f.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } });// 为窗口添加窗口事件监听器语句结束 } public static void main(String[] args){ new Ex9_8_3(); }}

9.5.3 事件处理 ( 续 ) ——例 9_8_3

Sw

ing

的特点和概念

Page 78: 第9章  图形用户界面 (GUI)

面向对象程序设计

78

采用三种不同方法的程序,其运行效果都是一样的,当鼠标在窗口中点击的时候,窗口标题栏将出现所点位置的坐标信息

9.5.3 事件处理 ( 续 ) ——例 9_8 运行结果

Sw

ing

的特点和概念

Page 79: 第9章  图形用户界面 (GUI)

面向对象程序设计

79

9.6 Swing 组件

组件和容器– 容器层次结构

是一个以顶层容器为根的树状组件集合 为了显示在屏幕上,每个组件必须是一套容器层次结构的一

部分

– 每个组件只能放置在某个容器内一次 如果某个组件已经在一个容器中,又将它加到另外一个容器

中,这个组件就会从第一个容器中清除

Page 80: 第9章  图形用户界面 (GUI)

面向对象程序设计

80

9.6.1 顶层容器

Swing 提供了 3 个顶层容器类: JFrame JApplet

JDialog

– 都是重量级组件,分别继承了 AWT 组件Frame、 Applet和Dialog

– 每个顶层容器都有一个内容面板,通常直接或间接的容纳别的可视组件

– 可以有选择地为顶层容器添加菜单,菜单被放置在顶层容器上,但是在内容面板之外

Sw

ing

组件

Page 81: 第9章  图形用户界面 (GUI)

面向对象程序设计

81

java.lang.Object

└ java.awt.Component

└ java.awt.Container

└ java.awt.Window

└ java.awt.Frame

└ javax.swing.JFrame

每个包含 Swing 组件的主窗口都应用 JFrame 来实现

Sw

ing

组件

9.6.1 顶层容器 ( 续 ) ——JFrame 的继承结构

Page 82: 第9章  图形用户界面 (GUI)

面向对象程序设计

82

java.lang.Object└ java.awt.Component └ java.awt.Container └ java.awt.Panel └ java.awt.Applet └ javax.swing.JApplet

每个包含 Swing 组件的 Applet 都应作为 JApplet 的子类来实现

Sw

ing

组件

9.6.1 顶层容器 ( 续 ) ——JApplet 的继承结构

Page 83: 第9章  图形用户界面 (GUI)

面向对象程序设计

83

java.lang.Object

└ java.awt.Component

└ java.awt.Container

└ java.awt.Window

└ java.awt.Dialog

└ javax.swing.JDialog

要实现对话框,需要从 JDialog派生一个类

Sw

ing

组件

9.6.1 顶层容器 ( 续 ) ——JDialog 的继承结构

Page 84: 第9章  图形用户界面 (GUI)

面向对象程序设计

84

9.6.1 顶层容器 ( 续 ) ——如何获得一个顶层容器

JApplet 类的顶层容器由浏览器提供,通常我们不需要自己产生一个 JApplet 类的对象。 JFrame和 JDialog 通过构造方法进行创建

名称 描述

JFrame() 建立一个新的 JFrame,默认值是不可见的(Invisible)

JFrame(String title) 建立一个具有标题 title的 JFrame,默认值是不可见的 (Invisilble)

JApplet() 建立一个 JApplet

JDialog() 建立一个 non-moal对话框,无标题

JDialog(Dialog owner) 建立一个属于Dialog组件的对话框,为 non-modal形式,无标题

JDialog(Dialog owner, boolean modal )

建立一个属于Dialog组件的对话框,可决定modal形式,无标题

JDialog(Dialog owner, String title)

建立一个属于Dialog组件的对话框,为 non-modal形式,有标题

Sw

ing

组件

Page 85: 第9章  图形用户界面 (GUI)

面向对象程序设计

85

JDialog(Dialog owner, String title, boolean modal)

建立一个属于Dialog组件的对话框,可决定modal形式,有标题

JDialog(Frame owner)建立一个属于 Frame组件的对话框,为 non-modal形式,无标题

JDialog(Frame owner, boolean modal)

建立一个属于 Frame组件的对话框,可决定modal形式,无标题

JDialog(Frame owner, String title)

建立一个属于 Frame组件的对话框,为 non-modal形式,有标题

JDialog(Frame owner, String title, boolean modal)

建立一个属于 Frame组件的对话框,可决定modal形式,有标题

9.6.1 顶层容器 ( 续 ) ——如何获得一个顶层容器续

Sw

ing

组件

Page 86: 第9章  图形用户界面 (GUI)

面向对象程序设计

86

9.6.1 顶层容器 ( 续 ) ——FrameDemo.java

import java.awt.*;import java.awt.event.*;import javax.swing.*;public class FrameDemo { public static void main(String s[]) { JFrame frame = new JFrame("FrameDemo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JLabel emptyLabel = new JLabel(""); emptyLabel.setPreferredSize(new Dimension(175, 100)); frame.getContentPane().add(emptyLabel,

BorderLayout.CENTER); frame.pack(); frame.setVisible(true); }}

Sw

ing

组件

Page 87: 第9章  图形用户界面 (GUI)

面向对象程序设计

87

import java.awt.*;import java.awt.event.*;import javax.swing.*;public class TopLevelDemo { public static void main(String s[]) { JFrame frame = new JFrame("TopLevelDemo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JLabel yellowLabel = new JLabel(""); yellowLabel.setOpaque(true); yellowLabel.setBackground(Color.yellow); yellowLabel.setPreferredSize(new Dimension(200, 180)); JMenuBar cyanMenuBar = new JMenuBar(); cyanMenuBar.setOpaque(true); cyanMenuBar.setBackground(Color.cyan); cyanMenuBar.setPreferredSize(new Dimension(200, 20)); frame.setJMenuBar(cyanMenuBar); frame.getContentPane().add(yellowLabel, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); }}

9.6.1 顶层容器 ( 续 ) ——TopLevelDemo.java

Sw

ing

组件

Page 88: 第9章  图形用户界面 (GUI)

面向对象程序设计

88

JDialog– 必须实现对话框中的每一个组件

JOptionPane– 只要显示一段文字,或是做一些简单的选择的简单对话框– 在 javax.swing 包内– 通过使用这个类提供的一些静态方法 show×××Dialog ,就

可以产生四种简单的对话框 它们的方法参数中绝大部分 (除了输入对话框可以不指定父

窗口 ) 都需要提供一个父窗口组件 ParentComponent ,只有关闭这些简单的对话框后,才可以返回到其父窗口,也就是说,它们绝大部分都是模态的

9.6.1 顶层容器 ( 续 ) ——JOptionPane 类

Sw

ing

组件

Page 89: 第9章  图形用户界面 (GUI)

面向对象程序设计

89

9.6.2 中间层容器

中间层容器存在的目的仅仅是为了容纳别的组件,它分为两类

– 一般用途的 JPanel JScrollPane JSplitPane JTabbedPane JToolBar

– 特殊用途的 JInternalFrame JRootPane (比较特殊,它由好几个部分构成,我们可以直接从顶层容器中获得一个 JRootPane 对象来直接使用,而不需要像别的中间容器那样,使用的时候需要新建一个对象)

Sw

ing

组件

Page 90: 第9章  图形用户界面 (GUI)

面向对象程序设计

90

JRootPane 的层次结构– glassPane

默认状态下是隐藏的 可以使用 glassPane 来截获所有

要到达 JRootPane 别的部分的事件

– layeredPane 分为很多层( layer ),每层都有

一个代表层深度的整数值( Z-order ),深度值高的组件将覆盖在深度值低的组件上

contentPane 所在层的深度值是 -30000 一般我们将所有组件添加到 contentPane 上

JmenuBar– 所在层的深度值是 -30000– 是可选的,如果没

有, contentPane 就会充满整个顶层容器

9.6.2 中间层容器 ( 续 ) ——JRootPane 类

Sw

ing

组件

Page 91: 第9章  图形用户界面 (GUI)

面向对象程序设计

91

JPanel– 是一种经常使用的轻量级中间容器– 在默认状态下,除了背景色外它并不绘制任何东西– 可以很容易的为它设置边框和绘制特性,我们可以把它设置

为顶层容器 contentPane 。有效地利用 JPanel 可以使版面管理更为容易

– 可以使用布局管理器来规划它所容纳的组件的位置和大小 可以通过 setLayout 方法来改变其布局 也可以在创建一个 JPanel 对象时就为它确定某种布局方式。在

默认状态下 panel 使用 FlowLayout 布局,将各组件布局在一行

9.6.2 中间层容器 ( 续 ) ——JPanel 类

Sw

ing

组件

Page 92: 第9章  图形用户界面 (GUI)

面向对象程序设计

92

9.6.2 中间层容器 ( 续 ) ——JPanel 类常用 API

名称 说明

JPanel() 创建一个 JPanel,默认布局是 FlowLayout

JPanel(LayoutManager layout) 创建一个指定布局的 JPanel

void add(Component comp) 添加组件

void add(Component comp, int index) 把组件添加到特定位置上

int getComponentCount() 获得这个 panel里所有组件的数量

Component getComponent(int index) 获得指定序号的某个组件

Component getComponentAt(int x, int y) 获得指定位置的某个组件

void remove(Component) 移除某个组件

void removeAll() 移除所有组件

void setLayout(LayoutManager layout) 设置布局

LayoutManager getLayout() 得到现有布局

void setBorder(Border border) 设置边框

Sw

ing

组件

Page 93: 第9章  图形用户界面 (GUI)

面向对象程序设计

93

Converter.java 用到如下类,都放在 JPanelDemo 包中– ConversionPanel.java– ConverterRangeModel.java– DecimalField.java– FollowerRangeModel.java– FormattedDocument.java– Unit.java

9.6.2 中间层容器 ( 续 ) ——JPanel 示例: Converter.java

Sw

ing

组件

Page 94: 第9章  图形用户界面 (GUI)

面向对象程序设计

94

JScrollPane 容器– 当容器内要容纳的内容大于容器大小的时候,我们希望容器能够

有一个滚动条,通过拖动滑块,就可以看到更多的内容。 JScrollPane 就是能够实现这种功能的特殊容器

– 由九个部分组成,包括一个中心显示地带、四个角和四条边

9.6.2 中间层容器 ( 续 ) ——JScrollPane

Sw

ing

组件

Page 95: 第9章  图形用户界面 (GUI)

面向对象程序设计

95

9.6.2 中间层容器 ( 续 ) ——JScrollPane 常用 API

名称 说明

static int HORIZONTAL_SCROLLBAR_ALWAYS 水平滚动条策略常数:总是显示

static int HORIZONTAL_SCROLLBAR_AS_NEEDED水平滚动条策略常数:当显示内容水平区域大

于显示区域时才出现

static int HORIZONTAL_SCROLLBAR_NEVER 水平滚动条策略常数:总是不显示

static int VERTICAL_SCROLLBAR_ALWAYS 垂直滚动条策略常数:总是显示

static int VERTICAL_SCROLLBAR_AS_NEEDED垂直滚动条策略常数:当显示内容垂直区域大

于显示区域时才出现

static int VERTICAL_SCROLLBAR_NEVER 垂直滚动条策略常数:总是不显示

JScrollPane() 建立一个空的 JScrollPane对象

JScrollPane(Component view)建立一个显示组件的 JScrollPane对象,当

组件内容大于显示区域时,自动产生滚动条

Sw

ing

组件

Page 96: 第9章  图形用户界面 (GUI)

面向对象程序设计

96

9.6.2 中间层容器 ( 续 ) ——JScrollPane 常用 API

void setViewportView(Component) 设置 JscrllPane要中心地带要显示的组件

void setVerticalScrollBarPolicy(int)int getVerticalScrollBarPolicy()

设置或者读取垂直滚动条策略常数

void setHorizontalScrollBarPolicy(int)int getHorizontalScrollBarPolicy()

设置或者读取水平滚动条策略常数

void setViewportBorder(Border)Border getViewportBorder()

设置或者读取中心显示地带的边框

void setWheelScrollingEnabled(Boolean)Boolean isWheelScrollingEnabled()

设置或者读取是否随着鼠标滚轮滚动出现或隐藏滚动条,默认状态下为真

void setColumnHeaderView(Component)void setRowHeaderView(Component)

设置显示在上面的边上的组件设置显示在左面的边上的组件

void setCorner(String key,Component corner)设置要显示在指定角上的组件, key的值为图

9_18中表明的字符串之一

Component getCorner(String key) 获得指定角上的组件

Sw

ing

组件

Page 97: 第9章  图形用户界面 (GUI)

面向对象程序设计

97

9.6.2 中间层容器 ( 续 ) ——ScrollDemo2.java

Sw

ing

组件

Page 98: 第9章  图形用户界面 (GUI)

面向对象程序设计

98

JSplitPane– 可以把两个组件显示在两个显示区域内,且随着区域间分隔线的

拖动,区域内组件的大小也随之发生变动– 它允许设置水平分割或者垂直分割;也允许设置动态拖曳功能

(拖动分界线时两边组件是否会随着拖曳动态改变大小还是在拖曳结束后才改动)

– 我们通常先把组件放到 Scroll Pane 中,再把 Scroll Pane 放到Split Pane 中。这样在每部分窗口中,都可以拖动滚动条看到组件的全部内容

9.6.2 中间层容器 ( 续 ) ——JSplitPane

Sw

ing

组件

Page 99: 第9章  图形用户界面 (GUI)

面向对象程序设计

99

9.6.2 中间层容器 ( 续 ) ——JSplitPane 常用 API

名称 说明

static int HORIZONTAL_SPLIT 水平分割常数

static int VERTICAL_SPLIT 垂直分割常数

JSplitPane()创建一个 JSplitPane,以水平方向排列,两边各是一个 button,没有动态拖曳功能

JSplitPane(int newOrientation)建立一个指定分割方向的 JSplitPane,没有动态拖曳功能,参数为两个分割常数之一

JSplitPane(int newOrientation, Boolean

newContinuousLayout)

指定分割方向,并可指定是否有动态拖曳功能

JSplitPane(int newOrientation, Boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent)

指定分割方向、是否具有动态拖曳功能,和两侧组件

Sw

ing

组件

Page 100: 第9章  图形用户界面 (GUI)

面向对象程序设计

100

9.6.2 中间层容器 ( 续 ) ——JSplitPane 常用 API

JSplitPane(int newOrientation,Component newLeftComponent, Component newRightComponent)

指定分割方向和两侧组件,无自动拖曳功能

void setOrientation(int newOrientation)int getOrientation()

设置或获得分割方向

void setDividerSize(int)int getDividerSize()

设置或读取分隔线条的粗细

void setContinuousLayout(boolean nCL)boolean isContinuousLayout()

设置或读取是否使用动态拖曳功能

void setOneTouchExpandable(Boolean oTE)

boolean is OneTouchExpandable()

设置或读取是否在分隔线上显示一个控键来完全扩展和完全压缩单侧内容。

void remove(Component comp)void add(Component comp)

删除或添加组件。只可以添加两个组件

void setDividerLocation(double)void setDividerLocation(int)int getDividerLocation()

设置或读取分隔线条的位置。设置参数可以是double型的百分数,也可以是 int型的象素值

Sw

ing

组件

Page 101: 第9章  图形用户界面 (GUI)

面向对象程序设计

101

import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import java.util.*;public class SplitPaneDemo implements ListSelectionListener { private Vector imageNames; private JLabel picture; private JList list; private JSplitPane splitPane; public SplitPaneDemo() { ResourceBundle imageResource; try { //Read image names from a properties file imageResource = ResourceBundle.getBundle("imagenames"); String imageNamesString = imageResource.getString("images"); imageNames = parseList(imageNamesString); } catch (MissingResourceException e) { System.exit(1); }

9.6.2 中间层容器 ( 续 ) ——JSplitPaneDemo.java

Sw

ing

组件

Page 102: 第9章  图形用户界面 (GUI)

面向对象程序设计

102

list = new JList(imageNames); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); list.addListSelectionListener(this); JScrollPane listScrollPane = new JScrollPane(list); ImageIcon firstImage = new ImageIcon("./build/classes/"+(String)imageNames.firstElement()); picture = new JLabel(firstImage); picture.setPreferredSize(new Dimension(firstImage.getIconWidth(), firstImage.getIconHeight())); JScrollPane pictureScrollPane = new JScrollPane(picture); splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, listScrollPane, pictureScrollPane); splitPane.setOneTouchExpandable(true); splitPane.setDividerLocation(150); Dimension minimumSize = new Dimension(100, 50); listScrollPane.setMinimumSize(minimumSize); pictureScrollPane.setMinimumSize(minimumSize); splitPane.setPreferredSize(new Dimension(400, 200)); }

9.6.2 中间层容器 ( 续 ) ——JSplitPaneDemo.java

Sw

ing

组件

Page 103: 第9章  图形用户界面 (GUI)

面向对象程序设计

103

public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) return; JList theList = (JList)e.getSource(); if (theList.isSelectionEmpty()) { picture.setIcon(null); } else { int index = theList.getSelectedIndex(); ImageIcon newImage = new ImageIcon("./build/classes/"+ (String)imageNames.elementAt(index)); picture.setIcon(newImage); picture.setPreferredSize(new Dimension(newImage.getIconWidth(), newImage.getIconHeight() )); picture.revalidate(); } }

9.6.2 中间层容器 ( 续 ) ——JSplitPaneDemo.java

Sw

ing

组件

Page 104: 第9章  图形用户界面 (GUI)

面向对象程序设计

104

protected static Vector parseList(String theStringList) { Vector v = new Vector(10); StringTokenizer tokenizer = new StringTokenizer(theStringList, " "); while (tokenizer.hasMoreTokens()) { String image = tokenizer.nextToken(); v.addElement(image); } return v; } public static void main(String s[]) { JFrame frame = new JFrame("SplitPaneDemo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} }); SplitPaneDemo splitPaneDemo = new SplitPaneDemo(); frame.getContentPane().add(splitPaneDemo.getSplitPane()); frame.pack(); frame.setVisible(true); }}

9.6.2 中间层容器 ( 续 ) ——JSplitPaneDemo.java

Sw

ing

组件

Page 105: 第9章  图形用户界面 (GUI)

面向对象程序设计

105

程序说明– 将一个 JList 组件放在一个 JScrollPane 容器中– 将一个绘有图片的 JLabel 放在另一个 JScrollPane 容器中– 将两个 JScrollPane 容器放到一个 JSplitPane 容器中– 该类实现了 ListSelectionListener 接口,对列表选择事件可以做出反应,使 JLable 显示出不同的图片

9.6.2 中间层容器 ( 续 ) ——JSplitPaneDemo 运行结果

Sw

ing

组件

Page 106: 第9章  图形用户界面 (GUI)

面向对象程序设计

106

JTabbedPane

– 如果一个窗口的功能有几项,我们可以给每项设置一个标签,每个标签下面包含为完成此功能专用的若干组件

– 用户要使用哪项功能,只用点击相应的标签,就可以进入相应的页面

9.6.2 中间层容器 ( 续 ) ——JTabbedPane

Sw

ing

组件

Page 107: 第9章  图形用户界面 (GUI)

面向对象程序设计

107

9.6.2 中间层容器 ( 续 ) ——JTabbedPane 常用 API

名称 说明

JTabbedPane() 创建一个 tabbed pane。标签条位置在顶部

JtabbedPane(int tabPlacement)

创建一个 tabbed pane,并设置其标签位置。参数为从SwingConstants接口中继承来的TOP、 BOTTOM、 LEFT、 RIGHT之一。

void addTab(String title, Icon icon, Component comp, String tip)void addTab(String title, Icon icon, Component comp)void addTab(String, Component)

增加一个标签页,第一个 String参数指定显示在标签上的文本,可选的Icon参数制定标签图标, Component参数指定选择此标签页时要显示的组件,最后一个可选的 String参数是提示信息

void insertTab(String title, Icon icon,

Component comp, String tip, int index)

在指定位置 index插入一个标签页,第一个标签页的 index是 0 ,其余参数意义同 addTab方法

removeTabAt(int index) 删除指定位置的标签页

Sw

ing

组件

Page 108: 第9章  图形用户界面 (GUI)

面向对象程序设计

108

9.6.2 中间层容器 ( 续 ) ——JTabbedPane 常用 API

int indexOfTabComponent comp)

int indexofTab(String title)int indexofTab(Icon icon)

返回有指定组件、标题或图标的标签页序号

void setSelectedIndex(int)void setSelectedComponent(Component comp)

选择指定序号或组件的标签页。选择的效果是将显示此标签页所含的所有内容

void setComponentAt(int index, Component comp)

Component getComponentAt(int index)

设置或读取指定序号标签页上的组件

void setEnabledAt(int index, Boolean enabled)

设置指定序号标签页是否可选

Sw

ing

组件

Page 109: 第9章  图形用户界面 (GUI)

面向对象程序设计

109

import javax.swing.JTabbedPane;import javax.swing.ImageIcon;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JFrame;import java.awt.*;import java.awt.event.*;public class TabbedPaneDemo extends JPanel { public TabbedPaneDemo() { ImageIcon icon = new ImageIcon("images/middle.gif"); JTabbedPane tabbedPane = new JTabbedPane(); Component panel1 = makeTextPanel("Blah"); tabbedPane.addTab("One", icon, panel1, "Does nothing"); tabbedPane.setSelectedIndex(0); Component panel2 = makeTextPanel("Blah blah"); tabbedPane.addTab("Two", icon, panel2, "Does twice as much

nothing");

9.6.2 中间层容器 ( 续 ) ——TabbedPaneDemo.java

Sw

ing

组件

Page 110: 第9章  图形用户界面 (GUI)

面向对象程序设计

110

Component panel3 = makeTextPanel("Blah blah blah"); tabbedPane.addTab("Three", icon, panel3, "Still does nothing"); Component panel4 = makeTextPanel("Blah blah blah blah"); tabbedPane.addTab("Four", icon, panel4, "Does nothing at all"); //Add the tabbed pane to this panel. setLayout(new GridLayout(1, 1)); add(tabbedPane); } protected Component makeTextPanel(String text) { JPanel panel = new JPanel(false); JLabel filler = new JLabel(text); filler.setHorizontalAlignment(JLabel.CENTER); panel.setLayout(new GridLayout(1, 1)); panel.add(filler); return panel; }

9.6.2 中间层容器 ( 续 ) ——TabbedPaneDemo.java

Sw

ing

组件

Page 111: 第9章  图形用户界面 (GUI)

面向对象程序设计

111

public static void main(String[] args) { JFrame frame = new JFrame("TabbedPaneDemo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) {System.exit(0);} });

frame.getContentPane().add(new TabbedPaneDemo(), BorderLayout.CENTER); frame.setSize(400, 125); frame.setVisible(true); }}

9.6.2 中间层容器 ( 续 ) ——TabbedPaneDemo.java

Sw

ing

组件

Page 112: 第9章  图形用户界面 (GUI)

面向对象程序设计

112

说明– 在构造函数中创建四个 JPanel 类型的对象– 并将其依次添加到一个 JTabbedPane 类的对象容器中– 最后再将该 JTabbedPane 类的对象容器放在一个

JFrame 对象的内容面板中

9.6.2 中间层容器 ( 续 ) ——TabbedPaneDemo.java 运行结果

Sw

ing

组件

Page 113: 第9章  图形用户界面 (GUI)

面向对象程序设计

113

JToolBar

– 一般我们在设计界面时,会将所有功能分类放置在菜单中( JMen

u ),但当功能相当多时,可能会使成用户为一个简单的操作反复地寻找菜单中相关的功能

– 可以把一些常用的功能以工具栏的方式呈现在菜单下,这就是JToolBar 容器类的好处

– 我们可以将 JToolBar 设计为水平或垂直方向的,也可以以鼠标拉动的方式来改变

9.6.2 中间层容器 ( 续 ) ——JToolBar

Sw

ing

组件

Page 114: 第9章  图形用户界面 (GUI)

面向对象程序设计

114

9.6.2 中间层容器 ( 续 ) ——JToolBar 常用 API

名称 说明

JToolBar()JToolBar(int orientation)JToolBar(String name)JToolBar(String name,int

orientation)

创建一个工具栏,可以指定其朝向orientation,为SwingConstants中的HORIZONTAL或VERTICLE,也可以指定游离工具栏显示的名称 name。

void add(Component) 为工具栏添加一个组件

void addSeparator() 在末尾增加一个分隔线

void setFloatabled(Boolean floatabled)

Boolean isFloatable()

设置或读取工具栏是否可以游离,成为一个独立的窗口

Sw

ing

组件

Page 115: 第9章  图形用户界面 (GUI)

面向对象程序设计

115

import javax.swing.JToolBar;import javax.swing.JButton;import javax.swing.ImageIcon;import javax.swing.JFrame;import javax.swing.JTextArea;import javax.swing.JScrollPane;import javax.swing.JPanel;import java.awt.*;import java.awt.event.*;public class ToolBarDemo extends JFrame { protected JTextArea textArea; protected String newline = "\n"; public ToolBarDemo() { //Do frame stuff. super("ToolBarDemo"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } });

9.6.2 中间层容器 ( 续 ) ——ToolBarDemo.java

Sw

ing

组件

Page 116: 第9章  图形用户界面 (GUI)

面向对象程序设计

116

JToolBar toolBar = new JToolBar(); //Create the toolbar. addButtons(toolBar); //Create the text area used for output. textArea = new JTextArea(5, 30); JScrollPane scrollPane = new JScrollPane(textArea); //Lay out the content pane. JPanel contentPane = new JPanel(); contentPane.setLayout(new BorderLayout()); contentPane.setPreferredSize(new Dimension(400, 100)); contentPane.add(toolBar, BorderLayout.NORTH); contentPane.add(scrollPane, BorderLayout.CENTER); setContentPane(contentPane); }

9.6.2 中间层容器 ( 续 ) ——ToolBarDemo.java

Sw

ing

组件

Page 117: 第9章  图形用户界面 (GUI)

面向对象程序设计

117

protected void addButtons(JToolBar toolBar) { JButton button = null; //first button button = new JButton(new ImageIcon("./build/classes/left.gif")); button.setToolTipText("This is the left button"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { displayResult("Action for first button"); } }); toolBar.add(button); //second button button = new JButton(new ImageIcon("./build/classes/middle.gif")); button.setToolTipText("This is the middle button"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { displayResult("Action for second button"); } }); toolBar.add(button);

9.6.2 中间层容器 ( 续 ) ——ToolBarDemo.java

Sw

ing

组件

Page 118: 第9章  图形用户界面 (GUI)

面向对象程序设计

118

//third button button = new JButton(new ImageIcon("./build/classes/right.gif")); button.setToolTipText("This is the right button"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { displayResult("Action for third button"); } }); toolBar.add(button); } protected void displayResult(String actionDescription) { textArea.append(actionDescription + newline); } public static void main(String[] args) { ToolBarDemo frame = new ToolBarDemo(); frame.pack(); frame.setVisible(true); }}

9.6.2 中间层容器 ( 续 ) ——ToolBarDemo.java

Sw

ing

组件

Page 119: 第9章  图形用户界面 (GUI)

面向对象程序设计

119

说明– 创建了三个按钮,并为每个按钮添加了事件监听器– 将三个按钮放在一个 JToolBar 容器中– 将 JToolBar 容器放在顶层容器的内容面板中– 将一个包含 JtextArea 组件的 JScrollPane 容器也放在顶层容器的内容面板中

9.6.2 中间层容器 ( 续 ) ——ToolBarDemo 运行结果

Sw

ing

组件

Page 120: 第9章  图形用户界面 (GUI)

面向对象程序设计

120

JInternalFrame

– 如果要实现在一个主窗口中打开很多个文档,每个文档各自占用一个新的窗口,就需要使用 JInternalFrame 容器类

– JInternalFrame 的使用跟 JFrame几乎一样,可以最大化、最小化、关闭窗口、加入菜单

– 唯一不同的是 JInternalFrame 是轻量级组件,因此它只能是中间容器,必须依附于顶层容器上

– 通常我们会将 internal frame 加入 JDesktopPane 类的对象来方便管理, JDesktopPane 继承自 JLayeredPane ,用来建立虚拟桌面。它可以显示并管理众多 internal frame 之间的层次关系

9.6.2 中间层容器 ( 续 ) ——JInternalFrame

Sw

ing

组件

Page 121: 第9章  图形用户界面 (GUI)

面向对象程序设计

121

9.6.2 中间层容器 ( 续 ) ——JInternalFrame 常用 API

名称 说明JInternalFrame() JInternalFrame(String title)JInternalFrame(String title, boolean

resizable)JInternalFrame(String title, boolean

resizable, boolean closable)JInternalFrame(String title, boolean

resizable, boolean closable, boolean maximizable)JInternalFrame(String, boolean resizable, boolean closable, boolean maximizable,boolean iconifiable)

创建一个子窗口对象,依次设置标题、是否可改变大小、可关闭、可最大最小化、是否有图标。默认状态下都是不可以。

void setContentPane(Container c)Container getContentPane()

设置或获得 internal frame的内容面板,通常包括除菜单以外的所有可视组件

Sw

ing

组件

Page 122: 第9章  图形用户界面 (GUI)

面向对象程序设计

122

void setJMenuBar(JMenuBar m)JMenuBar getJMenuBar()

设置或获得 internal frame的菜单

void setVisible(boolean b)

此方法从 Component 类继承。设置是否可见。应该在将internal frame 加到其父窗口之前调用。

void setLocation(int x, int y)设置相对于父窗口的位置。指定左上角坐标

void setBounds(int x, int y, int width, int height)

设置位置和大小

Void addInternalFrameListener(InternalFrameListener l)

添加事件监听器,相当于windowlistener

void setSelected(boolean b)boolean isSelected()

设置或获得当前是否被激活。

void setFramedIcon(Icon icon)Icon getFrameIcon()

设置或获得显示在 internal frame 标题栏中的图标

9.6.2 中间层容器 ( 续 ) ——JInternalFrame 常用 API

Sw

ing

组件

Page 123: 第9章  图形用户界面 (GUI)

面向对象程序设计

123

9.6.2 中间层容器 ( 续 ) ——InternalFrameDemo.java MyInternalFrame.java

Sw

ing

组件

Page 124: 第9章  图形用户界面 (GUI)

面向对象程序设计

124

9.6.3 原子组件

Swing原子组件有很多种 , 与顶层容器和中间容器相比,原子组件用法都比较简单

可将其分为三类– 显示不可编辑信息

JLabel、 JProgressBar、 JToolTip

– 有控制功能、可以用来输入信息 JButton、 JCheckBox、 JRadioButton、 JComboBox、 JList、 J

Menu、 JSlider、 JSpinner、 JTextComponent

– 能提供格式化的信息并允许用户选择 JColorChooser、 JFileChooser、 JTable、 JTree

Sw

ing

组件

Page 125: 第9章  图形用户界面 (GUI)

面向对象程序设计

125

JLabel– 该组件上可以显示文字和图像,并能指定两者的位置

JProgressBar– 在一些软件运行时,会出现一个进度条告知目前进度如何。通过使用该

组件我们可以轻松地为软件加上一个进度条 提示信息

– 通常不必直接处理 JToolTip 类– 通常使用 setToolTipText() 方法为组件设置提示信息– 有的组件例如 JTabbedPane 由多个部分组成,需要鼠标在不同部分停留时显示不同的提示信息,这时可以在其 addTab() 方法中设置提示信息参数,也可以通过 setTooltipTextAt 方法进行设置

9.6.2 原子组件 ( 续 ) ——第一类原子组件

Sw

ing

组件

Page 126: 第9章  图形用户界面 (GUI)

面向对象程序设计

126

随时间增加,进度条输出进度变化情况,同时标签上显示出当前进度。鼠标移到两组件时,显示提示信息

import javax.swing.*;import java.awt.*;import javax.swing.event.*;import java.awt.event.*;public class Ex9_9 implements ChangeListener {

JLabel label;JProgressBar pb;public Ex9_9() {int value=0;JFrame f=new JFrame("第一类原子组件演示 ");Container contentPane=f.getContentPane ();label=new JLabel("",JLabel.CENTER);label.setToolTipText (" 显示进度信息 ");pb=new JProgressBar();pb.setOrientation(JProgressBar.HORIZONTAL); // 设置进度条方向pb.setMinimum(0); // 设置最小值pb.setMaximum(100); // 设置最大值

9.6.2 原子组件 ( 续 ) ——例9_9

Sw

ing

组件

Page 127: 第9章  图形用户界面 (GUI)

面向对象程序设计

127

pb.setValue(value); //初值pb.setStringPainted(true); // 设置进度条上显示进度pb.addChangeListener(this); // 增加时间监听器pb.setToolTipText ("进度条 "); // 设置提示信息contentPane.add(pb,BorderLayout.CENTER);

contentPane.add(label,BorderLayout.SOUTH);f.setSize(400,60);f.setVisible(true);for(int i=1;i<=500000000;i++) {

if(i%5000000==0) pb.setValue(++value); //改变进度条的值,触发 ChangeEvent

} f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); public static void main(String[] args) { new Ex9_8(); } public void stateChanged(ChangeEvent e) { int value=pb.getValue(); label.setText (" 目前已完成进度: "+value+"% "); }}

9.6.2 原子组件 ( 续 ) ——例9_9

Sw

ing

组件

Page 128: 第9章  图形用户界面 (GUI)

面向对象程序设计

128

说明– Ex9_9 类实现 ChangeListener 接口,实现了 stateChanged 方法– main 方法中随着程序的运行,不断改变进度条的当前值,触发

stateChanged 方法,在 JLable 组件上显示当前进度信息– 通过 Component 类的 setTooltipText(String s) 方法为组件添加提

示信息

9.6.2 原子组件 ( 续 ) ——例 9_9 运行结果

Sw

ing

组件

Page 129: 第9章  图形用户界面 (GUI)

面向对象程序设计

129

按钮类– AbstractButton抽象类是众多按钮类的基类,继

承它的类包括 JButton JToggleButton—— 表示有两个选择状态的按钮

– CheckBox (多选按钮)– JRadioButton (单选按钮)

JMenuItem—— 在菜单中使用– JCheckBoxMenuItem (多选按钮)– JRadioButtonMenuItem (单选按钮)– JMenu (一般的菜单项)

9.6.2 原子组件 ( 续 ) ——第二类原子组件:按钮类

Sw

ing

组件

Page 130: 第9章  图形用户界面 (GUI)

面向对象程序设计

130

JComponent

AbstractButton

JToggleButton

JRadioButtonJCheckBox

JButton

JComponent

AbstractButton

JButton JToggleButton

JCheckBox JRadioButton

9.6.2 原子组件 ( 续 ) ——第二类原子组件:按钮类

Sw

ing

组件

Page 131: 第9章  图形用户界面 (GUI)

面向对象程序设计

131

ButtonDemo.java

CheckBoxDemo.java RadioButtonDemo.java

9.6.2 原子组件 ( 续 ) ——几个例子

Sw

ing

组件

Page 132: 第9章  图形用户界面 (GUI)

面向对象程序设计

132

列表框 JList– 除了 JCheckBox 以外, JList 也可以选择一到多个选项– 有几种各有特色的构造方法(选项是否可添加、删除)– 也提供了很多 API 可以用来设置各选项的显示方式(在

一列还是若干列)、选择模式(一次可选几项及是否可连续)等

– 因为 JList 通常含有很多选项,所以经常把它放在一个JScrollPane 对象里面

– JList 的事件处理一般可分为两类 取得用户选取的项目,事件监听器是

ListSelectionListener 对鼠标事件作出响应,其事件监听器是 MouseListener

9.6.2 原子组件 ( 续 ) ——第二类原子组件:列表框

Sw

ing

组件

Page 133: 第9章  图形用户界面 (GUI)

面向对象程序设计

133

说明– 先创建一个 LIstModel 对象,再将 ListModel 对象作为参数创建一个 JList 对象

– 列表框中的选择发生变化时将触发 ListSelectionListener 事件监听器

– 为 fire、 hire两个按钮添加 ActionListener 事件监听器,在其ActionPerformed 方法中修改 ListModel 对象的属性,以改变列表内容

9.6.2 原子组件 ( 续 ) ——ListDemo.java

Sw

ing

组件

Page 134: 第9章  图形用户界面 (GUI)

面向对象程序设计

134

复选框 JComboBox– 允许用户在许多选项中选其一,可以有两种非常不一样的格式

默认状态是不可编辑的模式,其特色是包括一个按钮和一个下拉列表,用户只能在下拉列表提供的内容中选其一

另一种是可编辑的模式,其特色是多了一个文本区域,用户可以在此文本区域内填入列表中不包括的内容

– 复选框只需要很少的屏幕区域,而一组JRadioBox、 JCheckBox、 JList占据的空间比较大

9.6.2 原子组件 ( 续 ) ——第二类原子组件:复选框

Sw

ing

组件

Page 135: 第9章  图形用户界面 (GUI)

面向对象程序设计

135

说明– 以一个字符串数组为参数创建了一个 JComboBox 对象– 为该对象添加 ActionListener 事件监听器,当选择不同动物名称时,

显示不同的动物图片

9.6.2 原子组件 ( 续 ) ——ComboBoxDemo.java

Sw

ing

组件

Page 136: 第9章  图形用户界面 (GUI)

面向对象程序设计

136

连续数值选择– JSlider

空间大 好像电器用品上机械式的控制杆,我们可以设置

它的最小、最大、初始刻度,还可以设置它的方向,还可以为其标上刻度或文本

在 JSlider 上移动滑动杆,会产生 ChangeEvent事件

– JSpinner 空间小 类似于可编辑的 JComboBox ,是种复合组件,

由三个部分组成:向上按钮、向下按钮和一个文本编辑区

可以通过按钮来选择待选项,也可以直接在文本编辑区内输入

和 JComboBox 不同的是,它的待选项不会显示出来

9.6.2 原子组件 ( 续 ) ——第二类原子组件:连续数值选择

Sw

ing

组件

Page 137: 第9章  图形用户界面 (GUI)

面向对象程序设计

137

文本组件– 允许用户在里边编辑文本,能满足复杂的文本需求– 都继承自 JTextComponent抽象类,可分为三类

JTextField、 JPasswordField、 JFormattedTextField– 它们只能显示和编辑一行文本,像按钮一样,它们可以产生 ActionEvent

事件,因此通常用来接受少量用户输入信息并在输入结束进行一些事件处理

JTextArea– 它可以显示和编辑多行文本,但是这些文本只能是单一风格的,因此通

常用来让用户输入任意长度的无格式文本或显示无格式的帮助信息 JEditorPane、 JTextPane

– 可以显示和编辑多行多种式样的文本,嵌入图像或别的组件

9.6.2 原子组件 ( 续 ) ——第二类原子组件:文本组件

Sw

ing

组件

Page 138: 第9章  图形用户界面 (GUI)

面向对象程序设计

138

在第一个窗口输入用户名和密码,要求输入密码使用 JPasswordField组件,密码正确后,才能进入第二个窗口进行“+、-、 ×、 ÷” 计算。运算符号使用单选按钮 JRadioButton ,操作数使用 JcomboBox和Jspinner 组件

9.6.2 原子组件 ( 续 ) ——例9_10

Sw

ing

组件

Page 139: 第9章  图形用户界面 (GUI)

面向对象程序设计

139

JColorChooser颜色选择对话框– 可以让用户选择所需要的颜色– 通常使用这个类的静态方法 showDialog() 来输出标准的颜色选择对话框,其返回值就是选择的颜色

– 也可以通过静态方法 createDialog() 方式输出个性化的颜色选择对话框,例如为其添加菜单、定义其事件处理程序,这个方法的返回值就是一个对话框

9.6.2 原子组件 ( 续 ) ——第三类原子组件

Sw

ing

组件

Page 140: 第9章  图形用户界面 (GUI)

面向对象程序设计

140

JFileChooser 文件选择对话框– 让用户选择一个已有的文件或者新建一个文件– 可以使用 JFileChooser的 showDialog、 showOpenDialog或

showSaveDialog() 方法来打开文件对话框,但是它仅仅会返回用户选择的按钮(确认还是取消)和文件名(如果确认的话),接下来的要实现的例如存盘或者打开的功能还需要程序员自己编写

– 这个类提供了专门的方法用于设置可选择的文件类型,还可以指定每类文件使用的类型图标

9.6.2 原子组件 ( 续 ) ——第三类原子组件

Sw

ing

组件

Page 141: 第9章  图形用户界面 (GUI)

面向对象程序设计

141

JTable 表格– 和其相关的还有一些接口和类,包括

TableModel、 AbstractTableModel、 DefaultTableModel、 SelectionModel、 TableColumnModel

– 可为表格设计显示外观(是否有滚动条、调整某一列宽其它列宽变化情形)、显示模式(根据数据类型的不同有不同的排列显示方式、为某一字段添加复选框 JComboBox )、选择模式(单选、多选、连续选、任意选)

– 在 JTable 的事件大致均针对表格内容的异操作处理,我们称为TableModelEvent 事件。通过 addTableModelListener 方法为表格添加此种事件监听器

9.6.2 原子组件 ( 续 ) ——第三类原子组件

Sw

ing

组件

Page 142: 第9章  图形用户界面 (GUI)

面向对象程序设计

142

JTree– 用来产生树状结构来直观地表现层次关系,有根节点、树枝节点、

树叶节点– 构造方法有多种,参数可以是一个 Hashtable ,也可以是

TreeNode或 TreeModel 对象– 可以使用 JComponent 提供的 putClientProperty 方法来设置 JTree外观,也可以使用 TreeCellRenderer 来个性化各类节点的显示样式

9.6.2 原子组件 ( 续 ) ——第三类原子组件

Sw

ing

组件

Page 143: 第9章  图形用户界面 (GUI)

面向对象程序设计

143

9.7 其它 Swing 特性

很多 Swing 组件都要使用一些相同的特性,包括– Action 对象– 边框– 设置外观和感觉– 应用线程– 定时器– 等等

Page 144: 第9章  图形用户界面 (GUI)

面向对象程序设计

144

9.7.1 Action 对象

Action 的用途– Action 接口是对 ActionListener 接口的一个有用的扩展,它的继

承关系如下public interface Action extends ActionListener

– 在很多既有菜单又有工具栏的应用程序中,我们可以看到某条菜单和工具栏的功能是相同的,按照前面所讲的方法,我们需要为每个组件一一添加事件监听器,并在其处理程序中写入相同的代码,程序就会显得比较繁琐。在这种场合,可以考虑使用 Action对象实现此功能

– 还可以通过它对不同组件的显示文字、图标、快捷键、提示文字、是否可用等属性进行统一的设置

其它S

win

g

特性

Page 145: 第9章  图形用户界面 (GUI)

面向对象程序设计

145

9.7.1 Action 对象 ( 续 ) —— 创建 Action 对象

创建 Action 对象– 通常我们首先需要创建一个继承抽象类 AbstractAction 类的子类,然后再实例化这个子类

– AbstractAction抽象类提供了 Action 接口的默认实现,而且还提供了一些获取和设置 Action域属性的方法。我们在继承它创建自己需要的子类的时候,只需要通过这些方法

设置需要的属性值 定义 actionPerformed 方法

其它S

win

g

特性

Page 146: 第9章  图形用户界面 (GUI)

面向对象程序设计

146

使用 Action 对象– 可通过 GUI 组件的 setAction 方法把 Action关联到此

GUI 组件。每个具有 addActionListener 方法的组件也都具有 setAction 方法

– 但 setAction 方法并不是 addActionLilstener 方法的替换: Action 是一个事件监听器,如果除此之外还需要添加别的监听器,则应该使用 addActionListener 方法

– 对给定的 GUI 组件,你可以调用 setAction 不止一次,但组件和上一个 Action 对象之间的关联会被删除

9.7.1 Action 对象 ( 续 ) —— 使用 Action 对象

其它S

win

g

特性

Page 147: 第9章  图形用户界面 (GUI)

面向对象程序设计

147

通过 setAction 方法把 Action 对象关联到某 GUI 组件后,会有如下效果

– 此组件的属性会被升级到符合这个 Action 对象的属性,例如如果设置了 Action 对象的文字和图标值,那么组件的文字和图标也会被重新设置成同样的值。

– 这个 Action 对象会被注册为此组件的一个事件监听器对象– 如果改变了 Action 对象的属性或方法,则所有和它关联的组件的使

能状态也会发生相应改变

9.7.1 Action 对象 ( 续 ) —— 使用 Action 对象的效果

其它S

win

g

特性

Page 148: 第9章  图形用户界面 (GUI)

面向对象程序设计

148

/* Uses actions with a tool bar and a menu. */import javax.swing.AbstractAction;import javax.swing.Action;import javax.swing.JToolBar;import javax.swing.JButton;import javax.swing.ImageIcon;import javax.swing.JMenuItem;import javax.swing.JCheckBoxMenuItem;import javax.swing.JMenu;import javax.swing.JMenuBar;import javax.swing.JFrame;import javax.swing.JTextArea;import javax.swing.JScrollPane;import javax.swing.JPanel;import java.awt.*;import java.awt.event.*;

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 149: 第9章  图形用户界面 (GUI)

面向对象程序设计

149

public class ActionDemo extends JFrame { protected JTextArea textArea; protected String newline = "\n"; protected Action leftAction; protected Action middleAction; protected Action rightAction; public ActionDemo() { super("ActionDemo"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); //Create the toolbar and menu. JToolBar toolBar = new JToolBar(); JMenu mainMenu = new JMenu("Menu"); createActionComponents(toolBar, mainMenu);

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 150: 第9章  图形用户界面 (GUI)

面向对象程序设计

150

//Create the text area used for output. textArea = new JTextArea(5, 30); JScrollPane scrollPane = new JScrollPane(textArea); //Lay out the content pane. JPanel contentPane = new JPanel(); contentPane.setLayout(new BorderLayout()); contentPane.setPreferredSize(new Dimension(400, 150)); contentPane.add(toolBar, BorderLayout.SOUTH); contentPane.add(scrollPane, BorderLayout.CENTER); setContentPane(contentPane); //Set up the menu bar. JMenuBar mb = new JMenuBar(); mb.add(mainMenu); mb.add(createAbleMenu()); setJMenuBar(mb); }

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 151: 第9章  图形用户界面 (GUI)

面向对象程序设计

151

protected void createActionComponents(JToolBar toolBar, JMenu mainMenu) { JButton button = null; JMenuItem menuItem = null; //first button and menu item leftAction = new AbstractAction("Go left", new ImageIcon("./build/classes/left.gif")) { public void actionPerformed(ActionEvent e) { displayResult("Action for first button/menu item", e); } }; button = toolBar.add(leftAction); button.setText(""); //an icon-only button button.setToolTipText("This is the left button"); menuItem = mainMenu.add(leftAction); menuItem.setIcon(null); //arbitrarily chose not to use icon in menu

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 152: 第9章  图形用户界面 (GUI)

面向对象程序设计

152

//second button and menu item middleAction = new AbstractAction("Do something", new ImageIcon("./build/classes/middle.gif")) { public void actionPerformed(ActionEvent e) { displayResult("Action for second button/menu item", e); } }; button = toolBar.add(middleAction); button.setText(""); button.setToolTipText("This is the middle button"); menuItem = mainMenu.add(middleAction);

menuItem.setIcon(null); //arbitrarily chose not to use icon in menu

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 153: 第9章  图形用户界面 (GUI)

面向对象程序设计

153

//third button and menu item rightAction = new AbstractAction("Go right", new ImageIcon("./build/classes/right.gif")) { public void actionPerformed(ActionEvent e) { displayResult("Action for third button/menu item", e); } }; button = toolBar.add(rightAction); button.setText(""); button.setToolTipText("This is the right button"); menuItem = mainMenu.add(rightAction); menuItem.setIcon(null); //arbitrarily chose not to use icon in menu }

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 154: 第9章  图形用户界面 (GUI)

面向对象程序设计

154

protected JMenu createAbleMenu() { JMenu ableMenu = new JMenu("Action State"); JCheckBoxMenuItem cbmi = null; cbmi = new JCheckBoxMenuItem("First action enabled"); cbmi.setSelected(true); cbmi.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { JCheckBoxMenuItem mi = (JCheckBoxMenuItem)(e.getSource()); boolean selected = (e.getStateChange() == ItemEvent.SELECTED); leftAction.setEnabled(selected); } }); ableMenu.add(cbmi); //… 这里省略了增加另外两个类似的菜单复选框的语句… return ableMenu; }

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 155: 第9章  图形用户界面 (GUI)

面向对象程序设计

155

protected void displayResult(String actionDescription, ActionEvent e) { String s = ("Action event detected by: " + actionDescription + newline + " Event source: " + e.getSource() + newline); textArea.append(s); }

public static void main(String[] args) { ActionDemo frame = new ActionDemo(); frame.pack(); frame.setVisible(true); }}

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 156: 第9章  图形用户界面 (GUI)

面向对象程序设计

156

说明– 创建了三个 Action 对象,在每个对象中定义了文本、图片等属性以及

actionPerformed 方法– 分别为三组按钮、菜单分别添加三个 Action 对象,使组内的按钮、菜单

具有相同的功能– 创建了三个复选框菜单选项,在其事件监听器 ItemListener() 中改变

Action 对象的 enabled 属性,因此可以同时改变按钮、菜单的使能状态

9.7.1 Action 对象 ( 续 ) ——ActionDemo.java

其它S

win

g

特性

Page 157: 第9章  图形用户界面 (GUI)

面向对象程序设计

157

9.7.2 边框

边框 (Border)– 每个继承自 JComponent的 Swing 组件都可以有若干个边框– 边框可以用来

绘制线条 为组件提供标题 为组件提供周边的空白区域

– 我们使用组件的 setBorder 方法为组件添加边框。这个方法需要提供一个 Border 类型的对象

通常可以使用 BorderFactory 类提供的很多静态方法产生一个常用的Border 对象

如果不能够满足要求,可以直接使用 javax.swing.border 包里的 API来定义自己的边框

其它S

win

g

特性

Page 158: 第9章  图形用户界面 (GUI)

面向对象程序设计

158

9.7.2 边框 ( 续 ) —— 有关 border 的常用 API

名称 说明BorderFactory类里的静态方法,返回类型都是 Border

createLineBorder(Color color)createLineBorder(Color color, int

thickness)创建指定颜色、线宽的线框

createEtcheBorder()createEtchedBorder(Color hightlight,

Color shadow)createEtchedBorder(int type)createEtcheBorder(int type, Color

highlight, Color shadow)

创建突起或凹陷的边框。可选的Color参数指定了使用的高亮和阴影色。 type参数为EtchedBorder.LOWERED或 EtchedBorder.RAISED之一,如果不含此参数,则为LOWERED。

createLoweredBevelBorder()创建一种边框,给人感觉组件比周围低

createRaiseBevelBorder()创建一种边框,给人感觉组件比周围高

其它S

win

g

特性

Page 159: 第9章  图形用户界面 (GUI)

面向对象程序设计

159

createBevelBorder(int type, Color highlight, Color shadow)

createBevelBorder(int type,Color highlightOuter, Color

highlightInner, Color shadowOuter, Color

shadowInner)

创建为组件造成突起或下沉的效果的边框, type为BevelBorder.RAISED或BevelBorder.LOWERED。颜色参数用来指定外层和内层的高亮色和阴影色

createEmptyBorder()createEmptyBorder(int top, int left,

int bottom, int right)

创建一不显示的边框,无参数的边框不占空间,有参数的指定了边框在四个边上占据的象素数

MatterBorder createMatteBorder(int top, int left, int bottom, int right, Color color)

MatterBorder createMatteBorder(int top, int left, int bottom, int right, Icon tileIcon)

创建一个不光滑的边框,四个整数参数指定了边框在四个边上占据的象素数,颜色参数指定了边框的颜色,图标参数指定了填充边框的图标

9.7.2 边框 ( 续 ) —— 有关 border 的常用 API

其它S

win

g

特性

Page 160: 第9章  图形用户界面 (GUI)

面向对象程序设计

160

TitledBorder createTitledBorder(Border border,String title,int titleJustification, int titlePosition, Font titleFont, Color titleColor)

为已有的 border增加标题 title,并指定标题位置、字体、颜色。某些参数是可选的,具体用法见API文档。

CompoundBorder createCompoundBorder(

Border outsideBorder, Border insideBorder)

创建一个双层边框

Swing组件用来设置边框的 API

void setBorder(Border border)Border getBorder()

设置或获得 JComponent组件的边框

void setBorderPainted(Boolean)Boolean isBorderPainted()

设置或获得是否显示边框,用在AbstractButton、 JMenuBar 、 JPopupMenu、 JProgressBar和 JToolBar中。

9.7.2 边框 ( 续 ) —— 有关 border 的常用 API

其它S

win

g

特性

Page 161: 第9章  图形用户界面 (GUI)

面向对象程序设计

161

说明– 创建了四个 JPanel 组件,放在一个 JTabbedPane 中间容器中– 在每个 JPanel 组件中,又创建了若干个 JPanel 组件,并为其

通过 setBorder 方法制定不同的边框 通过一个 JLabel 组件显示出对该种边框的描述

9.7.1 Action 对象 ( 续 ) ——BorderDemo.java

其它S

win

g

特性

Page 162: 第9章  图形用户界面 (GUI)

面向对象程序设计

162

9.7.3 设置外观和感觉

Swing 有一个十分有趣的特点,就是所谓的可插入式的外观和感觉( Pluggable Look & Feel ),允许程序模拟各种操作系统的外观和感觉

– JAVA Look and Feel 类名为“ javax.swing.plaf.metal.MetalLookAndFeel” 程序默认的 Look and Feel ,这是 java 提供的跨平台的有金属质感的外观和感觉。可以用在所有平台上

– Motif Look and Feel 类名为“ com.sun.java.swing.plaf.motif.MotifLookAndFeel” 仿真 UNIX环境的外观和感觉,也可以用在所有平台上

– Microsoft Windows 类名为“ com.sun.java.swing.plaf.windows.WindowsLookAndFeel” 它只能在 Microsoft Windows 的操作系统下使用。

– Macintosh style 类名为“ com.sun.java.swing.plaf.mac.MacLookAndFeel” 只能在 Macintosh 的操作系统下使用

其它S

win

g

特性

Page 163: 第9章  图形用户界面 (GUI)

面向对象程序设计

163

我们需要在产生任何可视组件以前就设置好它们的外观和感觉,要设置某种外观和感觉,必须使用 UIManager 类所提供的setLookAndFeel()静态方法,这个方法的参数为上面提到的类名字符串之一。通常我们只会做两种选择

– java 提供的跨平台的外观和感觉。可以利用 UIManager 类提供的getCrossPlatformLookAndFeelClassName()静态方法获得类名

– 程序所处系统的外观和感觉。可以利用 UIManager 类提供的getSystemLookAndFeel()静态方法获得目前操作平台的 Look and Feel 类名称字符串

9.7.2 设置外观和感觉 ( 续 ) —— 为组件进行设置

其它S

win

g

特性

Page 164: 第9章  图形用户界面 (GUI)

面向对象程序设计

164

前述设置不能影响顶层容器 JFrame和 JDialog ,因为它们是重量级组件,均是依赖于操作系统 (Operating System dependent )的,当使用的操作系统不同时,所显示的顶层容器就会有所不同。针对这两个顶层容器,有一个静态方法专门为其设置外观感觉

– static void setDefaultLookAndFeelDecorated(boolean ) 参数是 true ,就会选用默认的外观感觉 参数是 false ,就会选用操作平台的外观感觉

9.7.2 设置外观和感觉 ( 续 ) —— 为顶层容器进行设置

其它S

win

g

特性

Page 165: 第9章  图形用户界面 (GUI)

面向对象程序设计

165

Java 外观和感觉

CDE/Motif外观和感觉

Windows外观和感觉

9.7.3 设置外观和感觉 ( 续 )

其它S

win

g

特性

Page 166: 第9章  图形用户界面 (GUI)

面向对象程序设计

166

9.7.4 应用线程

一个 Swing 组件被创建出来后,应该只有事件处理的线程可以访问它。别的线程最好应该不去调用关于该组件的方法。否则有可能造成死锁

在某些情况下应该使用线程– GUI界面初始化中有一个很耗时的任务要完成(比如复杂的计算、网络堵塞、磁盘 I/O ),我们可以把这个任务放到主线程之外进行,这样界面就会出现得比较快

– 点击一个按钮进入一段事件处理程序中,而这段程序本身很费时间,如果这段程序不结束, GUI 就无法响应别的事件,解决办法就是把这段事件处理程序放到另外一个线程中,例如一个后台线程

– 定期重复执行某项操作– 等待从其它程序传来的消息

其它S

win

g

特性

Page 167: 第9章  图形用户界面 (GUI)

面向对象程序设计

167

单线程的绘图程序:有一个按钮和标签,标签可以在上面画线,按钮点击后则进入无限循环(点击按钮可能造成死机)import javax.swing.*;import java.awt.*;import java.awt.event.*;public class Ex9_11 extends JFrame { int x,y; public Ex9_11() {

this.setTitle (" 线程演示 ");Container c=this.getContentPane();JLabel L=new JLabel(" 点击可以画线哟 ",JLabel.CENTER);c.add(L,BorderLayout.CENTER);JButton b=new JButton(“试试按我,别后悔啊 ");b.setBorder (BorderFactory.createLineBorder (Color.red,5)); c.add(b,BorderLayout.SOUTH);

9.7.4 应用线程 ( 续 ) ——例9_11

其它S

win

g

特性

Page 168: 第9章  图形用户界面 (GUI)

面向对象程序设计

168

L.addMouseListener (new MouseAdapter(){ public void mousePressed(MouseEvent e){ x=e.getX(); //获得按点的横坐标 y=e.getY(); //获得按点的纵坐标 repaint(); // 重绘组件 } });

b.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e){ while(true); // 点击按钮后进入死循环 }

});this.setSize (300,400);this.show (); // 显示

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void update(Graphics g) {.drawLine(0,0,x,y);} public static void main(String[] args) { new Ex9_11(); }}

9.7.4 应用线程 ( 续 ) ——例9_11

其它S

win

g

特性

Page 169: 第9章  图形用户界面 (GUI)

面向对象程序设计

169

说明– 为标签添加 MouseAdapter 鼠标事

件监听器,对鼠标点击事件做出响应

– 通过 MouseEvent 事件对象可获得鼠标点击的坐标,调用 repaint 方法后,该方法又会自动调用 update 方法重绘 GUI

– 为按钮添加 ActionListener 事件监听器,鼠标点击后进入死循环,不能继续对点击标签事件做出响应了

9.7.4 应用线程 ( 续 ) ——例 9_11 运行结果

其它S

win

g

特性

Page 170: 第9章  图形用户界面 (GUI)

面向对象程序设计

170

多线程的绘图程序:修改上例,使点击按钮后虽然进入无限循环,仍可以画线import javax.swing.*;import java.awt.*;import java.awt.event.*;public class Ex9_12 extends JFrame { int x,y; public Ex9_12() {

this.setTitle (" 线程演示 ");Container c=this.getContentPane();JLabel L=new JLabel(" 点击可以画线哟 ",JLabel.CENTER);c.add(L,BorderLayout.CENTER);JButton b=new JButton("试试按我 ");b.setBorder (BorderFactory.createLineBorder (Color.red,5)); c.add(b,BorderLayout.SOUTH);

L.addMouseListener (new MouseAdapter(){ public void mousePressed(MouseEvent e){ x=e.getX(); //获得按点的横坐标 y=e.getY(); //获得按点的纵坐标 repaint(); // 重绘组件 } });

9.7.4 应用线程 ( 续 ) ——例9_12

其它S

win

g

特性

Page 171: 第9章  图形用户界面 (GUI)

面向对象程序设计

171

b.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ new newThread().start(); }

});this.setSize (300,400);this.show (); // 显示

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void update(Graphics g) {.drawLine(0,0,x,y); } public static void main(String[] args) { new Ex9_12(); }}class newThread extends Thread {

public void run() { while(true);}}

9.7.4 应用线程 ( 续 ) ——例9_12

其它S

win

g

特性

Page 172: 第9章  图形用户界面 (GUI)

面向对象程序设计

172

在对按钮的 ActionListener 事件监听器的事件处理方法 actionPerformed 方法中,将无限循环放到了另外一个线程中运行,这样就不会影响对标签的鼠标点击事件做出响应了

9.7.4 应用线程 ( 续 ) ——例 9_12 运行结果

其它S

win

g

特性

Page 173: 第9章  图形用户界面 (GUI)

面向对象程序设计

173

9.7.5 定时器

如果需要让程序按照一定时间顺序依次完成某项任务,就需要使用Timer 组件

– 其完整的类名是 javax.swing.Timer

– Timer 组件会根据程序员设定的间隔时间,周期性的触发 ActionEvent

事件– 这个类提供了一系列 API 用于对定时器的各种操作,例如启动、关闭、

设置间隔时间、设置是否只使用一次等

其它S

win

g

特性

Page 174: 第9章  图形用户界面 (GUI)

面向对象程序设计

174

名称 说明Timer(int delay, ActionListener

listener) 创建一个指定间隔时间和事件监听器的定时器

void setDelay(int milliseconds)int getDelay() 设置或获得间隔事件,单位是毫秒

void setInitialDelay(int milliseconds)

int getInitialDelay()

设置或获得首次触发 Timer事件的时间间隔,以后的间隔是 setDealy设置的数值。

void setRepeats(boolean flag)boolean isRepeats()

设置或获得是否可以连续触发,如果是 false,只触发一次事件

void setCoalesce(boolean flag)boolean isCoalesce()

设置或获得定时器是否将若干未处理的一系列事件削减为一个,而不至于积压排队,默认状态是 true

void start() 开启定时器

void restart() 取消当前定时器事件,并在 initialDelay间隔后重新开启定时器

void stop() 关闭定时器

boolean isRunning 获得定时器是否在运行

9.7.5 定时器 ( 续 ) ——Timer 类常用 API

其它S

win

g

特性

Page 175: 第9章  图形用户界面 (GUI)

面向对象程序设计

175

import java.awt.*;import java.awt.event.*;import javax.swing.*;public class AnimatorApplicationTimer extends JFrame implements ActionListener { int frameNumber = -1; Timer timer; boolean frozen = false; JLabel label; AnimatorApplicationTimer(int fps, String windowTitle) { super(windowTitle); int delay = (fps > 0) ? (1000 / fps) : 100; //Set up a timer that calls this object's action handler. timer = new Timer(delay, this); timer.setInitialDelay(0); timer.setCoalesce(true);

9.7.5 定时器 ( 续 ) ——AnimatorApplicationTimer.java

其它S

win

g

特性

Page 176: 第9章  图形用户界面 (GUI)

面向对象程序设计

176

addWindowListener(new WindowAdapter() {

public void windowIconified(WindowEvent e) { stopAnimation();}

public void windowDeiconified(WindowEvent e) {startAnimation();}

public void windowClosing(WindowEvent e) {System.exit(0);}

});

label = new JLabel("Frame ", JLabel.CENTER);

label.addMouseListener(new MouseAdapter() {

public void mousePressed(MouseEvent e) {

if (frozen) { frozen = false; startAnimation(); }

else { frozen = true; stopAnimation(); }

}

});

getContentPane().add(label, BorderLayout.CENTER);

}

9.7.5 定时器 ( 续 ) ——AnimatorApplicationTimer.java

其它S

win

g

特性

Page 177: 第9章  图形用户界面 (GUI)

面向对象程序设计

177

//Can be invoked by any thread (since timer is thread-safe). public void startAnimation() { if (frozen) { //Do nothing. The user has requested that we //stop changing the image. } else { //Start animating! if (!timer.isRunning()) { timer.start(); } } } //Can be invoked by any thread (since timer is thread-safe). public void stopAnimation() { //Stop the animating thread. if (timer.isRunning()) { timer.stop(); } }

9.7.5 定时器 ( 续 ) ——AnimatorApplicationTimer.java

其它S

win

g

特性

Page 178: 第9章  图形用户界面 (GUI)

面向对象程序设计

178

public void actionPerformed(ActionEvent e) { //Advance the animation frame. frameNumber++; label.setText("Frame " + frameNumber); } public static void main(String args[]) { AnimatorApplicationTimer animator = null; int fps = 10; //Get frames per second from the command line argument. if (args.length > 0) { try { fps = Integer.parseInt(args[0]);} catch (Exception e) {} } animator = new AnimatorApplicationTimer(fps, "Animator with Timer"); animator.pack(); animator.setVisible(true); animator.startAnimation(); }}

9.7.5 定时器 ( 续 ) ——AnimatorApplicationTimer.java

其它S

win

g

特性

Page 179: 第9章  图形用户界面 (GUI)

面向对象程序设计

179

说明– 为窗口通过 addWindowListener 方法添加了事件监听器,窗口最小化时停止 Timer ,窗口恢复时重新启动 Timer

– 为标签通过 addMouthListener 方法添加了事件监听器,在标签上点击时可以交替暂停和启动 Timer

– Timer 组件会根据程序员设定的间隔时间,周期性的触发ActionEvent 事件,在 ActionEvent 中让标签上显示的信息递增

9.7.5 定时器 ( 续 ) ——AnimatorApplicationTimer 运行结果

其它S

win

g

特性

Page 180: 第9章  图形用户界面 (GUI)

面向对象程序设计

180

9.8 本章小结

本章内容– Applet 的概念及基本方法– Java 的绘图机制,及实现更为出色绘图效果的 Java

2D– Swing 的结构层次、布局管理,以及如何为其编写事件处理程序

– 很多 Swing 组件都要使用的特色如 Action 对象、边框、外观风格、线程、定时器

本章要求– 掌握图形用户界面程序的编程方法、思路,学会在

Applet和 Application 中引入图形用户界面– 了解 Java 的图形环境,绘制简单图形– 掌握 Swing 的结构和特点,学会使用布局管理、事件处理,以及常用的 Swing 组件