第四十九讲 GUI(图形用户界面)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yerenyuan_pku/article/details/84721099

GUI的简单概述

Graphical User Interface(图形用户接口),用图形的方式,来显示计算机操作的界面,这样更方便更直观。与之相对应的Command line User Interface (命令行用户接口),就是常见的Dos命令行操作,需要记忆一些常用的命令,操作不直观。

Awt和Swing

Awt

概述

Java为GUI提供的对象都存在java.awt和javax.swing两个包中。java.awt就是Abstract Window ToolKit (抽象窗口工具包),需要调用本地系统方法实现功能,它属于重量级控件。

继承关系图

在这里插入图片描述
所有的可以显示出来的图形元素都称为Component,Component代表了所有的可见的图形元素,Component里面有一种比较特殊的图形元素叫Container,Container(容器)在图形界面里面是一种可以容纳其它Component元素的一种容器,Container本身也是一种Component,Container里面也可以容纳别的Container。
Container里面又分为Window和Panel,Window是可以独立显示出来的,平时我们看到的各种各样的应用程序的窗口都可以称为Window,Window作为一个应用程序窗口可以独立显示出来,Panel也可以容纳其它的图形元素,但一般看不见Panel,Panel不能作为应用程序的独立窗口显示出来,Panel要想显示出来就必须得把自己装入到Window里面才能显示出来。Panel应用比较典型的就是Applet(Java的页面小应用程序),现在基本上已经不用了,AJAX和JAVASCRIPT完全取代了它的应用;Window本身又可以分为Frame和Dialog,Frame就是我们平时看到的一般的窗口,而Dialog则是那些需要用户进行了某些操作(如点击某个下拉菜单的项)才出现的对话框,这种对话框就是Dialog。

布局管理器

容器中的组件的排放方式,就是布局。Awt提供了5种布局管理器类,它们依次是FlowLayout(流式布局管理器)、BorderLayout(边界布局管理器)、GridLayout(网格布局管理器)、GridBagLayout(网格包布局管理器)、CardLayout(卡片布局管理器),但是最屌的布局还是坐标式布局。下面分别对它们进行简单的介绍。

FlowLayout

FlowLayout是Panel类的默认布局管理器。FlowLayout布局管理器对组件逐行定位,行内从左到右,一行排满后换行,它不改变组件的大小,按组件原有尺寸显示组件,可设置不同的组件间距、行距以及对齐方式。FlowLayout布局管理器默认的对齐方式是居中。
在这里插入图片描述

BorderLayout

BorderLayout是Frame类的默认布局管理器。BorderLayout将整个容器的布局划分成东(EAST)、西(WEST)、南(SOUTH)、北(NORTH)、中(CENTER)五个区域,组件只能被添加到指定的区域。如不指定组件的加入部位,则默认加入到CENTER区。每个区域只能加入一个组件,如加入多个,则先前加入的会被覆盖。
BorderLayout型布局管理器尺寸缩放原则:北、南两个区域在水平方向缩放,东、西两个区域在垂直方向缩放,中部可以在两个方向上缩放。
在这里插入图片描述

GridLayout

GridLayout型布局管理器将空间划分成规则的矩形网格,每个单元格区域大小相等。组件被添加到每个单元格中,先从左到右添满一行后换行,再从上到下。
在这里插入图片描述

GridBagLayout

GridBagLayout型布局管理器将空间划分成非规则的矩形网格,每个单元格区域大小不一定相等。

CardLayout

CardLayout型布局管理器将整个容器的布局划分成几个选项卡,诸如下图这样。
在这里插入图片描述

Swing

概述

javax.swing是在Awt的基础上建立的一套图形界面系统,其中提供了更多的组件,而且完全由Java实现。它增强了移植性,属于轻量级控件。

事件监听机制

事件监听机制的组成

事件监听机制由下面几项组成:

  • 事件源:就是java.awt包或者java.swing包中那些图形界面组件;
  • 事件:每一个事件源都有自己特有的对应事件和共性事件(鼠标、键盘事件等);
  • 监听器:将可以触发某一个事件的动作(不只一个动作)都封装到监听器中;
  • 事件处理:引发事件后的处理方式。

注意:事件源、事件、监听器在Java中都已经定义好了,直接获取其对象来用就可以了,我们所要做的事情就是对产生的动作进行处理。

事件监听机制流程图

在这里插入图片描述
事件监听机制中所要明确的注意点:

  1. 确定事件源(容器或组件);
  2. 通过事件源对象的addXxxListener方法将监听器注册到该事件源上,该方法中接收XxxListener的子类对象,或者XxxListener的子类XxxAdapter的子类对象,一般用匿名内部类来表示。在覆盖方法的时候,方法的参数一般是XxxEvent类型的变量;
  3. 事件触发后会把事件打包成对象传递给该变量(其中包括事件源对象,通过getSource()或者getComponent()获取)。

按钮事件

现在想要用户点击按钮有效果,比如打印一句话。

思路:

  1. 确定事件源(按钮);
  2. 确定监听器,按钮添加监听器,按钮对象最清楚,到按钮对象中查找;
  3. 定义处理方式。
package cn.liayun.awt.frame;

import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class FrameSimple {

	public static void main(String[] args) {
		// 1,创建一个窗体,通过Frame
		Frame f = new Frame("按钮事件");

		// 2,对窗体进行基本设置
		f.setSize(500, 400);
		f.setLocation(400, 200);
		f.setBackground(Color.blue);// 设置窗体的背景颜色
									// blue是Color类里面的一个静态常量,可以使用"类名.静态常量名"来访问
		// 设置布局
		f.setLayout(new FlowLayout());

		// 给窗体添加组件
		Button but = new Button("my button");

		// 将组件添加到窗体中
		f.add(but);
		
		/*
		 * 需求:想要用户点击按钮有效果,比如打印一句话
		 * 思路:
		 * 1,确定事件源(按钮);
		 * 2,确定监听器,按钮添加监听器,按钮对象最清楚,到按钮对象中查找;
		 * 3,定义处理方式。
		 * 
		 * 定义的规范:XxxListener,Xxx监听器,有对应的XxxEvent事件。
		 */
		//1,在按钮上添加所需的监听器
		but.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("按钮被触发了......" + e);
//				System.exit(0);
			}
		});
		
		// 3,让窗体显示
		f.setVisible(true);
	}

}

窗体事件

现在想要实现点击窗体的✗(关闭),就可以实现窗体的关闭。

package cn.liayun.awt.frame;

import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class FrameSimple {

	public static void main(String[] args) {
		// 1,创建一个窗体,通过Frame
		Frame f = new Frame("按钮事件");

		// 2,对窗体进行基本设置
		f.setSize(500, 400);
		f.setLocation(400, 200);
		f.setBackground(Color.blue);// 设置窗体的背景颜色
									// blue是Color类里面的一个静态常量,可以使用"类名.静态常量名"来访问
		// 设置布局
		f.setLayout(new FlowLayout());

		// 给窗体添加组件
		Button but = new Button("my button");

		// 将组件添加到窗体中
		f.add(but);
		
		/*
		 * 需求:想要用户点击按钮有效果,比如打印一句话
		 * 思路:
		 * 1,确定事件源(按钮);
		 * 2,确定监听器,按钮添加监听器,按钮对象最清楚,到按钮对象中查找;
		 * 3,定义处理方式。
		 * 
		 * 定义的规范:XxxListener,Xxx监听器,有对应的XxxEvent事件。
		 */
		//1,在按钮上添加所需的监听器
		but.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("按钮被触发了......" + e);
//				System.exit(0);
			}
		});
		
		/*
		 * 需求:想要实现点击窗体的X,就可以实现窗体的关闭。
		 * 思路:
		 * 1,事件源:窗体;
		 * 2,监听器,通过窗体对象去查;
		 * 3,事件处理
		 * 
		 * 到底哪些监听接口有适配器类?
		 * 只要监听接口中的方法在2个以内,都没有适配器类。适配器类的出现只为方便创建监听器对象。
		 * 但是一般监听接口都有适配器。
		 */
		f.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				System.out.println("window closing");
				System.exit(0);
			}

			@Override
			public void windowOpened(WindowEvent e) {
				System.out.println("孔雀开屏!window open");
			}
			
			
		});
		
		// 3,让窗体显示
		f.setVisible(true);
	}

}

只要监听接口中的方法在2个以内,都没有适配器类。适配器类的出现只为方便创建监听器对象,但是一般监听接口都有适配器。

鼠标事件

演示鼠标监听。按钮作为事件源,鼠标监听器注册到按钮上。

package cn.liayun.awt.frame;

import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class FrameSimple {

	public static void main(String[] args) {
		// 1,创建一个窗体,通过Frame
		Frame f = new Frame("按钮事件");

		// 2,对窗体进行基本设置
		f.setSize(500, 400);
		f.setLocation(400, 200);
		f.setBackground(Color.blue);// 设置窗体的背景颜色
									// blue是Color类里面的一个静态常量,可以使用"类名.静态常量名"来访问
		// 设置布局
		f.setLayout(new FlowLayout());

		// 给窗体添加组件
		Button but = new Button("my button");

		// 将组件添加到窗体中
		f.add(but);
		
		/*
		 * 需求:想要用户点击按钮有效果,比如打印一句话
		 * 思路:
		 * 1,确定事件源(按钮);
		 * 2,确定监听器,按钮添加监听器,按钮对象最清楚,到按钮对象中查找;
		 * 3,定义处理方式。
		 * 
		 * 定义的规范:XxxListener,Xxx监听器,有对应的XxxEvent事件。
		 */
		//1,在按钮上添加所需的监听器
		but.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("按钮被触发了......" + e);
//				System.exit(0);
			}
		});
		
		/*
		 * 需求:想要实现点击窗体的X,就可以实现窗体的关闭。
		 * 思路:
		 * 1,事件源:窗体;
		 * 2,监听器,通过窗体对象去查;
		 * 3,事件处理
		 * 
		 * 到底哪些监听接口有适配器类?
		 * 只要监听接口中的方法在2个以内,都没有适配器类。适配器类的出现只为方便创建监听器对象。
		 * 但是一般监听接口都有适配器。
		 */
		f.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				System.out.println("window closing");
				System.exit(0);
			}

			@Override
			public void windowOpened(WindowEvent e) {
				System.out.println("孔雀开屏!window open");
			}
			
			
		});
		
		/*
		 * 演示鼠标监听。
		 * 
		 * 按钮作为事件源。
		 * 鼠标监听器注册到按钮上。
		 * 
		 * 组件.addXxxListener(new XxxAdapter() {
		 * 		public void methodName(XxxEvent e) {}
		 * });
		 */
		but.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				/*
				 * 想要对鼠标双击进行处理。应该找鼠标事件对象,因为事件对象一产生,内部必然封装事件源以及事件相关内容。
				 * 要查MouseEvent对象。
				 */
				if (e.getClickCount() == 2) {
					System.out.println("mouse double click");
				}
			}
			
		});
		
		// 3,让窗体显示
		f.setVisible(true);
	}

}

此时,不仅给按钮注册了一个ActionListener(活动监听器),还给按钮注册了一个MouseListener(鼠标监听器)。但要注意,按钮尽量添加ActionEvent(活动事件),当还有点击事件时,点击事件先执行。

键盘事件

文本框中只能输入数字。输入0-9之外的字符,提示输入非法,并且无法输入。

package cn.liayun.awt.frame;

import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class FrameSimple {

	public static void main(String[] args) {
		// 1,创建一个窗体,通过Frame
		Frame f = new Frame("按钮事件");

		// 2,对窗体进行基本设置
		f.setSize(500, 400);
		f.setLocation(400, 200);
		f.setBackground(Color.blue);// 设置窗体的背景颜色
									// blue是Color类里面的一个静态常量,可以使用"类名.静态常量名"来访问
		// 设置布局
		f.setLayout(new FlowLayout());

		// 给窗体添加组件
		Button but = new Button("my button");
		
		//加入一个文本框组件
		TextField tf = new TextField(40);

		// 将组件添加到窗体中
		f.add(but);
		f.add(tf);
		
		/*
		 * 需求:想要用户点击按钮有效果,比如打印一句话
		 * 思路:
		 * 1,确定事件源(按钮);
		 * 2,确定监听器,按钮添加监听器,按钮对象最清楚,到按钮对象中查找;
		 * 3,定义处理方式。
		 * 
		 * 定义的规范:XxxListener,Xxx监听器,有对应的XxxEvent事件。
		 */
		//1,在按钮上添加所需的监听器
		but.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("按钮被触发了......" + e);
//				System.exit(0);
			}
		});
		
		/*
		 * 需求:想要实现点击窗体的X,就可以实现窗体的关闭。
		 * 思路:
		 * 1,事件源:窗体;
		 * 2,监听器,通过窗体对象去查;
		 * 3,事件处理
		 * 
		 * 到底哪些监听接口有适配器类?
		 * 只要监听接口中的方法在2个以内,都没有适配器类。适配器类的出现只为方便创建监听器对象。
		 * 但是一般监听接口都有适配器。
		 */
		f.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e) {
				System.out.println("window closing");
				System.exit(0);
			}

			@Override
			public void windowOpened(WindowEvent e) {
				System.out.println("孔雀开屏!window open");
			}
			
			
		});
		
		/*
		 * 演示鼠标监听。
		 * 
		 * 按钮作为事件源。
		 * 鼠标监听器注册到按钮上。
		 * 
		 * 组件.addXxxListener(new XxxAdapter() {
		 * 		public void methodName(XxxEvent e) {}
		 * });
		 */
		but.addMouseListener(new MouseAdapter() {

			@Override
			public void mouseClicked(MouseEvent e) {
				/*
				 * 想要对鼠标双击进行处理。应该找鼠标事件对象,因为事件对象一产生,内部必然封装事件源以及事件相关内容。
				 * 要查MouseEvent对象。
				 */
				if (e.getClickCount() == 2) {
					System.out.println("mouse double click");
				}
			}
			
		});
		
		/*
		 * 需求:文本框中只能输入数字。
		 * 事件源:文本框。
		 * 文本框注册键盘监听。
		 * 事件处理。
		 */
		tf.addKeyListener(new KeyAdapter() {

			@Override
			public void keyPressed(KeyEvent e) {
				//1,如何获取录入的内容?通过键盘事件获取。
//				char key = e.getKeyChar();
//				int code = e.getKeyCode();
//				System.out.println(code + "..." + KeyEvent.getKeyText(code));
				
				int code = e.getKeyCode();
				if (!(code >= KeyEvent.VK_0 && code <= KeyEvent.VK_9)) {
					System.out.println("必须是0-9之间的数字");
					e.consume();//直接取消默认处理方式
				}
				
				//组合键的应用
//				if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) {
//					System.out.println("ctrl + enter run");
//				}
			}
			
		});
		
		// 3,让窗体显示
		f.setVisible(true);
	}

}

猜你喜欢

转载自blog.csdn.net/yerenyuan_pku/article/details/84721099