黑马程序员 Java基础学习之GUI

本文详细介绍Java图形用户界面(GUI)编程的基础知识,包括GUI概述、布局管理、事件监听机制及其实现方法。通过多个实战案例,如文件浏览、简易记事本模拟等,深入浅出地讲解了如何使用Java AWT和Swing库创建和控制GUI应用程序。

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

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

GUI概述

以前我们接触的操作窗口就是dos窗口,而且该窗口也有很大的局限性,比如只能使用dos命令,而且效率也比较低,所以Java为我们提供了GUI(图形用户话界面),用来可以直接操作图形

GUI和其他类一样也封装哎java.awt和javax,Swing这两个包中

区别:java awt这个包调用的是本地系统的方法,依赖于系统,跨平台性较差,属于重量级控件

javax.swing这个包是在awt的基础上,建立了一套图形用户界面的系统,提供了更多的控件,而且这些控件全部都是用Java写的,并且跨平台性更强。属于轻量级控件。

Java中布局

容器中的排列顺序就是布局

流式布局(FlowLayOut):默认时居中对齐,从左往右排序,如果一行不能够放下,那么就换行,依然也是居中对齐(Pannel默认的布局管理器)

边界布局(BorderLayOut):东南西北中,默认时居中对齐,如果没有指定控件的边界,那么该控件遍铺满整个窗体(Frame默认的布局管理器);

GrideLayOut():网格式布局

GridBagLayOut:网格包式布局:

CardLayOut:卡片式布局:

实例一:

需求:创建一个简单的GUI图形界面

/*
创建图形化界面的步骤:
1创建一个窗体framme
2设置窗体的基本属性,比如大小,位置,以及布局
3创建组件
4将组件添加到窗体中去.
*/
/*通过实验我们发现图形化界面是用另一个线程来控制,只要开启图形化界面,就会开启一个线程*/
import java.awt.*;
class GUIdemo1_1 
{
	public static void main(String[] args) 
	{
		Frame f=new Frame("我的窗体");//创建一个不可见的窗体
		f.setVisible(true);
		f.setLocation(300,400);
		f.setSize(400,400);
		f.setLayout(new FlowLayout());
		Button b=new Button("按钮");
		f.add(b);

	}
}
运行结果如下:


事件监听机制的流程:


事件处理机制的的特点:

1事件源:在java中是awt或者swing包中的组件。

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

3监听器:将有可能触发的动作(有可能有多个)封装在监听器中

4事件处理程序:由程序员来编写。

前面三种在java中已经编写好。不需要程序员进行编写。

窗体事件的演示

实例:在关闭Frame窗口时,提示关闭汉字。

演示实例如下:

import java.awt.*;
import java.awt.event.*;
class GUIDemo1_2 
{
	public static void main(String[] args) 
	{
		//创建一个窗体:(1事件源)
		Frame f=new Frame();
		f.setSize(300,300);
		f.setLocation(213,121);
		f.setLayout(new FlowLayout());//给船体进行布局
		Button b=new Button("我是按钮");
		f.add(b);
		/*f.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e)
			{
				System.out.println("我关");
				System.exit(0);//关闭虚拟机2014-12-20
			}
			public void windowOpened(WindowEvent e)
			{
				System.out.println("打开了");
			}
		
		
		});//定义一个匿名的时间监听器,将监听器注册到事件源上,并覆盖WindowClosing方法,创建自己的时间处理程序。
		*/
		f.addWindowListener(new MyListener());
				f.setVisible(true);
		
	}

}
//WindowAdapter是WindowListener接口的实现子类,而且这个类是一个抽象类,复写了接口中的所有方法,但是方法的内容都是null,所以我们可以自定义一个事件处理程序,那样就只需要写我们需要监听的事件,如果我们直接继承自WindowListenner,那么我们就需要复写接口里面所有的方法,那样效率太低。
class MyListener extends WindowAdapter
{
	public void windowClosing(WindowEvent e)//只要外部有动作引用事件,那么就让那个动作封装成一个对象,并赋给e
	{
		System.out.println("我关");
		System.exit(0);
	}
	
	public void windowActivated(WindowEvent e)//注意窗体先打开触发的是windowActivated(也就是窗体前置这个动作)这个事件。然后才是触发windowOpened这个事件。
	{
		System.out.println("激活了");
	}
	public void windowOpened(WindowEvent e)
	{
		System.out.println("窗体打开了");
	}
}

接下来,我们讨论一下容器的鼠标事件和键盘事件。

代码如下:

import java.awt.*;
import java.awt.event.*;
class GUIDemo1_4 
{
	private Frame f;
	private Button btn;
	GUIDemo1_4()
	{
		init();
	}
	public void init()
	{
		f=new Frame();
		btn=new Button("我的按钮");
		f.setBounds(100,200,400,500);
		f.setLayout(new FlowLayout());
		f.add(btn);
		myEvent();
		f.setVisible(true);
	}
	public void myEvent()
	{
		f.addWindowListener(new WindowAdapter(){
		public void windowClosing(WindowEvent e)
		{
			System.out.println("窗口已经关闭");
			System.exit(0);//关闭虚拟机
		}	
		});
		//btn.addActionListener(new ActionListener(){
			//actionPerformed这个事件是表示组件发生操作时就会被调用,比如触发这个事件的动作可能是键盘触发的,也可能是鼠标触发的。
		/*public void actionPerformed(ActionEvent e)
		{
			System.out.println("窗口关闭,是按钮干的");
			System.exit(0);
		}
		});
		*/
		//通过查阅Java API文档我们发现Component这个顶级容器都支持addMouseListener这个监听器。
		btn.addMouseListener(new MouseAdapter(){
		int clickCount=1;
		int enterCount=1;
		public void mouseClicked(MouseEvent e)
		{
			if(e.getClickCount()==2)
			{
				System.out.println("鼠标双击触发");
			}
			else
			{
			 System.out.println("鼠标点击事件触发,点击次数"+clickCount++);
			}
		}
		public void mouseEntered(MouseEvent e)
		{
			System.out.println("鼠标进入事件触发,进入次数"+enterCount++);
		}
		});
	}
	public static void main(String[] args) 
	{
		new GUIDemo1_4();
	}
}
运行结果如下:



接下我们我们来继续组件的键盘事件,

需求:

接下来我们在文本框来判断输入的文字是否是数字

代码如下:

import java.awt.*;
import java.awt.event.*;
class GUIDemo1_5 
{
	private Frame f;
	private Button btn;
	private TextField tf;
	GUIDemo1_5()
	{
		init();
	}
	public void init()
	{
		f=new Frame("我的窗体");
		btn=new Button("按钮一");
		tf=new TextField(20);
		f.setBounds(100,200,400,400);
		f.setLayout(new FlowLayout());
		f.add(tf);
		f.add(btn);
		myEvent();
		f.setVisible(true);
	}
	public void myEvent()
	{
		//给按钮添加一个键盘监听
		btn.addKeyListener(new KeyAdapter(){
		 public void keyPressed(KeyEvent e)
		 {
			// if(KeyEvent.)
			// System.out.println(e.getKeyChar()+"……"+e.getKeyCode());//获取键盘录入字符和字符所对应的ASCii码
			 //System.out.println(KeyEvent.getKeyText(e.getKeyCode()));//获取键盘录入所对应的字符串文本形式。
			 if(e.getKeyCode()==KeyEvent.VK_X)
			 {
				 System.out.println("您按下的是X键");
			 }
		 }
		});
		f.addWindowListener(new WindowAdapter(){
		 public void windowClosing(WindowEvent e)
		 {
			 System.exit(0);
		 }
		});
		//用于校验文本框是否是输入的数字.
		tf.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e)
			{
				int keycode=e.getKeyCode();
				if(!(keycode>=KeyEvent.VK_0&&keycode<=KeyEvent.VK_9))
				{
					System.out.println("您输入的不是数字:"+e.getKeyChar()+"……"+e.getKeyCode());
					//通过查询KeyEvent的基类InputEvent发现有一个方法就是consume(),这个方法来屏蔽键。
					e.consume();
				}
			}
		});
	}
	public static void main(String[] args) 
	{
		new GUIDemo1_5();
	}
}
运行结果如下:


通过上面的代码我们发现,其实图形用户化界面和我们以前使写过的Dos命令行代码使用的思想是一样的,只不过我们将展示的页面展现给用户。

接下来我们将实现一个小的Demo:

需求:在文本框中输入一个目录名,然后在另一个文本框中显示该目录名下所有的文件。

代码如下:

import java.awt.*;
import java.io.*;
import java.awt.event.*;
class GUIDemo1_6 
{
	private Frame f;
	private Button btn;
	private TextField tf;
	private TextArea ta;
	GUIDemo1_6()
	{
		init();
	}
	public void init()
	{
		f=new Frame();
		btn=new Button("转入");
		tf=new TextField(40);
		ta=new TextArea(40,60);
		f.setBounds(100,200,600,600);
		f.setLayout(new FlowLayout());
		f.add(tf);
		f.add(btn);
		f.add(ta);
		myEvent();
		f.setVisible(true);
	}
	public void myEvent()
	{
		f.addWindowListener(new WindowAdapter(){
		public void windowClosing(WindowEvent e)
		{
			sop("窗口关闭");
			System.exit(0);
		}
		});
		btn.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e)
		{
			
			File dir=new File(tf.getText());
			if(dir.exists()&&dir.isDirectory())
			{
				String[] names=dir.list();
				for(String name:names)
				{
					ta.append(name+"\r\n");
				}
			}
			tf.setText("");
		}
		
		});
	}

	public static void main(String[] args) 
	{
		new GUIDemo1_6();
	}
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
}
运行结果如下:



接下来我们将结束对话框的使用方法。

通过查阅Java API文档我们发现,其实Dialog就是一个容器,我们可以向里面添加需要的组件,比如Button和Label等组件。使用代码如下:

import java.io.*;
import java.awt.*;
import java.awt.event.*;
class GUIDemo1_7 
{
	private Frame f;
	private Button btn;
	private Dialog dia;
	private Label lab;
	private Button btnOk;
	private TextField tf;
	private TextArea ta;
	GUIDemo1_7()
	{	
		init();
	}
	public void init()
	{
		f=new Frame("我的窗体");
		btn=new Button("转到");
		btnOk=new Button("确定");
		dia=new Dialog(f,"提示消息",true);//构造一个最初不可见的、无模式的 Dialog,它带有指定的所有者 Frame 和标题。第三个参数表示如果为true,表示如果不对对话框进行操作,如果没有操作,就不能操作其他的窗口。
		dia.setBounds(100,200,300,150);
		tf=new TextField(40);
		ta=new TextArea(40,50);
		lab=new Label();
		f.setBounds(100,200,600,600);
		f.setLayout(new FlowLayout());
		dia.setLayout(new FlowLayout());
		dia.add(lab);
		dia.add(btnOk);
		f.add(tf);
		f.add(btn);
		f.add(ta);
		myEvent();
		f.setVisible(true);
	}
	public void myEvent()
	{
		tf.addKeyListener(new KeyAdapter(){
		 public void keyPressed(KeyEvent e)
		 {
			 //录入目录后,如果用户按下Enter键,开始显示录入目录下对应的所有文件。
			 if(e.getKeyCode()==KeyEvent.VK_ENTER)
			 {
				searchDir();
			 }
		 }
		});
		btnOk.addActionListener(new ActionListener(){
		 public void actionPerformed(ActionEvent e)
		{
			dia.setVisible(false);
		}
		
		});
		dia.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e)
			{
				dia.setVisible(false);
			}
		
		});
		f.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		
		});
		btn.addActionListener(new ActionListener(){
		 public void actionPerformed(ActionEvent e)
		 {
			 searchDir();
		 }
		});
	}
	public static void main(String[] args) 
	{
		new GUIDemo1_7();
	}
	private void searchDir()
	{
		File dir=new File(tf.getText());
			//如果输入的是文件夹名
			if((dir.exists()&&dir.isDirectory()))
			{
				String[]names=dir.list();
				for(String name :names)
				{
					ta.append(name+"\r\n");
				}
			}
			//如果输入的不是文件夹名
			else
			{
				lab.setText("错误提示:"+dir+"不是文件夹,请重新输入");
				dia.setVisible(true);
			}
			tf.setText("");
	}
}
运行结果如下:

接下来,我们将接着继续使用Menu这个组件的使用方法。

代码如下:

import java.awt.*;
import java.awt.event.*;
class GUIDemo1_8 
{
	private Frame f;
	private MenuBar mb;
	private Menu m1,m2;
	private MenuItem mi,m3;
	GUIDemo1_8()
	{
		init();
	}
	private void init()
	{
		f=new Frame("我的窗口");
		f.setBounds(100,200,400,400);
		f.setLayout(new FlowLayout());
		mb=new MenuBar();
		m1=new Menu("文件");
		mi=new MenuItem("退出");
		m2=new Menu("操作");
		m3=new MenuItem("编辑");
		m1.add(mi);
		mb.add(m1);
		m1.add(m2);
		m2.add(m3);
		f.setMenuBar(mb);
		myEvent();
		f.setVisible(true);
	}
	private void myEvent()
	{
		mi.addActionListener(new ActionListener(){
		public void actionPerformed(ActionEvent e)
		{
			System.exit(0);
		}
		});
	}
	public static void main(String[] args) 
	{
		new GUIDemo1_8();
	}
}
通过上面的实例我们发现,Frame通过setMenuBar()将指定的MenuBar添加到frame中,然后将指定的Menu添加到指定的MenuBar中,如果Menu中没有子菜单了,那么就可以使用MenuItem来代替。有子菜单就只能使用Menu。

运行结果如下:

接来下,我们使用Menu和MenuBar的使用实例:

实例:使用Menu和MenuBar来模拟记事本。

代码如下:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
class GUIDemo1_9 
{
	private Frame f;
	private MenuBar mb;
	private Menu m;
	private MenuItem mi1,mi2,mi3;
	private FileDialog fdia;
	private TextArea ta;
	private String fileTemp=null;
	GUIDemo1_9()
	{
		init();
	}
	public void init()
	{
		f=new Frame("我的窗口");
		f.setBounds(100,100,500,500);
		mb=new MenuBar();
		m=new Menu("文件");
		mi1=new MenuItem("打开");
		mi2=new MenuItem("保存");
		mi3=new MenuItem("退出");
		ta=new TextArea();
		fdia=new FileDialog(f,"文件打开",FileDialog.LOAD);
		fdia.setBounds(100,100,400,400);
		m.add(mi1);
		m.add(mi2);
		m.add(mi3);
		f.setMenuBar(mb);
		f.add(ta);
		mb.add(m);
		myEvent();
		f.setVisible(true);
	}
	public void myEvent()
	{
		//模拟记事本打开文件的操作。
		 mi1.addActionListener(new ActionListener(){
		  public void actionPerformed(ActionEvent e)
		  {
			 fdia.setVisible(true);
			 ta.setText("");
			 String dirPath=fdia.getDirectory();//获取选取文件的目录名。
			 String filename=fdia.getFile();//获取文件夹的文件
			 if(dirPath==null&&filename==null)
				 return;
			 File f=new File(filename);
			 fileTemp=dirPath+filename;
			 System.out.println(dirPath+filename);
			 BufferedReader br=null;
			 try
			 {
				br=new BufferedReader(new FileReader(dirPath+filename));
				String line=null;
				while((line=br.readLine())!=null)
				{
					ta.append(line+"\r\n");
				}
			 }
			 catch (IOException e1)
			 {
				 throw new RuntimeException("文件复制失败");
			 }
			 finally
			 {
				 try
				 {
					if(br!=null)
						br.close();
				 }
				 catch (IOException e2)
				 {
					 throw new RuntimeException("字符读取流关闭失败");
				 }
			 }
		  }
		});
		//点击保存按钮也可以保存文件。
		mi2.addActionListener(new ActionListener(){
		 public void actionPerformed(ActionEvent e)
		{
			 save();
		}
		});
	    ta.addKeyListener(new KeyAdapter(){
		public void keyPressed(KeyEvent e)
		{
			//使用快键键也可以保存文件
			if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_S)
			{
				save();
			}
		}
		});
		mi3.addActionListener(new ActionListener(){
		  public void actionPerformed(ActionEvent e)
		  {
			  System.exit(0);
		  }
		});
	}
	private void save()
	{
		 BufferedWriter bw=null;
		 String text=ta.getText();
		 try
		 {
			bw=new BufferedWriter( new FileWriter(fileTemp));
			bw.write(text);
			bw.flush();
			ta.setText("");
		 }
		 catch (IOException e1)
		 {
			 throw new RuntimeException("文件保存失败");
		 }
		 finally
		 {
			 try
			 {
				if(bw!=null)
					bw.close();
			 }
			 catch (IOException e2)
			 {
				 throw new RuntimeException("字符写入流关闭失败");
			 }
		 }
	}
	public static void main(String[] args) 
	{
		new GUIDemo1_9();
	}
}




内容概要:该PPT详细介绍了企业架构设计的方法论,涵盖业务架构、数据架构、应用架构和技术架构四大核心模块。首先分析了企业架构现状,包括业务、数据、应用和技术四大架构的内容和关系,明确了企业架构设计的重要性。接着,阐述了新版企业架构总体框架(CSG-EAF 2.0)的形成过程,强调其融合了传统架构设计(TOGAF)和领域驱动设计(DDD)的优势,以适应数字化转型需求。业务架构部分通过梳理企业级和专业级价值流,细化业务能力、流程和对象,确保业务战略的有效落地。数据架构部分则遵循五大原则,确保数据的准确、一致和高效使用。应用架构方面,提出了分层解耦和服务化的设计原则,以提高灵活性和响应速度。最后,技术架构部分围绕技术框架、组件、平台和部署节点进行了详细设计,确保技术架构的稳定性和扩展性。 适合人群:适用于具有一定企业架构设计经验的IT架构师、项目经理和业务分析师,特别是那些希望深入了解如何将企业架构设计与数字化转型相结合的专业人士。 使用场景及目标:①帮助企业和组织梳理业务流程,优化业务能力,实现战略目标;②指导数据管理和应用开发,确保数据的一致性和应用的高效性;③为技术选型和系统部署提供科学依据,确保技术架构的稳定性和扩展性。 阅读建议:此资源内容详尽,涵盖企业架构设计的各个方面。建议读者在学习过程中,结合实际案例进行理解和实践,重点关注各架构模块之间的关联和协同,以便更好地应用于实际工作中。
资 源 简 介 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系, 详 情 说 明 独立分量分析(Independent Component Analysis,简称ICA)是近二十年来逐渐发展起来的一种盲信号分离方法。它是一种统计方法,其目的是从由传感器收集到的混合信号中分离相互独立的源信号,使得这些分离出来的源信号之间尽可能独立。它在语音识别、电信和医学信号处理等信号处理方面有着广泛的应用,目前已成为盲信号处理,人工神经网络等研究领域中的一个研究热点。 本文简要的阐述了ICA的发展、应用和现状,详细地论述了ICA的原理及实现过程,系统地介绍了目前几种主要ICA算法以及它们之间的内在联系,在此基础上重点分析了一种快速ICA实现算法一FastICA。物质的非线性荧光谱信号可以看成是由多个相互独立的源信号组合成的混合信号,而这些独立的源信号可以看成是光谱的特征信号。为了更好的了解光谱信号的特征,本文利用独立分量分析的思想和方法,提出了利用FastICA算法提取光谱信号的特征的方案,并进行了详细的仿真实验。 此外,我们还进行了进一步的研究,探索了其他可能的ICA应用领域,如音乐信号处理、图像处理以及金融数据分析等。通过在这些领域中的实验和应用,我们发现ICA在提取信号特征、降噪和信号分离等方面具有广泛的潜力和应用前景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值