Java图形界面编程

一、Java图形用户界面(gui)介绍

1、Java GUI简介

  图形用户界面(Graphics User Interface,GUI)是用户与程序交互的窗口,比命令行的界面更加直观并且更好操作。


  Sun已经提供了一个跨平台GUI开发工具包AWT抽象窗口工具箱(Abstract Window Toolkit)。
  Sun又创建了一个新的GUI框架swing。解决了AWT存在的Icd问题。
  IBM认为swing比较消耗内存,创建了一个新的GUI库,这就是SWT。
  IBM为了方便开发SWT程序,在SWT基础上又创建了一个更易用,功能强大的图开包"JFace"。
  AWT(Abstract Window Toolkit):抽象窗口工具包,早期编写图形界面应用程序的包。 AWT的图形函数与操作系统提供的图形函数有着一一对应的关系。也就是说,当我们利用 AWT构件图形用户界面的时候,实际上是在利用操作系统的图形库。
        AWT的层次关系

  Swing:为解决 AWT 存在的问题而新开发的图形界面包。Swing是对AWT的改良和扩展。 不仅提供了AWT 的所有功能,还用纯粹的Java代码对AWT的功能进行了大幅度的扩充,与平台无关。
        Swing组件层次关系


2、AWT和Swing的区别与联系

  AWT和Swing都是java中的包。
  AWT(Abstract Window Toolkit):抽象窗口工具包,早期编写图形界面应用程序的包。
  Swing:为解决 AWT 存在的问题而新开发的图形界面包。Swing是对AWT的改良和扩展。
  AWT和Swing的实现原理不同:
  AWT的图形函数与操作系统提供的图形函数有着一一对应的关系。也就是说,当我们利用 AWT构件图形用户界面的时候,实际上是在利用操作系统的图形库。
  不同的操作系统其图形库的功能可能不一样,在一个平台上存在的功能在另外一个平台上则可能不存在。为了实现Java语言所宣称的"一次编译,到处运行"的概念,AWT不得不通过牺牲功能来实现平台无关性。因此,AWT 的图形功能是各操作系统图形功能的“交集”。
  因为AWT是依靠本地方法来实现功能的,所以AWT控件称为“重量级控件”。
  而Swing,不仅提供了AWT 的所有功能,还用纯粹的Java代码对AWT的功能进行了大幅度的扩充。例如:并不是所有的操作系统都提供了对树形控件的支持,Swing则利用了AWT中所提供的基本作图方法模拟了一个树形控件。
  由于 Swing是用纯粹的Java代码来实现的,因此Swing控件在各平台通用。因为Swing不使用本地方法,故Swing控件称为“轻量级控件”。
  AWT和Swing之间的区别:
  1)、AWT 是基于本地方法的C/C++程序,其运行速度比较快;Swing是基于AWT的Java程序,其运行速度比较慢。
  2)、AWT的控件在不同的平台可能表现不同,而Swing在所有平台表现一致。
  在实际应用中,应该使用AWT还是Swing取决于应用程序所部署的平台类型。例如:
  1)、对于一个嵌入式应用,目标平台的硬件资源往往非常有限,而应用程序的运行速度又是项目中至关重要的因素。在这种矛盾的情况下,简单而高效的AWT当然成了嵌入式Java的第一选择。
  2)、在普通的基于PC或者是工作站的标准Java应用中,硬件资源对应用程序所造成的限制往往不是项目中的关键因素。所以在标准版的Java中则提倡使用Swing,也就是通过牺牲速度来实现应用程序的功能。
  在java中,AWT包的名称是java.awt,Swing包的名称是javax.swing。

二、Swing的基本使用

1、几个常用的组件

  1、文本框(JTextField)
  2、密码框(JPasswordField)
  3、标签(JLable)
  4、复选框组件(JCheckBox)
  5、单选框组件(JRadioButton):同一组单选按钮必须先创建ButtonGroup,然后把单选框组件放入到ButtonGroup中。



  6、下拉框(JComboBox)
  7、列表框(JList)
  8、滚动窗格(JScrollPane)

  9、列表框(JList)和滚动窗格(JScrollPane)一般会一起使用。
  10、拆分窗格(JSpitPane):属于容器类组件。
  11、JTextArea:多行文本框。
  12、JTabbedPane:选项卡窗格(业签组件)。
  13、JMenuBar:菜单条组件
  14、JMenu:菜单组件
  15、JMenuItem:菜单项组件
  16、JToolBar:容器类组件

2、Java布局管理

  Java为我们提供了几个常用的布局管理器类,例如:FlowLayout、BorderLayout、GridLayout、GridBagLayout等。
  1、java.awt FlowLayout(流布局) 将组件按从左到右而后从上到下的顺序依次排列,一行不能放完则折到下一行继续放置。流式布局可以以左对齐、居中对齐、右对齐的方式排列组件。


  流式布局不限制他所管理的组件的大小,允许他们有最佳的大小。当容器最缩放时,组件的位置可以改变,但组件的大小不改变。JPanel的默认布局为流式布局管理。
  2、java.awt BorderLayout(边界布局) 将组件按东、南、西、北、中五个区域放置,每个方向最多只能放置一个组件。

  JFrame窗体,JDialog对话框组件默认布局方法为边界布局(BorderLayout),边界布局的五个部分不是都要添加,中间部分会自动调节大小。
  3、java.awt GridLayout(网格布局) 形似一个无框线的表格,每个单元格中放一个组件。将容器分割成多行多列,组件被填充到每个网格中,添加到容器中的组件首先放置在左上角的网格中,然后从左到右放置其他组件,当占满该行的所有网格后,接着继续在下一行从左到右放置组件。

  组件的相对位置不随容器的缩放而改变,但大小会改变,所有组件的大小相同。
  可以通过GridLayout(int rows, int cols, int hgap, int vgap)来指定网格的行/列,水平间隙/垂直间隙。
  java.awt GridBagLayout 非常灵活,可指定组件放置的具体位置及占用单元格数目。


  4、一个界面只可以有一个JFrame窗体组件,但可以有多个Jpanel面板组件,而JPanel上也可使用各种布局管理器,这样可以组合使用达到较为复杂的布局效果。
  JPanel是JComponent的子类。默认布局为流式布局(FlowLayout),属于容器类组件,可以加入别的组件。

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MultiLayout extends JFrame {
    private static final long serialVersionUID = 1L;
    
    // 定义组件
    JPanel jp1, jp2;
    JButton jb1, jb2, jb3, jb4, jb5, jb6;

    public static void main(String[] args) {
        new MultiLayout();
    }

    public MultiLayout() {
        // 创建组件
        // JPanel布局默认是FlowLayout流布局
        jp1 = new JPanel();
        jp2 = new JPanel();

        jb1 = new JButton("西瓜");
        jb2 = new JButton("苹果");
        jb3 = new JButton("荔枝");
        jb4 = new JButton("葡萄");
        jb5 = new JButton("桔子");
        jb6 = new JButton("香蕉");

        // 设置布局管理器(Jpanel默认流布局)
        jp1.add(jb1);
        jp1.add(jb2);
        jp2.add(jb3);
        jp2.add(jb4);
        jp2.add(jb5);

        // 把Panel加入JFrame
        this.add(jp1, BorderLayout.NORTH);
        this.add(jb6, BorderLayout.CENTER);
        this.add(jp2, BorderLayout.SOUTH);

        // 设置窗体
        // 窗体大小
        this.setSize(300, 250);
        // 屏幕显示初始位置
        this.setLocation(200, 200);
        // 显示
        this.setVisible(true);
        // 退出窗体后将JFrame同时关闭
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

  5、 GroupLayout(分组布局) ,它将组件按层次分组,以决定它们在 Container 中的位置。GroupLayout 主要供生成器使用,但也可以手工编码。分组由 Group 类的实例来完成。GroupLayout 支持两种组。串行组 (sequential group) 按顺序一个接一个地放置其子元素。并行组 (parallel group)能够以四种方式对齐其子元素。
  每个组可以包含任意数量的元素,其中元素有 Group、Component 或间隙 (gap)。间隙可被视为一个具有最小大小、首选大小和最大大小的不可见组件。此外,GroupLayout 还支持其值取自 LayoutStyle 的首选间隙。
  GroupLayout是一个很重要的布局管理器,在jdk 1.6才加入,配合其它的管理器可以实现很好的界面。GroupLayout必须要设置它的GroupLayout.setHorizontalGroup和GroupLayout.setVerticalGroup。
  GroupLayout.setHorizontalGroup是指按照水平来确定,下面例子“账号”和“密码”是一个级别的,其它的组件也是一个级别的。
  GroupLayout.setVerticalGroup。是按照垂直来确定的。他们的级别是按照Group去设置组件的优先级别,级别越高就显示越上面。

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JRadioButton;
import javax.swing.JTextField;

public class GroupLayoutTest extends JFrame {
    private static final long serialVersionUID = -5159330521192113057L;

    public static void main(String[] args) {
        new GroupLayoutTest();
    }

    JLabel label1;
    JLabel label2;
    JLabel label3;
    JTextField tf;
    JPasswordField psf;
    JRadioButton rb1;
    JRadioButton rb2;
    JButton bt1;
    JButton bt2;

    public GroupLayoutTest() {
        this.setVisible(true);
        this.setSize(250, 220);
        this.setVisible(true);
        this.setLocation(400, 200);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        label1 = new JLabel("登陆界面");
        label2 = new JLabel("账号:");
        label3 = new JLabel("密码:");
        tf = new JTextField();
        psf = new JPasswordField();
        rb1 = new JRadioButton("记住密码");
        rb2 = new JRadioButton("自动登陆");
        bt1 = new JButton("登陆");
        
        // 为指定的 Container 创建 GroupLayout
        GroupLayout layout = new GroupLayout(this.getContentPane());
        this.getContentPane().setLayout(layout);
        
        // 创建GroupLayout的水平连续组,,越先加入的ParallelGroup,优先级级别越高。
        GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
        // 添加间隔
        hGroup.addGap(5);
        hGroup.addGroup(layout.createParallelGroup().addComponent(label2).addComponent(label3));
        hGroup.addGap(5);
        hGroup.addGroup(layout.createParallelGroup().addComponent(label1).addComponent(psf).addComponent(rb1)
                .addComponent(rb2).addComponent(tf).addComponent(bt1));
        hGroup.addGap(5);
        // 设置水平分组
        layout.setHorizontalGroup(hGroup);
        
        // 创建GroupLayout的垂直连续组,,越先加入的ParallelGroup,优先级级别越高。
        GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
        vGroup.addGap(10);
        vGroup.addGroup(layout.createParallelGroup().addComponent(label1));
        vGroup.addGap(10);
        vGroup.addGroup(layout.createParallelGroup().addComponent(label2).addComponent(tf));
        vGroup.addGap(5);
        vGroup.addGroup(layout.createParallelGroup().addComponent(label3).addComponent(psf));
        vGroup.addGroup(layout.createParallelGroup().addComponent(rb1));
        vGroup.addGroup(layout.createParallelGroup().addComponent(rb2));
        vGroup.addGroup(layout.createParallelGroup(Alignment.TRAILING).addComponent(bt1));
        vGroup.addGap(10);
        // 设置垂直组
        layout.setVerticalGroup(vGroup);
    }

}



三、Java绘图技术

   坐标原点位于左上角,以像素为单位。像素是计算机屏幕上最小的显示单位。 在java的坐标系中,第一个是X坐标,表示当前位置为水平方向,距离坐标原点X个像素;第二个是Y坐标,表示当前位置为垂直方向,距离坐标原点Y个像素。


   计算机在屏幕上显示的内容都是由屏幕上的每一个像素组成的。 例如,计算机显示器的分辨率是800×600,表示计算机屏幕上的每一行由800个点组成,共有600行,整个计算机屏幕共有480000个像素。现在的计算机可以支持更高的分辨率,也就是说,屏幕上可以显示更多的像素。因此, 像素是一个密度单位,而厘米是长度单位,两者无法比较。
  Component类提供了两个和绘图相关最重要的方法:
  1、paint(Graphics g)绘制组件的外观;
  2、repaint()刷新组件的外观。
  当组件第一次在屏幕显示的时候,程序会自动的调用paint()方法来绘制组件,在以下情况paint()将会被调用:
  1、窗口最小化,再最大化;
  2、窗口的大小发生变化;
  3、repaint函数被调用。

1、Graphics类

  Graphics类可以理解就是画笔,为我们提供了各种绘制图形的方法:
  1、画直线 drawLine(int x1, int y1, int x2, int y2);
  2、画矩形边框 drawRect(int x, int y, int width, int height);
  3、画椭圆边框 drawOval(int x, int y, int width, int height);
  4、填充矩形 fillRect(int x, int y, int width, int height);
  5、填充椭圆 fillOval(int x, int y, int width, int height);
  6、画图片 drawImage(Image img, int x, int y,..);
  7、画字符串 drawString(String str, int x, int y);
  8、设置画笔的字体 setFont(Font font);
  9、设置画笔的颜色 setColor(Color c);

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GraphicsTest extends JFrame {
    // 定义组件
    MyPanel1 mp = null;
    public static void main(String[] args) {
        new GraphicsTest();
    }

    public GraphicsTest() {
        // 构建组件
        mp = new MyPanel1();
        // 加入组件
        this.add(mp);
        
        // 设置窗体
        this.setSize(400, 300);
        this.setVisible(true);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

/**
 * @Description: 定义一个MyPanel(我自己的面板是用于绘图和显示绘图的区域)
 */
class MyPanel1 extends JPanel {
    private static final long serialVersionUID = 1L;

    // 重写(覆盖)JPanel的paint方法
    public void paint(Graphics g) {
        // 1、调用父类函数,完成初始化任务
        super.paint(g);
        // 画一个直线
        g.drawLine(10, 10, 40, 10);
        // 画矩形边框
        g.drawRect(50, 50, 40, 40);
        // 画椭圆边框
        g.drawOval(130, 130, 60, 60);
        // 画填充矩形
        g.setColor(Color.blue);
        g.fillRect(10, 150, 70, 70);
        
        // 画填充椭圆
        // 设置画笔颜色
        g.setColor(Color.red);
        g.fillOval(270, 140, 100, 80);

        // 如何画出字
        g.setColor(Color.red);
        g.setFont(new Font("黑体", Font.BOLD, 40));
        g.drawString("祖国万岁", 150, 100);
        // 画弧形
        g.drawArc(100, 100, 120, 200, 50, 100);
    }
}



2、Graphics2D类

  Java语言在Graphics类提供绘制各种基本的几何图形的基础上,扩展Graphics类提供一个Graphics2D类,它拥用更强大的二维图形处理能力,提供、坐标转换、颜色管理以及文字布局等更精确的控制。
  绘图属性
  Graphics2D定义了几种方法,用于添加或改变图形的状态属性。可以通过设定和修改状态属性,指定画笔宽度和画笔的连接方式;设定平移、旋转、缩放或修剪变换图形;以及设定填充图形的颜色和图案等。图形状态属性用特定的对象存储。

2.1、stroke属性

  stroke属性控制线条的宽度、笔形样式、线段连接方式或短划线图案。该属性的设置需要先创建BasicStroke对象,再调用setStroke()方法来设置。创建BasicStroke对象的方法有:
  BasicStroke(float w):指定线条宽w。
  BasicStroke(float w, int cap, int join):
  cap是端点样:CAP_BUTT(无修饰),CAP_ROUND(半圆形末端),CAP_SQUARE(方形末端,默认值)。
  Join定义两线段交汇处的连接方式:JOIN_BEVEL(无修饰),JOIN_MTTER(尖形末端,默认值),JOIN_ROUND(圆形末端)。

2.2、paint属性

  paint属性控制填充效果。先调用以下方法确定填充效果,理用setPaint()方法设置。
  GradientPaint(float x1, float y1, Color c1, float x2, flaot y2, Color c2):从(x1, y1)到(x2, y2)颜色从c1渐变到c2。其中:参数c1, c2决定这个渐变色是从颜色c1渐变到颜色c2。参数x1, y1, x2, y2决定了渐变的强弱,即要求从点(x1, y1)出发到达点(x2, y2),颜色从c1变成c2。
  GradientPaint(float x1, float y1, Color c1, float x2, float y2, Color c2, Boolean cyclic):如果希望渐变到终点又是起点的颜色,应将cyclic设置为true。

2.3、transform属性

  transform 属性用来实现常用的图形平移、缩放和斜切等变换操作。首先创建AffineTransform对象,然后调用setTransform()方法设置transform属性。最后,用具有指定属性的Graphics2D对象绘制图形。创建AffineTransform对象的方法有:
  getRotateinstrance(double theta):旋转theta弧度。
  getRotateInstance(double theta, dioble x, double y):绕旋转中心(x, y)旋转。
  getScaleInstance(double sx, double sy):x和y 方向分别按sx, sy比例变换。
  getTranslateInstance(double tx, double ty):平移变换。
  getShearInstance(double shx, double shy):斜切变换,shx和shy指定斜拉度。
  也可以先创建一个没有transform属性的AffineTransform对象,然后用以下方法指定图形平移、旋转、缩放变换属性。
  transelate(double dx, double dy):将图形在x轴方向平移dx像素。
  scale(double sx, double sy):图形在x轴方向缩放sx倍,纵向缩放sy倍。
  rotate(double arc, double x, double y):图形以点(x, y)为轴点,旋转arc弧度。
  例如,创建AffineTransform对象:
  AffineTransform trans = new AffineTransform();
  为AffineTransform对象指定绕点旋转变换属性:
  Trans.rotate(50.0*3.1415927/180.0,90,80);
  接着为Graphics2D 的对象g2d设置具有上述旋转变换功能的“画笔”:
  Graphics2D g2d = (Graphics2D)g; g2d.setTranstorm(trans);
  最后,以图形对象为参数调用具有变换功能的Graphics2D 对象的draw()方法。例如,设已有一个二次曲线对象curve,以下代码实现用上述旋转功能的g2d对象绘制这条二次曲线:
  g2d.draw(curve);

2.4、clip属性

  clip属性用于实现剪裁效果。设置剪裁属性可调用setClip()方法确定剪裁区的Shape。连续多个setClip()得到它们交集的剪裁区。

2.5、composit属性

  composit属性设置图形重叠区域的效果。先用方法AlphaComposite.getInstance(int rule, float alpha)得到AlphaComposite对象,再通过setComposite()方法设置混合效果。Alpha值的范围为0.0f(完全透明)-0.1f(完全不透明)。

2.6、Graphics2D类的绘图方法

  Graphics2D类仍然保留Graphics类的绘图方法,同时增加了许多新方法。新方法将几何图形(线段、圆等)作为一个对象来绘制。在java.awt.geom包中声明的一系列类,分别用于创建各种身体图形对象。主要有:
  Line2D线段类,RoundRectangle2D圆角矩形类,Ellipse2D椭圆类,Arc2D圆弧类,QuadCurve2D二次曲线类,CubicCurve2D三次曲线类。
  要用Graphics2D类的新方法画一个图形。先在重画方法paintComponent()或paint()中,把参数对象g强制转换成Graphics2D对象;然后,用上述图形类提供的静态方法Double()创建该图形的对象;最后,以图形对象为参数调用Graphics2D对象的draw()方法绘制这个图形。例如以下代码用Graphics2D的新方法绘制线段和圆角矩形:
  // 将对象g类型从Graphics转换成Graphics2D
  Graphics2D g2d = (Graphics2D)g;
  Line2D line = new Line2D.Double(30.0, 30.0, 340.0, 30.0);
  g2d.draw(line);
  RoundRectangle2D rRect = new RoundRectangle2D.Double(13.0, 30.0, 100.0, 70.0, 40.0, 20.0);
  g2d.draw(rRect);
  也可以先用java.awt.geom包提供的Shape对象,并用单精度Float坐标或双精度Double坐标创建Shape对象,然后再用draw()方法绘制。例如,以下代码先创建圆弧对象,然后绘制圆弧:
  Shape arc = new Arc2D.Float(30, 30, 150, 150, 40, 100, Arc2D.OPEN);
  g2d.draw(arc); //绘制前面创建的图形对象arc.

  Graphics2D的几何图形类
  1、线段:
  // 声明并创建线段对象(起点是(2,3),终点是(200,300))
  Line2D line = new Line2D.Double(2,3,200,300);
  2、矩形:
  // 声明并创建矩形对象,矩形的左上角是(20,30),宽是300,高是40。
  Rectangle2D rect = new Rectangle2D.Double(20, 30, 80, 40);
  3、圆角矩形:
  // 左上角是(20,30),宽是130,高是100,圆角的长轴是18,短轴是15。
  RoundRectangle2D rectRound = new RoundRectangle2D.Double(20, 30, 130, 100, 18, 15);
  4、椭圆:
  // 左上角 (20,30),宽是100,高是50
  Ellipse2D ellipse = new Ellipse2D.Double(20, 30, 100, 50);
  5、圆弧:
  // 外接矩形的左上角(10,30),宽85,高60,起始角是5度,终止角是90度。
  Arc2D arc1 = new Arc2D.Double(10, 30, 85, 60, 5, 90, Arc2D.OPEN);
  Arc2D arc2 = new Arc2D.Double(20,65,90,70,0,180,Arc2D.CHORD);
  Arc2D arc3 = new Arc2D.Double(40,110,50,90,0,270,Arc2D.PIE);
  // 参数Arc2D.OPEN、Arc2D.CHORD、Arc2D.PIE分别表示圆弧是开弧、弓弧和饼弧。
  6、二次曲线:
  二次曲线用二阶多项式表示:y(x) = ax2+bx+c。一条二次曲线需要三个点确定:始点、控制点和终点。
  QuadCurve2D curve1 = new QuadCurver2D.Double(20,10,90,65,55,115);
  QuadCurve2D curve2 = new QuadCurver2D.Double(20,10,15,63,55,115);
  QuadCurve2D curve3 = new QuadCurver2D.Double(20,10,54,64,55,115);
  // 方法Double()中的6个参数分别是二次曲线的始点、控制点和终点。以上3条二次曲线的开始点和终点分别相同。
  7、三次曲线:
  三次曲线用三阶多项式表示:y(x)=ax3+bx2+cx+d。一条三次曲线需要四个点确定:始点、两个控制点和终点。
  CubicCurve2D curve1 = new CubicCurve2D.Double(12,30,50,75,15,15,115,93);
  CubicCurve2D curve2 = new CubicCurve2D.Double(12,30,15,70,20,25,35,94);
  CubicCurve2D curve3 = new CubicCurve2D.Double(12,30,50,75,20,95,95,95);
  方法Double()中的8个参数分别是三次曲线的始点、两个控制点和终点。


  一般的方程曲线的绘制过程用一个循环控制。通过循环产生自变量的值,按照方程计算出函数值,再作必要的坐标转换:原点定位的平移变换,图像缩小或放大的缩放变换,得到曲线的图像点,并绘制这个点。以绘制以下曲线方程为例:
  Y=sin(x)+cos(x)
绘制的部分代码可以写成如下:

double x0, y0, x1, y1, x2, y2, scale;
x0 = 100; y0 = 80;
scale = 20.0;
for(x1 = -3.1415926d; x1 <= 2*3.1415926d; x1 += 0.01d) {
    y1 = Math.sin(x1) + Math.cos(x1);
    x2 = x0 + x1 * scale; y2 = y0 + y1 * scale; //(x2,y2)是图像点
    g.fillOval((int)x2, (int)y2, 1, 1); // 画一个圆点作为图像点
}


四、事件处理机制

  Java事件处理是采取“委派事件模型”。所谓“委派事件模型”是指当事件发生时,产生事件的对象(即事件源),会把此“信息”传递给“事件的监听者”处理的一种方式,而这里所说的“信息”实际上就是java.awt.event事件类库里的某个类所创建的对象。我们暂时把它称为“事件的对象”。


  1、事件源(event source)
  事件源是一个产生(或触发)事件的对象,如文本框、按钮等。当这个事件源对象的某些状态以某种方式发生变化时,就会产生某种类型的事件(一个事件源可能会生成多个不同类型的事件)。如果某个组件(对象)希望得到事件源产生的事件,就需要在这个事件源上注册,一个事件源是一个能够注册监听器并且为它们发送事件对象的对象。
  2、事件(event object)
事件就是承载事件源状态改变时的信息对象。或者说,事件是事件源事件监听器传输事件源状态信息的载体。在用户与GUI组件进行交互时就会生成事件,比如当鼠标在面板中移动时,就会生成一个鼠标移动事件的对象,而这个对象保存着当前鼠标在面板中位置信息。java.awt.event包和javax.swing.event包中定义了各种事件类型,常见的事件类有:

事件类 说明
ActionEvent 通常在按下按钮,或双击一个列表项或选中某个菜单时发生
AdjustmentEvnet 当操作一个滚动条时发生
ComponentEvent 当一个组件隐藏、移动、改变大小时发送
ContainerEvent 当一个组件从容器中加入或者删除时发生
FocusEvent 当一个组件获得或是失去焦点时发生
ItemEvent 当一个复选框或是列表项被选中时,当一个选择框或选择菜单被选中
KeyEvent 当从键盘的按键被按下,松开时发生
MouseEvent 当鼠标被拖动、移动、点击、按下..
TextEvent 当文本区和文本域的文本发生改变时发生
WindowEvent 当一个窗口激活、关闭、失效、恢复、最小化...

  3、事件监听器接口
  事件源产生一个事件,可以传送给事件监听者处理,那么怎样才能编写一个事件监听者呢?
  事件监听者实际上就是一个类,该类实现了某个事件监听器接口,它就可以作为一个事件监听者,对接受到的事件进行处理。
  事件监听器接口有多种,不同的事件监听器接口可以监听不同的事件,一个类可以实现一个事件监听接口,也可以实现多个监听接口,这些接口在java.awt.event和javax.swing.event包中定义。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345