当前位置:课程学习>>第八章 图形界面程序设计>>文本学习>>知识点一


知识点一  图形界面设计




一、概述

本章介绍的内容是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);

  }

}

运行结果:

1

方法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;

1

图 8.1居中显示框架

最大化框架窗口的语句如下:

   frame.setExtendedState(JFrame.MAXIMIZED_BOTH);

禁止框架窗口大小被改变的语句如下:

   frame.setResizable(false);

3. 向框架中添加组件

框架作为容器,允许向其内容窗格中加入组件。例如:

frame.getContentPane().add(new JButton(“OK”));

JFrame类中的getContentPane方法可以返回框架的内容窗格,其中包含了框架中的各个组件。实例中使用new JButton来创建按钮对象,并添加到内容窗格中。如图8.2所示。

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);

 }

}

运行结果:

3

在实例中的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);

  }

}

运行结果:

4

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);

  }

}

运行结果:

5

在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:是前三项的总和。

这些属性参见下图:

4

图 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);

  }

}

运行结果:

7

七、事件处理

在介绍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

【例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等。

 

进入知识点二学习