GUI:图形化界面编程

1  GUI概述与布局

GUI,全称是Graphical User Interface(图形用户接口),用于图形化界面编程。

用图形的方式,来显示计算机操作的界面,这样更方便更直观。

 

CLI,全称是Command line User Interface (命令行用户接口),就是常见的DOS操作命令。

只管需要记忆一些常用命令,操作不直观。

举例;比如:创建文件夹,或者删除文件夹等。

 

JavaGUI提供的对象都存在java.Awtjavax.Swing两个包中。

Awt与 Swing

java.AwtAbstract Window ToolKit (抽象窗口工具包),需要调用本地系统方法实现功能。属重量级控件。

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

继承关系图:

GUI:图形化界面编程_第1张图片

Component代表组件,它的子类:Button(按钮)Lable(标签,封装文字使用,将文字作为组件对象)。

Checkbox(复选框)TextComponen(文本组件:文本框和文本域)。

Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。Window(窗口)Panel(面板)Frame(框架)Dialog(对话框)FileDialog(文本对话框)。

 

Button此类创建一个标签按钮。当按下该按钮时,应用程序能执行某项动作

Label:是一个可在容器中放置文本的组件。一个标签只显示一行只读文本。文本可由应用程序更改,但是用户不能直接对其进行编辑。

Checkbox复选框是一个可处于”(true) ”(false) 状态的图形组件。单击复选框可将其状态从更改为,或从更改为。 

Frame:是带有标题和边框的顶层窗口。

TextComponent:是所有允许编辑文本的组件的超类。

 

Window:是一个没有边界和菜单栏的顶层窗口。窗口的默认布局是 BorderLayout

Panel :是最简单的容器类。应用程序可以将其他组件放在面板提供的空间内,这些组件包括其他面板

Frame: 是带有标题和边框的顶层窗口。

Dialog: 是一个带标题和边界的顶层窗口,边界一般用于从用户处获得某种形式的输入。

FileDialog :是一个文件对话框窗口,用户可以从中选择文件。

 

布局管理器:

什么是布局?容器中的组件的排放方式,就是布局。

常见的布局管理器:

FlowLayout(流式布局管理器):从左到右的顺序排列,Panel默认的布局管理器。

BorderLayout(边界布局管理器):东,南,西,北,中,Frame默认的布局管理器。

GridLayout(网格布局管理器):规则的矩阵。

CardLayout(卡片布局管理器):选项卡。

GridBagLayout(网格包布局管理器):非规则的矩阵。

 

2  创建一个简单的窗体

Container常用子类:WindowPanelWindow代表窗口,Panel是面板,其中面板不能单独存在。

Window常用子类:Frame(框架)、Dialog(对话框)。

 

创建图形化界面过程:

1,创建frame窗体。

2,对窗体进行基本设置。比如大小,位置,布局。

3,定义组件。

4,将组件通过窗体的add方法添加到窗体中。

5,让窗体显示,通过setVisible(true),设置是否可视化。

 

简单的窗体创建过程:

      Frame  f = new Frame(my window);  //创建一个窗口框架。

      f.setLayout(new FlowLayout());   //使用流式布局。

      f.setSize(500,400);    //设置窗口大小。

      f.setLocation(300,200);    //设置窗口出现在屏幕的位置。

      f.setVisible(true);   //true,显示这个窗口。设置是否可视化。

 

代码示例:

import java.awt.*;

class GUIDemo{
	public static void main(String[] args){
		Frame f = new Frame("my Window"); //创建一个窗口框架。
		
		f.setLayout(new FlowLayout()); //使用流式布局。
		f.setSize(500,400);    //设置窗口大小。
		f.setLocation(300,200);  //设置窗口出现在屏幕的位置。
		f.setVisible(true);   //true,显示这个窗口。设置是否可视化。
	}
}

3  事件监听机制

事件监听机制:

1,将监听器注册到事件源。

2,有监听器所监听的动作,作用于事件源上。

3,产生事件对象。

4,将事件对象传给事件处理方式。

GUI:图形化界面编程_第2张图片


事件监听机制的特点:

1,事件源。

2,事件。

3,监听器。

4,事件处理。

 

事件源:就是awt包或者swing包中的那些图形界面组件。

事件:每一个事件源都有自己特有的对应事件和共性事件。

监听器:将可以触发某一个事件的动作(不止一个动作)都已经封装到了监听器中。

 

以上三者,在java中都已经定义好了,直接获取其对象来用就可以了。

我们要做的事情是,就是对产生的动作进行处理。

 

通过一个实现窗体关闭功能的实例,演示事件监听机制。

事件源:是窗口,即窗口右上角的关闭。

事件:点击窗口右上角,产生窗口事件WindowEvent

监听器:自己实现的监听器,继承WIndowAdapter类,覆盖关闭窗口的方法。

事件处理:关闭这个窗口,即退出程序exit(0)

代码和注释:

import java.awt.*;
import java.awt.event.*;  //这两个包都要导入,WindowEvent用到此包。

class AwtDemo {
	public static void main(String[] args){
		Frame f = new Frame("my awt");  //Frame默认边界布局。
		
		f.setSize(500,400);    //调整框体的大小,第一个数横坐标,第二个数纵坐标。
		f.setLocation(300,200);  //移动框体的位置,到(300,200)坐标。
		f.setLayout(new FlowLayout());  //设置流失布局
		f.setVisible(true);  //true,即为显示该组件。
		
		Button b = new Button("我是一个按钮");
		
		f.add(b);  //向框体中添加按钮。
		f.addWindowListener(new MyWin()); //事件监听机制。添加指定的窗口监听器。
	}
}
/*  
class MyWin implements WindowListener {  //实现监听器接口
	//覆盖7个方法。可是我只用到了关闭的动作。
	//其他动作都没有用到,可是却必须复写。
}
*/
//因为WindowListener的子类WindowAdapter已经实现了WindowListenner接口。
//并覆盖了其中的所有方法,那么我只要继承WindowAdapter,覆盖我需要的方法即可。
class MyWin extends WindowAdapter {
	public void windowClosing(WindowEvent e){ //关闭窗口函数,把窗体事件作为参数传递进来。
		System.out.println("我关"+e.toString()); //打印事件信息。事件处理。
		System.exit(0);  //结束程序,关闭窗体。这是事件的处理。
	}
	public void windowActivated(WindowEvent e){  //窗体前置,激活窗体。
		System.out.println("我活了");
	}
	public void windowOpened(WindowEvent e){  //窗体打开。
		System.out.println("我被打开了,hahaha");
	}
}

4  透过窗体事件和Action事件看事件监听规律

窗体事件:

addWindowListener——>WindowAdapter——>windowClosing——>WindowEvent

Action事件:

addActionListener——>ActionListener——>actionPerformed——>ActionEvent

其他例如鼠标事件:

addMouseListener——>MouseAdapter——>mouseClosing——>MouseEvent

 

规律:

      上一个例子中,窗体调用addWindowListener( new MyWin()) 方法添加MyWin监听器,MyWin类继承了WindowAdapter监听器类,并覆盖了监听器类的windowClosing()方法,MyWin监听器要监听的事件(WindowEvent)会作为参数传递给windowClosing方法。

      总结,组件调用相应的addXXXListener()方法添加指定的监听器,指定的监听器会继承XXXAdapter监听器类(或实现XXXListener监听器接口),并且覆盖其中的XXXClosing等操作函数。指定的监听器所要监听的事件XXXEvent会作为参数传递给XXXClosing等操作函数。触发一个事件的动作发生时,此事件自动产生。

      可以利用匿名内部类简化代码,见第5节中的示例。

代码示例和注释:

import java.awt.*;
import java.awt.event.*;

class FrameDemo {
	//定义该图形中所需的组件的引用。
	private Frame f;
	private Button but;
	
	FrameDemo(){
		init(); //初始化GUI界面
	}
	
	public void init(){
		f = new Frame("my frame");
		
		//对frame进行基本设置。
		f.setBounds(300,100,600,500);
		f.setLayout(new FlowLayout());  //设置此容器的布局管理器,流水布局。
		
		but = new Button("退 出");
		
		//将组件添加到frame中
		f.add(but);
		
		//加载一下窗体上的事件。还有每个事件相应的监听器。
		myEvent();
		
		//显示窗体
		f.setVisible(true);
	}
	
	private void myEvent(){
		f.addWindowListener(new WindowAdapter(){  //addWindowListener()添加窗体监听器。
			//windowClosing()是WindowAdapter监听器类的方法。
			public void windowClosing(WindowEvent e){ 
				System.exit(0);  //WindowEvent窗体事件的处理。
			}
		});
		
		//让按钮具备退出程序的功能。
		/* 
		按钮就是事件源。
		那么选择哪个监听器呢?
		通过关闭窗体示例了解到,想要知道哪个组件具备什么样的特有监听器。
		需要查看该组件对象的功能。
		 通过查阅button的描述,发现按钮支持一个特有监听addActionListener。
		*/
		
		//addActionListener()是Button类的方法,添加action事件监听器,监听按钮动作。
		but.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){ //actionPerformed()是ActionListener类的方法,
				System.out.println("退出,按钮干的");    //处理Action事件。
				System.exit(0);
			}
		});
	}
	
	public static void main(String[] args){
		new FrameDemo();
	}
}

5  鼠标事件和键盘事件

代码示例和相应的注释,先初始化GUI界面再进行事件处理:

import java.awt.*;
import java.awt.event.*;

class MouseAndKeyEvent {
	private Frame f;
	private Button but;
	private TextField tf;
	
	MouseAndKeyEvent(){
		init(); //初始化GUI界面
	}
	
	public void init(){
		f = new Frame("my frame");
		
		f.setBounds(300,100,600,500); //移动窗口到(300,100)位置,并调整大小为宽600长500.
		f.setLayout(new FlowLayout());  //设为流水布局
		f.setVisible(true);   //显示窗口
		
		but = new Button("退 出"); //按钮
		tf = new TextField(20);  //20是这个单行文本框的列数 
		
		f.add(tf);  //窗口中添加文本框
		f.add(but); //窗口中添加按钮
		
		myEvent(); //事件处理
	}
	
	private void myEvent() { //事件处理
		//窗体事件的处理
		f.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		
		//按钮的Action事件的处理。
		but.addActionListener(new ActionListener(){  //匿名内部类
			public void actionPerformed(ActionEvent e){
				System.out.println("action ok");
			}
		});
		
		//按钮的鼠标事件。
		but.addMouseListener(new MouseAdapter(){  //添加鼠标监听器,匿名内部类。
			private int count = 1;
			private int clickcount = 1;
			public void mouseEntered(MouseEvent e){ //鼠标进入but按钮的范围,触发鼠标进入事件。
				System.out.println("鼠标进入到该组件"+count++);
			}
			public void mouseClicked(MouseEvent e){ //双击动作
				if(e.getClickCount()==2)
					System.out.println("鼠标双击击事件"+clickcount++);
			}
		});
		
		//键盘事件,给But添加一个键盘监听,敲键盘则按钮响应。
		but.addKeyListener(new KeyAdapter(){  //匿名内部类。
			public void keyPressed(KeyEvent e){
				int n = e.getKeyCode();
				String s = e.getKeyText(n);
				System.out.println(s);
				if(s.equals("Enter"))
					System.out.println("回车键"+"..n:"+n+"..s:"+s);
				if(e.getKeyCode()==KeyEvent.VK_ESCAPE)  //使用静态常量,"Esc"键退出。
					System.exit(0);
			}
		});
		
		//单行文本框
		tf.addKeyListener(new KeyAdapter(){  //匿名内部类。
			public void keyPressed(KeyEvent e){
				int code = e.getKeyCode();
				if(!(code>=KeyEvent.VK_0 && code<=KeyEvent.VK_9)){
					System.out.println("输入不合法");
					
					e.consume(); //不使用默认的方式处理此事件。
					             //使用了此方法,则键盘敲'A'时,字母'a'不会再进入文本框。
				}
			}
		});
	}
	
	public static void main(String[] args){
		new MouseAndKeyEvent();
	}
}

6  对话框Dialog练习

需求:列出指定目录内容。

先初始化界面,再对事件进行处理。

代码及注释:

import java.awt.*;
import java.awt.event.*;
import java.io.*;  //用到File类

class MyWindowDemo {
	private Frame f;
	private TextField tf; //允许编辑单行文本
	private Button but;
	private TextArea ta; //显示文本的多行区域,可以将它设置为允许编辑或只读。
	
	private Dialog d;  //对话框
	private Label lab;  //标签,对话框上的显示内容 
	private Button okBut; //对话框上的按钮 
	
	MyWindowDemo(){
		init(); //初始化GUI界面
	}
	
	public void init(){
		f = new Frame("my window"); //创建框体
		f.setBounds(300,100,600,500); //设置大小
		f.setLayout(new FlowLayout()); //设置布局
		f.setVisible(true);  //显示窗体
		
		tf = new TextField(60); //创建单行文本框,并指定其列数。
		but = new Button("转到"); //创建一个按钮 
		ta = new TextArea(25,70); //创建一个多行文本区域,15行,40列。
		
		d = new Dialog(f,"提示信息-self",true); //创建一个对话框
		
		d.setBounds(400,200,240,150); //设置对话框位置及大小,位置(400,200),大小长240宽150 
		d.setLayout(new FlowLayout());  //设置这个对话框的布局 
		lab = new Label();          //创建一个标签 
		okBut = new Button("确定");
		
		d.add(lab);  //对话框中加入标签
		d.add(okBut); //对话框中加入按钮
		f.add(tf);
		f.add(but);
		f.add(ta);
		
		myEvent(); //事件处理
	}
	
	public void myEvent(){
		//窗体监听器,点右上角的X号能关闭窗体 
		f.addWindowListener(new WindowAdapter(){ 
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		
		//按钮监听器,窗体上的按钮。
		but.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				showDir();  //点击按钮和按回车键的处理方式相同 
			}
		});
		
		//文本框监听
		tf.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e){
				if(e.getKeyCode()==KeyEvent.VK_ENTER) //当敲回车时,和点按钮效果相同 
					showDir();
			}
		});
		
		//对话框的窗体事件的监听
		d.addWindowListener(new WindowAdapter(){ 
			public void windowClosing(WindowEvent e){
				d.setVisible(false);  //隐藏对话框
			}
		});
		okBut.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				d.setVisible(false);
			}
		});
	}
	
	//列出目录下的所有文件
	public void showDir(){
		String dirPath = tf.getText();//获取文本框中的内容,即目录
		File dir = new File(dirPath);//根据目录创建一个File对象 
				
		if(dir.exists() && dir.isDirectory()){ //存在并且是个目录 
			String[] names = dir.list(); //列出目录dir下的文件和目录
			ta.setText(""); //清空 
			for(String name : names){
				//ta.setText(name+"\r\n"); //setText方法会把以前的内容覆盖
				ta.append(name+"\r\n");  //append方法追加内容,不会覆盖 
			}
		}
		else{
			String info = "您输入的路径"+dirPath+"是错误的";
			lab.setText(info);  //设置对话框中标签的的内容 
			d.setVisible(true); //若输入的不是目录,则弹出对话框 
		}
	}
	
	public static void main(String[] args){
		new MyWindowDemo();
	}
}

7  菜单栏、菜单(子菜单)、菜单项

代码及注释:

import java.awt.*;
import java.awt.event.*;

class MyMenuDemo {
	private Frame f;  //窗体
	private MenuBar mb; //菜单栏
	private Menu m,subMenu; //菜单
	private MenuItem closeItem,subItem; //菜单项
	
	MyMenuDemo(){
		init(); //初始化GUI界面
	}
	
	//初始化
	public void init(){ 
		f = new Frame("my window");  //创建框体
		f.setBounds(300,100,500,600); //设置大小
		f.setLayout(new FlowLayout()); //设置布局
		f.setVisible(true); //显示Frame窗体
		
		mb = new MenuBar(); //菜单栏
		m = new Menu("文件"); //菜单栏中的一个菜单 
		subMenu = new Menu("子菜单"); 
		
		closeItem = new MenuItem("退出"); //菜单下拉中的一个菜单项 
		subItem = new MenuItem("子条目");
		
		m.add(closeItem);  //把菜单项添加到菜单中 
		m.add(subMenu);   //菜单中添加一个子菜单 
		subMenu.add(subItem);  //子菜单中添加一个菜单项 
		mb.add(m);        //把菜单添加到菜单栏中 
		
		f.setMenuBar(mb); //将此Frame窗体的菜单栏设置为指定的菜单栏 
		
		myEvent(); //事件处理
	}
	
	public void myEvent(){
		//窗体监听器,点右上角的X号能关闭窗体 
		f.addWindowListener(new WindowAdapter(){ 
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		
		//"退出"菜单项的监听,实现点击退出
		closeItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				System.exit(0);
			}
		});
	}

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

8  练习:打开文件、保存文件

Dialog 的子类FileDialog,是专用于操作文件的对话框,比如打开文件和保存文件。

构造函数:

FileDialog(Frame parent, String title, int mode)

      创建一个具有指定标题的文件对话框窗口,用于加载或保存文件。

      parent - 对话框的所有者。

      title - 对话框的标题。

      mode - 对话框的模式,可以是 FileDialog.LOAD 或 FileDialog.SAVE

代码示例和注释:

import java.awt.*;
import java.awt.event.*;
import java.io.*;

class MyMenuTest {
	private Frame f;        //窗体
	private MenuBar mb;     //菜单栏
	private Menu m;      //菜单
	private MenuItem openItem,saveItem,closeItem;   //菜单项
	private TextArea ta;  //文本区域
	
	private FileDialog openDia,saveDia; //★创建两个文件对话框,可以操作文件 
	private File file; 
	
	MyMenuTest(){
		init(); //初始化
	}
	
	//初始化
	public void init(){ 
		f = new Frame("my window");  //创建框体
		f.setBounds(300,100,500,600);  //设置大小
		f.setLayout(new BorderLayout()); //设置布局:边界布局
		f.setVisible(true); //★显示Frame窗体
		
		mb = new MenuBar(); //菜单栏
		m = new Menu("文件"); //菜单栏中的一个菜单 
		
		openItem = new MenuItem("打开"); //菜单下拉中的一个菜单项 
		saveItem = new MenuItem("保存");
		closeItem = new MenuItem("退出");
		ta = new TextArea();
		
		openDia = new FileDialog(f,"我要打开",FileDialog.LOAD);//★创建一个打开文件的对话框
		saveDia = new FileDialog(f,"我要保存",FileDialog.SAVE);//★创建一个保存文件的对话框
		
		mb.add(m);  //把菜单添加到菜单栏中
		m.add(openItem); //把菜单项添加到菜单中 
		m.add(saveItem);
		m.add(closeItem);
		f.add(ta); //添加文本区域 
		
		f.setMenuBar(mb); //★将此Frame窗体的菜单栏设置为指定的菜单栏 
		
		myEvent(); //事件监听和处理
	}
	
	public void myEvent(){
		//窗体监听器,点右上角的X号能关闭窗体 
		f.addWindowListener(new WindowAdapter(){ 
			public void windowClosing(WindowEvent e){
				System.exit(0);
			}
		});
		
		//退出菜单项监听,实现点击退出
		closeItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				System.exit(0);
			}
		});
		
		//点击“打开”,弹出openDia对话框,使用IO技术实现打开功能,打开的数据显示在文本区域中 
		openItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				openDia.setVisible(true);
				String dirPath = openDia.getDirectory();
				String fileName = openDia.getFile();
				if(dirPath==null || fileName==null)
					return;
				file = new File(dirPath,fileName);
				ta.setText(""); //清空
				
				try{
					BufferedReader bufr = new BufferedReader(new FileReader(file));
					String line = null;
					while((line=bufr.readLine())!=null){
						ta.append(line+"\r\n"); //读取数据到文本区域中
					}
					bufr.close(); //这里为了代码简单,close没放到finally中 
				}
				catch(IOException ee){
					throw new RuntimeException("读取失败");
				}
			}
		});
		
		//点击“保存”,弹出saveDia对话框,实现保存功能,打开的数据显示在文本区域,修改之后保存到原文件 
		saveItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				if(file==null){
					saveDia.setVisible(true);
					String dirPath = saveDia.getDirectory();
					String fileName = saveDia.getFile();
					if(dirPath==null || fileName==null)
						return;
					file = new File(dirPath,fileName);
				}
				
				try{
					BufferedWriter bufw = new BufferedWriter(new FileWriter(file));
					String text = ta.getText(); //获取文本区域中数据
					bufw.write(text);
				  //bufw.flush();
					bufw.close();
				}catch(IOException ee){
					throw new RuntimeException("保存失败");
				}
			}
		});
	}

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

你可能感兴趣的:(Java基础)