AVA基础——图形化界面(GUI)

这篇博客介绍了JAVA中的图形化界面GUI,重点讲解了Awt包的内容,包括布局管理器、创建GUI的流程、事件处理机制。此外,还详细阐述了如何制作可以双击执行的JAR包,包括编写主类、配置MANIFEST.MF文件以及打包过程。通过实例展示了如何使用Button添加ActionListener,并给出了创建菜单栏的基础步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GUI(图形化界面)

JAVA为GUI提供的对象都存在java.Awt和java.Swing的两个包中。

这里主要说Awt包中的内容。


Awt包

java.Awt包中提供了两种基类表示图形界面元素:Component和MenuComponent。
前者代表一个能以图形化方式显示出来并与用户交互的对象。例如Button代表一个按钮。TextField代表一个文本框等。
后者则代表图形界面的菜单组件,包括MenuBar(菜单条),MenuItem(菜单项)等子类。
下面是Component的继承关系图:



注:Container为容器,是一个特殊组件,该组件中可以通过add方法添加其他组件进来。

布局管理器

容器中的排放方式就是布局。
常见的布局管理器:
FlowLayout(流式布局管理器)
从左到右的顺序排列,Panel默认的布局管理器。
BorderLayout(边界布局管理器)
东南西北中,Frame默认的布局管理器。
GridLayout(网格式布局管理器)
规则的矩阵
CardLayout(卡片式布局管理器)
选项卡
GridBagLayout(网格包布局管理器)
非规则的矩阵


创建图形化界面的流程

1,创建frame窗体。
2,对窗体进行基本设置。
比如大小——setSize(横,高);位置——setLocation(x,y);
大小与位置——setBounds(x,y,横,高);流式布局——setLayout(new FlowLayout())。
3,定义组件。
4,将组件通过窗体的add方法添加到窗体中。
5,让窗体显示,通过setVisible(true)

注:以上仅仅把窗体界面做出来,并没有实现功能。

例:
/*
简单的实现图形化界面
Frame 是带有标题和边框的顶层窗口。
*/
import java.awt.*;

class  AwtDemo
{
	public static void main(String[] args) 
	{
		//创建一个Frame窗口
		Frame f=new Frame("测试窗口");
		//设置窗口界面
		f.setBounds(500,400,500,300);
		f.setLayout(new FlowLayout());
		f.add(new Button("关闭"));
		//让窗口显示
		f.setVisible(true);

	}
}

事件处理

在awt编程中,所有事件必须由特定对象(事件监听器)来处理。即在各个组件上加上事件处理机制。
类似在门上装上监听器,监听一些动作,如:砸,撬等,一旦发生就进行指定的动作。

事件监听机制的特点:
1,事件源:就是awt包或者swing包中的那些图形界面组件。
2,事件:每一个事件源都有自己特有的对应事件和共性事件。
3,监听器:将可以触发某一个事件的动作(不只一个动作)都已经封装到了监听器中。。
4,事件处理。
前面三者,JAVA已经封装好了,直接获取对象用即可,我们只需要做的是对事件处理。

一般操作步骤:
1,确定事件源(容器或组件)

2,通过事件源对象的addXXXListener()方法将监听器注册到该事件源上(注意监听器在java.awt.event包中)。

该方法中接收XXXListener(接口)的子类对象,或者XXXListener的子类XXXAdapter的子类对象。

一般用匿名内部类来表示,然后覆盖方法。

3,在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。

例子:

/*
简单的实现图形化界面并实现功能
*/
import java.awt.*;
import java.awt.event.*;
class  AwtDemo
{
	public static void main(String[] args) 
	{
		//创建一个Frame窗口
		Frame f=new Frame("测试窗口");
		//设置窗口界面
		f.setBounds(500,400,500,300);
		f.setLayout(new FlowLayout());
		Button b=new Button("关闭");
		f.add(b);

		//实现功能
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e) 
			{
				System.exit(0);
			}
		});
		b.addMouseListener(new MouseAdapter()
		{
			public void mouseClicked(MouseEvent e)
			{
				System.exit(0);
			}
		});

		//让窗口显示
		f.setVisible(true);

	}
}

一般把这种图形化界面封装成一个类,例:

import java.awt.*;
import java.awt.event.*;
class FrameClass 
{
	private Frame frame;
	private Button button;
	FrameClass()
	{
		init();
	}
	public void init()
	{
		frame=new Frame("我的窗口");
		frame.setBounds(500,400,500,400);
		frame.setLayout(new FlowLayout());
		button=new Button("点我关闭");
		frame.add(button);
		//加载自定义事件
		myEvent();

		frame.setVisible(true);
	}
	//自定义事件
	private void myEvent()
	{
		frame.addWindowListener(new WindowAdapter()
		{
			//覆盖方法
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		button.addMouseListener(new MouseAdapter()
		{
			public void mouseClicked(MouseEvent e) 
			{
				System.exit(0);
			}
		});
		button.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				//对着按钮按enter键则关闭
				if(e.getKeyCode()==KeyEvent.VK_ENTER)
					System.exit(0);
			}
		});
	}
}
class FrameDemo
{
	public static void main(String[] args) 
	{
		new FrameClass();
	}
}

注意:Frame可以添加addWindowListener,因为可以在Frame类中找的这个方法,Button类中也有自己的添加监听器方法:addActionListener(ActionListener l)

添加指定的动作侦听器,以接收发自此按钮的动作事件。之所以可以addKeyListener和addMouseListener是因为这两个方法是共性方法,放在父类Component类中的。

例:利用Button的addActionListener来实现关闭按钮,由于ActionListener方法比较少所以没有子类ActionAdapter。

		button.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e) 
			{
				System.exit(0);
			}
		});


练习:

/*
写一个类似我的电脑的地址栏的工具,可以输入路径,并列出路径下的文件
用到IO流技术
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class MyComputer
{
	private Frame f;
	private Button but,qd;//后面一个位弹出对话框的确定按钮
	private TextField tf;
	private TextArea ta;
	//如果路径输入错误,弹出对话框
	private Dialog log;
	//对话框需要有一个标签,一个标签只显示一行只读文本。
	private Label lab;
	MyComputer()
	{
		init();
	}
	private void init()
	{
		f=new Frame("我的电脑");
		f.setBounds(300,100,600,500);
		f.setLayout(new FlowLayout());
		qd=new Button("确定");
		//参见dialog类构造函数(所属Frame,标题,是否锁定窗口不能切换)
		//默认dialog不显示
		log = new Dialog(f,"提示信息-self",true); 
		log.setBounds(500,400,300,200);
		log.setLayout(new FlowLayout());
		lab=new Label();
		but=new Button("转到");
		//构造具有指定列数的新空文本字段,用于输入地址栏。
		tf=new TextField(60);
		//构造一片文本区域,用于显示文件
		ta = new TextArea(25,70);

		f.add(tf);
		f.add(but);
		f.add(ta);
		log.add(lab);
		log.add(qd);
		myEvent();
		f.setVisible(true);

	}
	private void myEvent()
	{
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		but.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				showDir();
			}
		});

		//此处要保证按回车就会显示路径下的文件,事件源不是按钮“转到”,而是TextField
		tf.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				if(e.getKeyCode()==KeyEvent.VK_ENTER)
					showDir();
			}
		});
		//让dialog的叉有效,此方法是其父类Window的
		log.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				log.setVisible(false);
			}
		});
		//让dialog的确定按键有效
		qd.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				log.setVisible(false);
			}
		});
		qd.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				if(e.getKeyCode()==KeyEvent.VK_ENTER)
					log.setVisible(false);
			}
		});


	}
	//显示文件
	private void showDir()
	{
		//TextField的父类有getText方法
		String path=tf.getText();
		File dir=new File(path);
		if(dir.exists()&&dir.isDirectory())
		{
			//将TextArea清空
			ta.setText("");
			String[] names=dir.list();
			for(String name:names)
				ta.append(name+"\r\n");
		}
		else
		{
			String info="输入的路径:"+path+"错误";
			lab.setText(info);
			log.setVisible(true);
		}
		
	}
}
class  MyComputerDemo
{
	public static void main(String[] args) 
	{
		new MyComputer();
	}
}


菜单栏

从大到小分:MenuBar-->Menu-->MenuItem

创建菜单gui的例子(未实现按键):

/*
文件菜单(menu)
		操作(menu)
			打开(menuitem)
			保存(menuitem)
		关闭(menu)
*/

import java.awt.*;
import java.awt.event.*;
class MyMenu
{
	private Frame f;
	private MenuBar mb;
	private Menu opFile,fileTool;
	private MenuItem open,close,save;
	MyMenu()
	{
		init();
	}
	private void init()
	{
		f=new Frame("我的窗口");
		f.setBounds(300,100,500,400);
		f.setLayout(new FlowLayout());

		mb=new MenuBar();
		fileTool=new Menu("文件");
		opFile=new Menu("操作");
		open=new MenuItem("打开");
		save=new MenuItem("保存");
		close=new MenuItem("关闭");
		
		//MenuBar不是用add方法,而是用frame的setMenuBar方法
		f.setMenuBar(mb);

		mb.add(fileTool);
		fileTool.add(opFile);
		fileTool.add(close);
		opFile.add(open);
		opFile.add(save);
		
		myEvent();
		f.setVisible(true);
	}
	private void myEvent()
	{
		//待实现
	}
}

class MenuDemo 
{
	public static void main(String[] args) 
	{
		new MyMenu();
	}
}

利用io技术完成上述例子的功能实现,达到类似记事本的功能。

/*
文件菜单(menu)
		操作(menu)
			打开(menuitem)
			保存(menuitem)
		关闭(menu)
完成所用功能,类似记事本。
注意:FileDialog 类显示一个对话框窗口,用户可以从中选择文件。
		构造函数:FileDialog(Frame parent,String title,int mode)
		parent - 对话框的所有者,mode - 对话框的模式,可以是 FileDialog.LOAD 或 FileDialog.SAVE 
*/
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class MyMenu
{
	private Frame f;
	private MenuBar mb;
	private Menu opFile,fileTool;
	private MenuItem open,close,save;
	private FileDialog openDia,saveDia;
	private TextArea ta;
	private File file;
	MyMenu()
	{
		init();
	}
	private void init()
	{
		f=new Frame("我的窗口");
		f.setBounds(300,100,500,400);
		//此处为了让文本框合适大小,不需要流式布局
		//f.setLayout(new FlowLayout());

		mb=new MenuBar();
		fileTool=new Menu("文件");
		opFile=new Menu("操作");
		open=new MenuItem("打开");
		save=new MenuItem("保存");
		close=new MenuItem("关闭");
		openDia=new FileDialog(f,"打开",FileDialog.LOAD);
		saveDia=new FileDialog(f,"保存",FileDialog.SAVE);
		ta=new TextArea();

		//MenuBar不是用add方法,而是用frame的setMenuBar方法
		f.setMenuBar(mb);
		//添加组件
		mb.add(fileTool);
		fileTool.add(opFile);
		fileTool.add(close);
		opFile.add(open);
		opFile.add(save);
		f.add(ta);

		myEvent();
		f.setVisible(true);
	}
	private void myEvent()
	{
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		close.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}
		});

		//完成打开功能
		open.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				openDia.setVisible(true);
				String path=openDia.getDirectory();
				String FileName=openDia.getFile();
				//接下来利用io技术读取并append到TextArea
				//先判断路径与文件名是否存在,一定要判断。
				//否则不选文件点取消会报空指针异常
				if(path==null||FileName==null)
					return;

				ta.setText("");
				file=new File(path,FileName);
				//源:文件,目的:TextArea
				BufferedReader bufr=null;
				try
				{
					bufr=new BufferedReader(new FileReader(file));
					String line=null;
					while(null!=(line=bufr.readLine()))
					{
						ta.append(line+"\r\n");
					}
				}
				catch (IOException ex)
				{
					throw new RuntimeException ("读取失败");
				}
				finally
				{
					try
					{
						bufr.close();
					}
					catch (IOException ex)
					{
						throw new RuntimeException ("关闭读取流失败");
					}
				}
			}
		});
		//完成保存功能
		save.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				//如果没有文件 才显示保存窗体
				//比如之前保存过一次了,file已经new过了则不需要再new了
				if(file==null||file.exists()==false)
				{
					saveDia.setVisible(true);
					String path=saveDia.getDirectory();
					String fileName=saveDia.getFile();
					if(path==null || fileName==null)
						return ;
					file=new File(path,fileName);
				}
				//源:TextArea,目的:文件
				BufferedWriter bufw=null;
				try
				{
					bufw=new BufferedWriter(new FileWriter(file));
					String text=ta.getText();
					bufw.write(text);
					bufw.flush();
				}
				catch (IOException ex)
				{
					throw new RuntimeException ("写入失败");
				}
				finally
				{
					try
					{
						bufw.close();
					}
					catch (IOException ex)
					{
						throw new RuntimeException ("关闭写入流失败");
					}
				}
			}
		});
		
	}
}

class MenuDemo 
{
	public static void main(String[] args) 
	{
		new MyMenu();
	}
}

制作可以双击执行的jar包

1,将多个类封装到了一个包(package)中。(在文件头写上package XXXX)

带着包编译:javac -d 存放位置 java文件名,可将带主函数的类public,具体看需求。

2,定义一个jar包的配置信息。
定义一个文件a.txt 。文件内容内容为:
Main-Class:(空格)包名.类名(回车)
3,打jar包。
jar -cvfm my.jar a.txt 包名
4,通过winrar程序进行验证,查看该jar的配置文件中是否有自定义的配置信息。
5,通过工具--文件夹选项--文件类型--jar类型文件,通过高级,定义该jar类型文件的打开动作的关联程序。
jdk\bin\javaw.exe -jar



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值