当前位置:课程学习>>第八章 图形界面程序设计>>文本学习>>知识点一
一、概述
本章介绍的内容是Java图形程序设计。图形用户界面(Graphic User Interface, GUI)广泛地应用于客户机/服务器应用程序和基于Web的applet小程序。
在最初引入Java的阶段,一般使用抽象窗口工具集(Abstract Window Toolkit, AWT)库中的图形组件。对Java运行的各个平台,AWT的组件通过它们各自的代理映射成平台特定的组件,这些代理称为同位体(peer)。AWT仅适用于简单的GUI程序,缺少剪贴板、打印支持、键盘导航等特性,原来的AWT甚至不包括弹出式菜单或滚动窗格等基本元素。此外,AWT容易发生平台特定故障,这是由于它的基于同位体的解决方案非常依赖于底层平台。
随着Java2的发展,AWT的用户界面组件被更稳定、通用、灵活的库取代,这个库就是Swing组件库。Swing是由100%纯Java实现的,Swing组件是用Java实现的轻量级(light-weight)组件,没有本地代码,不依赖操作系统的支持,这是它与AWT组件的最大区别。对应地,AWT组件被称为重型(heavy-weight)组件,它们必须使用特定系统上的本地GUI来绘制。Swing比AWT组件具有更强的实用性,在不同的平台上表现一致,并且有能力提供本地窗口系统不支持的其它特性。尽管Java2仍然支持AWT组件,建议在学习的过程中使用Swing组件编程,因为Swing用户界面组件具有更高的优势和更好的发展前景。
Java提供了丰富的有助于创建图形用户界面的类,这些类包括框架、面板、标签、文本域、文本区、组合框、复选框、单选按钮、菜单、滚动条、滚动窗格和选项卡等。
目前,Swing组件不能取代AWT的全部类,只能替代AWT的用户界面组件(Button、TextField、TextArea等),其他辅助类(Graphics、Color、Font、FontMetrics、LayoutManager)仍保持不变。此外,Swing组件仍使用AWT的事件模型。
二、Java图形类层次
Java图形程序类可以分为三组:容器类(container class)、界面组件类(component class)和辅助类(helper class)。容器类,如JFrame、JPanel和JApplet等,用来包含其他组件。界面组件类,如JButton、JTextField、JTextArea、JLabel、JComboBox、JList、JRadioButton和JMenu等,都是JComponent类的子类,它们是构建图形用户界面的基本元素。辅助类,如Color、Font、FontMetrics、Dimension和LayoutManager等,是组件和容器用于绘制和放置对象的。
三、框架
Java程序有两种类别的应用,分别是应用程序application和小程序applet(applet是嵌入在HTML网页中以Web方式调用,参见第9章内容)。application需要创建并处理框架。
1. 创建框架
JFrame类在包javax.swing中,在创建框架时需要包含导入语句:
import javax.swing.*;
JFrame类的构造方法有两个,用于创建JFrame对象。
public JFrame();
创建一个空标题的JFrame对象。
public JFrame(String title);
创建一个指定标题的JFrame对象。
【例8.1】 创建框架的简单程序。
//MyFrame.java
import javax.swing.*;
public class MyFrame {
public static void main(String[] args) {
JFrame frame = new JFrame("Simple Frame");
frame.setSize(400, 120);
frame.setVisible(true);
}
}
运行结果:
方法setSize(400, 120)指定框架的宽度和高度分别为400和120像素。如果不使用setSize方法,框架的宽度和高度都是0,在这种情况下仅能观察到标题栏。方法setVisible(true)指定框架可见,创建完框架后,不调用该方法的话,框架就不会显示。如果要在程序运行过程中隐藏框架窗口,可将参数设置为false。
2. 调整框架的外观
在默认情况下,框架显示在屏幕的左上角。要在指定的位置显示框架,可调用setLocation(int x, int y)方法,该方法将框架放置在屏幕的(x, y)处。
许多情况下要求框架居中显示。要实现这个要求,首先需要计算屏幕的宽和高,以便确定框架的位置坐标。屏幕的尺寸可以通过java.awt.Toolkit类得到,java.awt.Dimension类的实例封装了宽度和高度。语句为:
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
而框架的大小可以通过setSize方法得到。
Dimension frameSize = frame.getSize();
根据屏幕尺寸和框架大小可以确定框架的位置,如图8.1所示。
int x = (screenWidth–frameSize.width())/2;
int y = (screenHeight–frameSize.height())/2;
图 8.1居中显示框架
最大化框架窗口的语句如下:
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
禁止框架窗口大小被改变的语句如下:
frame.setResizable(false);
3. 向框架中添加组件
框架作为容器,允许向其内容窗格中加入组件。例如:
frame.getContentPane().add(new JButton(“OK”));
JFrame类中的getContentPane方法可以返回框架的内容窗格,其中包含了框架中的各个组件。实例中使用new JButton来创建按钮对象,并添加到内容窗格中。如图8.2所示。
图8.2 在框架中添加组件
不管如何调整框架的大小,按钮始终保持处于内容窗格的中央,并且占据整个窗格。此时,框架使用的是默认的布局管理器。
四、布局管理器
在容器中放置的GUI组件,是由容器的布局管理器来安排位置的。在8.3.3节的例中,虽然没有指定按钮对象的位置,但是框架frame的布局管理器能够将组件放置在合适的位置。
布局管理器包括:FlowLayout、GridLayout、BorderLayout、CardLayout和GridBagLayout等。它们都包含在java.awt包内,实现了LayoutManager接口。在使用时需要导入语句:
import java.awt.*;
为容器设置布局管理器的语法为:
container.setLayout(new SpecificLayout());
其中,容器container可以是JFrame、JApplet或是JPanel的内容窗格,SpecificLayout则指定了某种布局管理器。
在下面的内容中,就FlowLayout、GridLayout、BorderLayout三种布局管理器进行介绍。
1. FlowLayout布局管理器
FlowLayout布局管理器使用最为简单,是按照组件添加的顺序由左至右排列在容器内,一行排满后自动排列新一行。在FlowLayout中可以指定组件的对齐方式,即:FlowLayout.RIGHT(居右)、FlowLayout.CENTER(居中)和FlowLayout.LEFT(居左)。并且允许指定组件间距的像素值。
FlowLayout有三个构造方法。
public FlowLayout()
创建一个FlowLayout对象,默认的对齐方式是居中对齐,水平和垂直间距都是5个像素。
public FlowLayout(int align)
按照指定的对齐方式创建FlowLayout对象,默认的水平和垂直间距都是5个像素。
public FlowLayout(int align, int hGap, int vGap)
这个方法按照指定的对齐方式和间距创建FlowLayout对象。
【例8.2】 演示FlowLayout布局管理器的使用,在例子中对框架中的10个按钮进行排列。
//FlowLayoutTest.java
import javax.swing.*;
import java.awt.*;
public class FlowLayoutTest extends JFrame {
public FlowLayoutTest() {
getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
for (int i = 1; i <= 10; i++)
getContentPane().add(new JButton("Button " + i));
}
public static void main(String args[]) {
FlowLayoutTest frame = new FlowLayoutTest();
frame.setTitle("Test FlowLayout");
frame.setSize(400, 150);
frame.setVisible(true);
}
}
运行结果:
在实例中的FlowLayoutTest是JFrame的派生类。在构造方法中使用FlowLayout布局管理器对框架中的组件进行排列。指定的布局方式为左对齐,且水平和垂直间距都为10个像素。在调整框架的大小时,组件会随之自动地排列以适合框架。setTitle方法是在java.awt.Frame类中定义的,为Frame指定标题。JFrame类是Frame类的派生类,可以继承该方法。
2. GridLayout布局管理器
GridLayout布局管理器是以指定的行数和列数构建一个网格(二维矩阵)的形式来对组件进行排列。组件按照添加的顺序从左至右排列,从第一行开始,依次类推。GridLayout也有三个构造方法。
public GridLayout()
以每行一列的方式构造一个新的GridLayout对象。
public GridLayout(int rows, int cols)
根据指定的行数和列数构造一个新的GridLayout对象。默认的水平和垂直间距为0。
public GridLayout(int rows, int cols, int hGap, int vGap)
该方法根据指定的行数和列数,以及组件的水平和垂直间距构造一个新的GridLayout对象。
网格的行数和列数的基本规则为:
(1) 行数或列数可以为0,但不能全为0。当其中一个维数为0时,不为0的维数由指定值固定,为0的维数由GridLayout动态计算。例如,如果指定网格的行数为0,列数为3,组件的个数为10。GridLayout创建4行3列的网格,其中第4行仅第1个单元格内包含一个组件。
(2) 如果行数和列数都不为0,则行数为固定的,列数被忽略,并由布局管理器动态计算。如果指定一个3行3列的GridLayout,且组件数为10。GridLayout创建3行4列的网格,其中第3行包含2个组件。
【例8.3】 用GridLayout布局管理器在框架中排列组件,演示的是创建一个4行3列的GridLayout,且包含10个按钮。
//TestGridLayout.java
import javax.swing.*;
import java.awt.*;
public class TestGridLayout extends JFrame {
public TestGridLayout() {
getContentPane().setLayout(new GridLayout(4, 3, 5, 5));
for (int i = 1; i <= 10; i++)
getContentPane().add(new JButton("Button " + i));
}
public static void main(String args[]) {
TestGridLayout frame = new TestGridLayout();
frame.setTitle("Test GridLayout");
frame.setSize(400, 150);
frame.setVisible(true);
}
}
运行结果:
3. BorderLayout布局管理器
BorderLayout布局管理器将内容窗格分为五个部分:BorderLayout.EAST(东区)、BorderLayout.SOUTH(南区)、BorderLayout.WEST(西区)、BorderLayout.NORTH(北区)和BorderLayout.CENTER(中央)。使用add(component, index)方法可以将组件添加到布局管理器中,其中index代表五个部分中的指定值。 BorderLayout是JFrame采用的默认布局。BorderLayout布局中,add方法允许省略参数index,默认为BorderLayout.CENTER。
BorderLayout有两个构造方法。
public BorderLayout()
该方法构造一个新的BorderLayout对象,各个组件之间的水平间距和垂直间距为0。
public BorderLayout(int hGap, int vGap)
该方法根据指定的水平和垂直间距来构造BorderLayout对象。
组件根据它们最合适的尺寸和在容器中的位置来放置。南区和北区的组件可以水平扩展,东区和西区的组件可以竖直拉伸,中央组件既可以水平扩展也可以竖直拉伸以填满空白区域。
【例8.4】 使用BorderLayout布局管理器在框架中排列组件,分别在东区、南区、西区、北区和中央位置放置按钮组件。
//TestBorderLayout.java
import javax.swing.*;
import java.awt.*;
public class TestBorderLayout extends JFrame {
public TestBorderLayout() {
getContentPane().setLayout(new BorderLayout(5, 5));
getContentPane().add(new JButton("East"), BorderLayout.EAST);
getContentPane().add(new JButton("South"), BorderLayout.SOUTH);
getContentPane().add(new JButton("West"), BorderLayout.WEST);
getContentPane().add(new JButton("North"), BorderLayout.NORTH);
getContentPane().add(new JButton("Center"), BorderLayout.CENTER);
}
public static void main(String[] args) {
TestBorderLayout frame = new TestBorderLayout();
frame.setTitle("Test BorderLayout");
frame.setSize(400, 150);
frame.setVisible(true);
}
}
运行结果:
在BorderLayout布局中的组件按照所在的区域自动延伸。
五、颜色和字体
1. 颜色
可以使用java.awt.Color类为GUI组件设置颜色。颜色由红、绿、蓝三种原色组成,每种原色的亮度用一个byte值表示,从0(最暗)到255(最亮),也就是所说的RGB模式。
Color对象的构造方法为:
public Color(int r, int g, int b)
java.awt.Color将13种标准颜色定义为常量,可以使用类似Color.RED的方式来使用。
可以调用Component类的setBackground和setForeground方法来设置组件的背景色和前景色。例如:
JPanel panel = new JPanel();
Panel.setBackground(new Color(255, 0, 0));
2. 字体
字体和字体尺度包含在Font和FontMetrics类中。
设置字体时,需要从Font类中创建Font对象,构造方法如下:
public Font(String name, int style, int size)
name指定了字体名,常用的字体名包括ScanSerif、Serif、Monospaced、Dialog等;style指定了字型,可以选择Font.PLAIN、Font.BOLD和Font.ITALIC,字型可以组合使用;size指定了字体的字号。如:
Font font1 = new Font(“ScanSerif”, Font.BOLD, 16);
Font font2 = new Font(“Serif”, Font.BOLD+Font.ITALIC, 12);
FontMetrics类用来计算字符串的精确长度和宽度,对于度量字符串的大小以便在正确的位置显示是非常有效的。FontMetric的属性包括:
Leading:表示文本行之间的距离。
Ascent:表示字符从基线到其顶端的高度。
Descent:对于j、y、g等字符,表示从基线到底端的距离。
Height:是前三项的总和。
这些属性参见下图:
图 8.3 FontMetrics的属性量度
FontMetric对象的获取,需要调用Graphics类的getFontMetrics方法:
public FontMetrics getFontMetrics()
获取当前字体的FontMetrics信息。
public FontMetrics getFontMetrics(Font font)
获取字体font的FontMetrics信息。
字体信息的获取方法包括:
public int getAscent()
public int getDescent()
public int getLeading()
public int getHeight()
public int stringWidth(String str)
六、图形绘制
与字符串的绘制类似,图形绘制也是由java.awt.Graphics类实现的,通常在面板JPanel进行绘制。
1. 绘制基本图形
(1)绘制直线 (2)绘制矩形 (3)绘制椭圆
2. 绘制直线
绘制直线的方法为:
public void drawLine(int x1, int y1, int x2, int y2)
其中,参数指定了直线的起点(x1, y1)和终点(x2, y2)。
3. 绘制多边形
Polygon类封装了坐标空间中封闭的二维区域的描述。此区域以任意条线段为边界,每条线段都是多边形的一条边。在内部,一个多边形包含一列 (x, y) 坐标对,其中每个坐标对定义多边形的一个顶点,且两个连续的坐标对是多边形一条边的端点。第一个和最后一个 (x, y) 坐标通过一条线段相连,形成一个封闭的多边形。
Polygon的构造方法包括:
public Polygon()
方法创建了一个空的Polygon对象,通过调用addPoint(int x, int y)方法来增加顶点。
public Polygon(int[] xPoints, int[] yPoints, int nPoints)
其中,xpoints和ypoints指定了多边形的一系列顶点,npoints指示了顶点的个数。可以使用Polygon对象来绘制多边形,方法如下:
public void drawPolygon(Polygon poly)
语句如下:
int[] xpoints = {40, 70, 60, 45, 20};
int[] ypoints = {20, 40, 80, 45, 60};
Polygon poly = new Polygon(xpoints, ypoints, 5);
g.drawPolygon(poly);
也可以用数组来直接绘制多边形。
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
另外,可以调用方法来绘制不封闭的多边形,它绘制有x坐标和y坐标数组定义的相连线段,如果第一个点不同于最后一个点则图形不封闭。方法如下:
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
4. 图形绘制实例
【例8.5】 在面板中绘制一个时钟,该时钟由时针、分针和秒针组成,画表针需要确定两个端点,一个端点是时钟的中心(xCenter,yCenter),另一个端点(x,y)由下面的算式决定。
x = xCenter +handLen * sin(a);
y = yCenter - handLen * cos(a);
角度a的单位是弧度,令hour、minute和second分别表示当前的时、分、秒。
时针的角度为:(hour%12+minute/60+second/(60*60))*(2*PI/12)
分针的角度为:(minute+second/60)*(2*PI/60)
秒针的角度为:second*(2*PI/60)
为了简单起见,在计算时针和分针角度时,可以忽略秒数,因为秒数的影响非常小。
//DisplayClock.java
import javax.swing.*;
import java.awt.*;
public class DisplayClock extends JFrame {
private ClockPanel panel = new ClockPanel();
public DisplayClock() {
panel.setTime(21, 5, 25);
getContentPane().add(panel);
}
public static void main(String[] args) {
DisplayClock frame = new DisplayClock();
frame.setTitle("Display Clock");
frame.setSize(200, 200);
frame.setVisible(true);
}
}
class ClockPanel extends JPanel {
private int hour = 0, minute = 0, second = 0;
private int xCenter, yCenter;
private int radius;
public void setTime(int hour, int minute, int second) {
if (hour < 0) this.hour = 0;
else if (hour > 23) this.hour = 23;
else this.hour = hour;
if (minute < 0) this.minute = 0;
else if (minute > 59) this.minute = 59;
else this.minute = minute;
if (second < 0) this.second = 0;
else if (second > 59) this.second = 59;
else this.second = second;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Initialize clock parameters
radius = (int) (Math.min(getSize().width, getSize().height) * 0.7 / 2);
xCenter = (getSize().width) / 2;
yCenter = (getSize().height) / 2;
// Draw circle
g.drawOval(xCenter - radius, yCenter - radius, 2 * radius, 2 * radius);
g.drawString("3", xCenter + radius, yCenter + 3);
g.drawString("6", xCenter - 3, yCenter + radius + 10);
g.drawString("9", xCenter - radius - 8, yCenter + 3);
g.drawString("12", xCenter - 5, yCenter - radius);
// Draw hour hand
int hLen = (int) (radius * 0.5);
int xHour = (int) (xCenter + hLen * Math.sin((hour % 12 + minute / 60.0) * (2 * Math.PI / 12) );
int yHour = (int) (yCenter - hLen * Math.cos((hour % 12 + minute / 60.0) * (2 * Math.PI / 12)));
g.drawLine(xCenter, yCenter, xHour, yHour);
// Draw minute hand
int mLen = (int) (radius * 0.75);
int xMinute = (int) (xCenter + mLen * Math.sin(minute * (2 * Math.PI / 60)));
int yMinute = (int) (yCenter - mLen * Math.cos(minute * (2 * Math.PI / 60)));
g.drawLine(xCenter, yCenter, xMinute, yMinute);
// Draw second hand
int sLen = (int) (radius * 0.9);
int xSecond = (int) (xCenter + sLen * Math.sin(second * (2 * Math.PI / 60)));
int ySecond = (int) (yCenter - sLen * Math.cos(second * (2 * Math.PI / 60)));
g.drawLine(xCenter, yCenter, xSecond, ySecond);
}
}
运行结果:
七、事件处理
在介绍Swing组件之前,首先要了解Java的事件处理方式。Java采用事件驱动的程序设计的方式,激活某个事件就开始执行相应的代码。
1. 事件和事件源
运行Java图形程序时,用户与程序进行交互,由事件来驱动程序的执行。事件(event)可以定义为程序发生某件事情的信号。用户行为,如点击按钮、移动或点击鼠标、按下键盘键等,可以引发事件。此外,操作系统如时钟等,也可以引发事件。程序可以对事件进行响应或忽略。
发生事件的组件对象称为事件源(event source)。例如,按钮是点击按钮事件的事件源。一个事件是事件类的实例,事件类的根类是java.util.EventObject。事件对象包含于事件有关的一系列属性,可以使用EventObject类的getSource方法来获得事件源。EventObject的子类处理特定类型的事件,事件、事件源和事件类的对应关系见下表。
表8.1 事件、事件源和事件对象
事件 |
事件源 |
事件类 |
点击按钮 |
JButton |
ActionEvent |
改变文本 |
JTextComponent |
TextEvent |
在文本域按下回车键 |
JTextField |
ActionEvent |
选定一个新项 |
JComboBox |
ItemEvent, ActionEvent |
选定(多)项 |
JList |
ListSelectionEvent |
点击复选框 |
JCheckBox |
ItemEvent, ActionEvent |
点击单选按钮 |
JRadioButton |
ItemEvent, ActionEvent |
选定菜单项 |
JMenuItem |
ActionEvent |
移动滚动条 |
JScrollBar |
AdjustmentEvent |
窗口打开、关闭、最小化、还原或正在关闭 |
Window |
WindowEvent |
在容器中添加或删除组件 |
Container |
ConainerEvent |
组件移动、改变大小、隐藏或显示 |
Component |
ComponentEvent |
组件获得或失去焦点 |
Component |
FocusEvent |
按下或释放键盘键 |
Component |
KeyEvent |
鼠标移动、点击 |
Component |
MouseEvent |
除了ListSelectionEvent包含在包javax.swing.event中,其余的事件类都包含在包java.awt.event中。
2. 事件注册、监听
事件要执行的话,需要在事件源对象上注册对应事件的监听器(listener)。Java使用事件委托处理模型来处理事件,在事件源对象上的外部行为引发事件,由监听器负责接收事件。
一般来说,不同的事件类需要实现不同的监听器接口,在接口中定义了不同的监听器方法,如表8.2所示。同时,一个事件源对象可以对应多个监听器,它拥有一个由监听器构成的队列。
表8.2 事件及其对应的监听器接口和方法
事件类 |
监听器接口 |
监听器方法 |
ActionEvent |
ActionListener |
actionPerformed(ActionEvent e) |
ItemEvent |
ItemListener |
itemStateChanged(ItemEvent e) |
WindowEvent |
WindowListener |
windowClosing(WindowEvent e) windowOpened(WindowEvent e) windowIconified(WindowEvent e) windowDeiconified(WindowEvent e) windowClosed(WindowEvent e) windowActivated(WindowEvent e) windowDeactivated(WindowEvent e) |
ContainerEvent |
ContainerListener |
componentAdded(ContainerEvent e) componentRemoved(ContainerEvent e) |
ComponentEvent |
ComponentListener |
componentMoved(ComponentEvent e) componentHidden(ComponentEvent e) componentResized(ComponentEvent e) componentShown(ComponentEvent e) |
FocusEvent |
FocusListener |
focusGained(FocusEvent e) focusLost (FocusEvent e) |
TextEvent |
TextListener |
textValueChanged(TextEvent e) |
KeyEvent |
KeyListener |
keyPressed(KeyEvent e) keyReleased(KeyEvent e) keyTyped(KeyEvent e) |
MouseEvent |
MouseListener MouseMotion Listener |
mousePressed(MouseEvent e) mouseReleased(MouseEvent e) mouseEntered(MouseEvent e) mouseExited(MouseEvent e) mouseClicked(MouseEvent e) mouseDragged(MouseEvent e) mouseMoved(MouseEvent e) |
AdjustmentEvent |
AdjustmentListener |
adjustmentValueChanged(AdjustmentEvent e) |
例如,如果一个框架中的按钮JButton对象的点击事件需要响应,必须由JButton对象注册,即通过JButton对象的方法来声明框架对象是JButton对象的监听器。同时,设置监听器方法,在监听器方法中实现对事件的处理代码。当点击按钮时,JButton对象产生一个ActionEvent事件并且通知监听器,通过调用在监听器方法中的代码来处理该点击事件。
JFrame需要实现监听器接口ActionListener。语句类似于:
public class TestActionEvent extends JFrame implements ActionListener {}
还要为按钮对象注册监听器:
button.addActionListener(this);
定义的监听器方法为:
public void actionPerformed(ActionEvent e) {}
在语句中,this代表JFrame对象,即声明JFrame对象是JButton对象的监听器。
3. 事件处理
监听器方法接到通知后,开始执行并进行事件处理。事件对象传递给事件处理方法,它包含与事件类型相关的信息。从事件对象中可以得到处理事件的相关数据。例如,可以使用方法e.getSource()得到源对象,用以判断事件源的类型等。
【例8.6】在框架中放置”OK”按钮,点击按钮后弹出消息框。
//ActionEventTest.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ActionEventTest extends JFrame implements ActionListener {
private JButton okBtn = new JButton("OK");
public ActionEventTest() {
okBtn.addActionListener(this);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(okBtn);
}
public static void main(String[] args) {
ActionEventTest frame = new ActionEventTest();
frame.setTitle("Button Action");
frame.setSize(400, 150);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == okBtn)
JOptionPane.showMessageDialog(okBtn, "Click OK button!");
}
}
运行结果:
【例8.7】对窗口事件的处理。在程序中监听框架窗口的打开和正在关闭事件,响应事件时弹出消息提示框。
//WindowEventTest.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WindowEventTest extends JFrame implements WindowListener {
public WindowEventTest() {
addWindowListener(this);
}
public static void main(String[] args) {
WindowEventTest frame = new WindowEventTest();
frame.setTitle("Window Event Test");
frame.setSize(400, 150);
frame.setVisible(true);
}
public void windowOpened(WindowEvent e) {
JOptionPane.showMessageDialog(this, "Open window!");
}
public void windowClosing(WindowEvent e) {
JOptionPane.showMessageDialog(this, "Closing window!");
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowClosed(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
}
由于WindowEventTest实现了WindowListener接口,必须定义WindowListener类定义的全部抽象方法,包括windowIconified等。