Java基础——GUI概述

GUI图形用户界面

GUI

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

CLI

命令行用户接口:就是常见的dos命令行操作,需要记忆一些常用的命令,操作不直观

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

Awt和Swing

  • java.Awt抽象窗口工具包,需要调用本地系统方法实现功能,属于重量级控件
  • javax.Swing在Awt的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由java实现,增强了移植性,属轻量级控件。

这里写图片描述

容器中的组件的排放方式,就是布局。
常见的布局管理器:

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

那么我们开始建立一个新的窗体,
步骤是:
建立一个窗体;
设置窗体的基本属性,包括大小,位置,布局
通过add方法在窗体中添加组件
通过setVisible()里边传true值使窗体可见。

演示:

//演示基本窗体的建立
import java.awt.*;
public class FrameDemo {
	public static void main(String[] args) 
	{
		
		Frame f = new Frame("myFrame");//先创建一个窗体对象

		f.setLayout(new FlowLayout());//设置布局方式为流式布局

		f.setLocation(300,200);//设置窗体位置在距离左边300px,距离上边200px

		f.setSize(500,400);//设置窗体大小为500*400

		Button b = new Button("按钮1");//创建一个按钮对象

		f.add(b);//将按钮对象添加进窗体中

		f.setVisible(true);//将窗体设置为可见
	}
}

运行结果:

这里写图片描述

注意:
Frame窗体默认的是面板式布局,就是添加进来的组件会布满整个窗体,所以这里使用了流式布局。
setVisible方法必须放在最后一行,否则有些效果出不来。

当我们在操作创建下的窗体的时候,发现,最大化最小化都可以实现,但是关闭按钮点了没有反应,窗体不会关闭,这是为什么呢?

这就设计到了事件监听机制的问题:

事件监听机制的组成:

  • 事件源
  • 事件
  • 监听器
  • 事件处理(引发事件后处理方式)

这里写图片描述

事件源:就是Awt包或者Swing包中的那些图形化界面组件

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

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

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

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

//演示基本窗体的建立
import java.awt.*;
import java.awt.event.*;
public class FrameDemo {
	public static void main(String[] args) 
	{
		
		Frame f = new Frame("myFrame");//先创建一个窗体对象

		f.setLayout(new FlowLayout());//设置布局方式为流式布局

		f.setLocation(300,200);//设置窗体位置在距离左边300px,距离上边200px

		f.setSize(500,400);//设置窗体大小为500*400

		Button b = new Button("按钮1");//创建一个按钮对象

		f.add(b);//将按钮对象添加进窗体中
		


		//给窗体添加一个事件监听器
		f.addWindowListener(new WindowAdapter()//传进来一个事件监听器WindowListener但是这里边有7个抽象方法,
		{
			//WindowAdapter实现了WindowListener接口,而且覆盖了所有的方法
			//可以直接拿过来创建匿名内部类进行方法的复写

			//关闭窗口的方法
			public void windowClosing(WindowEvent e)//当事件发生的时候,调用该方法
			{
				System.out.println("关闭");
				System.exit(0);
			}
			//当窗口被打开的时候调用
			public void windowOpened(WindowEvent e)
			{
				System.out.println("打开窗体");
			}
			//当窗口获得焦点的时候会自动调用
			public void windowActivated(WindowEvent e)
			{
				System.out.println("激活窗口");
			}
		});

		f.setVisible(true);//将窗体设置为可见
	}
}

运行结果:

窗口可以直接被关闭,而且控制台上会有数据打印出来。

这里写图片描述

其实加监听器的方法就是先给窗体调用添加监听器的方法addWindowListener
同时参数要传进去一个WindowListener对象,可是WindowListener是一个接口,
发现了WindowListener有一个子类,WindowAdapter实现了WindowListener接口,并且复写了WindowListener所有的方法,而且方法体都是空的,
但是WindowAdapt是一个抽象的类,不可以创建对象,
于是用内部类的方式,复写里边的方法
每一个处理方法被调用的时候,都要有个事件传进来。

//规范化书写,将窗体布局的设置和添加监听器分离开
//给按钮添加监听器,能够关闭掉窗体
import java.awt.*;
import java.awt.event.*;
class MyFrame
{
	MyFrame()
	{
		inis();
	}
	Frame f = null;
	Button b = null;
	public void inis()
	{
		f = new Frame("我的窗体");
		b = new Button("关闭");
		f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高
		f.setLayout(new FlowLayout());
		f.add(b);
		myListener();//该方法可以添加进来全部的监听器
		f.setVisible(true);
	}
	//这里添加监听器
	public void myListener()
	{
		//关闭键关闭窗体的监听器
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		//通过按钮关闭窗体
		b.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				System.out.println("关闭,按钮干的");
				System.exit(0);
			}
		});
	}
}
public class FrameDemo2 {
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}

运行结果:
这里写图片描述

操作成功,为什么WindowListener需要有Adapter(适配器)呢?而按钮监听器不用呢?

这是因为,Window上边的监听器(接口)中的方法有7个,要是一个一个去复写,很累的,所以就出现了适配器,适配器覆盖了所有的方法但是方法体为空的,我们使用适配器,用哪个方法就复写哪个方法,很方便的。

但是在按钮的监听器中,只有一个方法,actionPerformed,所以用不着适配器。

鼠标事件:

在按钮上添加鼠标活动事件:

实例如下:

//规范化书写,将窗体布局的设置和添加监听器分离开
//给按钮添加鼠标监听器
import java.awt.*;
import java.awt.event.*;
class MyFrame
{
	MyFrame()
	{
		inis();
	}
	Frame f = null;
	Button b = null;
	public void inis()
	{
		f = new Frame("我的窗体");
		b = new Button("关闭");
		f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高
		f.setLayout(new FlowLayout());
		f.add(b);
		myListener();//该方法可以添加进来全部的监听器
		f.setVisible(true);
	}
	//这里添加监听器
	public void myListener()
	{
		//关闭键关闭窗体的监听器
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		//鼠标进入按钮监听器
		b.addMouseListener(new MouseAdapter()
		{
			int count = 1;
			public void mouseEntered(MouseEvent e)
			{
				System.out.println("鼠标进入按钮区域:"+count++);
			}
		});
		//鼠标点击事件监听器
		b.addMouseListener(new MouseAdapter()
		{
			int count = 1;
			public void mouseClicked(MouseEvent e)
			{
				System.out.println("鼠标点击"+count++);
			}
		});
		//MouseEvent中有可以获取鼠标点击次数的方法int getClickCount()
		//可以用来设置单击双击事件。

		//也可以设置动作监听器:
		b.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				System.out.println("action   run");
			}
		});
	}
}
public class FrameDemo3 {
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}

运行结果:
这里写图片描述

结果可以发现,在给按钮同时加上鼠标监听器和动作监听器之后,点击一次鼠标,是鼠标监听器先执行,
这是因为鼠标监听事件更具体一些,所以先执行。

给按钮添加键盘监听事件:

//规范化书写,将窗体布局的设置和添加监听器分离开
//给按钮添加键盘监听器
import java.awt.*;
import java.awt.event.*;
class MyFrame
{
	MyFrame()
	{
		inis();
	}
	Frame f = null;
	Button b = null;
	public void inis()
	{
		f = new Frame("我的窗体");
		b = new Button("关闭");
		f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高
		f.setLayout(new FlowLayout());
		f.add(b);
		myListener();//该方法可以添加进来全部的监听器
		f.setVisible(true);
	}
	//这里添加监听器
	public void myListener()
	{
		//关闭键关闭窗体的监听器
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		b.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				System.out.println(KeyEvent.getKeyText(e.getKeyCode()));
				//getKeyCode方法可以根据键盘键入的值获取到相应的int类型的值
				//getKeyText方法可以根据传入的int类型的值获取到键盘上的文字形式的字符串
			}
		});
	}
}
public class FrameDemo3 {
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}

运行结果为:

这里写图片描述

然后演示一个扣扣号的输入框:
需求是:一个输入框,只能输入数字,如果输入其他字符,则提示这个字符是非法的,而且该非法字符不可以写入到输入框中:

//一个扣扣输入框,只能输入数字
import java.awt.*;
import java.awt.event.*;
class MyFrame
{
	MyFrame()
	{
		inis();
	}
	Frame f = null;
	TextField tf = null;
	Button b = null;
	public void inis()
	{
		f = new Frame("QQ窗体");
		b = new Button("登陆");
		tf = new TextField(15);//新建一个文本框,列数为15
		f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高
		f.setLayout(new FlowLayout());
		f.add(tf);
		f.add(b);
		myListener();//该方法可以添加进来全部的监听器
		f.setVisible(true);
	}
	//这里添加监听器
	public void myListener()
	{
		//关闭键关闭窗体的监听器
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				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("输入的字符是非法的");
					//默认是键盘一敲就文字就会到了输入框中,
					//consume方法就是改变这种默认的方式。
					e.consume();
				}
			}
		});
	}
}
public class MouseAndKeyTest {
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}

运行结果为:

这里写图片描述

演示组合键怎么读取的:

//组合键的使用
import java.awt.*;
import java.awt.event.*;
class MyFrame
{
	MyFrame()
	{
		inis();
	}
	Frame f = null;
	Button b = null;
	public void inis()
	{
		f = new Frame("我的窗体");
		b = new Button("关闭");
		f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高
		f.setLayout(new FlowLayout());
		f.add(b);
		myListener();//该方法可以添加进来全部的监听器
		f.setVisible(true);
	}
	//这里添加监听器
	public void myListener()
	{
		//关闭键关闭窗体的监听器
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		b.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				//判断Ctrl键是否已经按下,和按键是否为Enter键
				if(e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER)
					System.out.println("Control   +   enter    run ");
			}
		});
	}
}

public class FrameDemo4 {
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}

运行结果:

这里写图片描述

练习:列出指定的目录中的内容:

//列出指定目录下的文件名称
//具体是:在最上方的文本框中输入一个目录,然后在下方的文本区域中输出该目录下的所有文件
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class MyFrame
{
	MyFrame()
	{
		inis();
	}
	//在外边建立所有对象的引用,省的等会找不到还是怎么的
	Frame f = null;
	Button b = null;
	TextField tf = null;
	TextArea ta = null;
	//从这里开始定义的是弹出错误对话框的对象
	Dialog d = null;
	Label l = null;
	Button but = null;
	public void inis()
	{
		f = new Frame("我的Window");
		b = new Button("转到");
		tf = new TextField(55);
		ta = new TextArea(40,62);
		f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高
		f.setLayout(new FlowLayout());
		f.add(tf);
		f.add(b);
		f.add(ta);
		myListener();//该方法可以添加进来全部的监听器
		f.setVisible(true);
		
	}
	//这里添加监听器
	public void myListener()
	{
		//关闭键关闭窗体的监听器
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		//给转到按钮添加时间监听器
		b.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				showDir();
			}
		});
		//键盘监听器,输完目录之后按回车可以直接显示出目录中的文件
		tf.addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				if(KeyEvent.VK_ENTER==e.getKeyCode())
				{
					showDir();
				}
			}
		});
		
	}
	//这里封装的是按照文本框中输入的目录获取到目录下的文件的方法
	private void showDir()
	{
		//每一次列出目录的时候,都把文本区域中的数据清空
		ta.setText("");
		String line = tf.getText();
		File dir = new File(line);
		//判断如果存在,而且文件是目录,则写入数据,如果不是目录,或者目录不存在,弹出对话框
		if(dir.exists() && dir.isDirectory())
		{
			String[] names = dir.list();
			for(String name:names)
			{
				ta.append(name+"\r\n");
			}
		}
		else
		{
			d = new Dialog(f,"温馨提示",true);
			l = new Label();
			but = new Button("确定");
			d.setBounds(500,400,270,100);
			d.setLayout(new FlowLayout());
			d.add(l);
			d.add(but);
			
			String s = "对不起,您输入的内容"+line+"有误,请重输";
			l.setText(s);
			//点关闭按钮可以使对话框关闭
			d.addWindowListener(new WindowAdapter()
			{
				public void windowClosing(WindowEvent e)
				{
					d.setVisible(false);
				}
			});
			//鼠标点击按钮可以使对话框关闭
			but.addActionListener(new ActionListener()
			{
				public void actionPerformed(ActionEvent e)
				{
					d.setVisible(false);
				}
			});
			//按回车键可以使对话框关闭
			but.addMouseListener(new MouseAdapter()
			{
				public void mouseClicked(MouseEvent e)
				{
					d.setVisible(false);
				}
			});
			but.addKeyListener(new KeyAdapter()
			{
				public void keyPressed(KeyEvent e)
				{
					d.setVisible(false);
				}
			});
			d.setVisible(true);
		}
		tf.setText("");//将目录中的文件输入文本区域后就把文本框中的数据清空
	}
}

public class MyWindowDemo {
	public static void main(String[] args) 
	{
		new MyFrame();
	}
}

运行结果:
当输入正确的目录之后是这样的结果:

这里写图片描述

当输入错误的目录之后是这样的结果:

这里写图片描述

图形化界面中的菜单

MenuBar菜单栏,用窗体的setMenuBar方法添加,而不是add方法
Menu:菜单,用MenuBar对象调用add方法添加进菜单栏中
MenuItem:条目,菜单中的一个一个的选项。

演示:

//菜单条的添加演示
import java.awt.*;
import java.awt.event.*;
class MenuDemo
{
	MenuDemo()
	{
		isit();
	}
	private Frame f = null;
	private MenuBar mb = null;
	private Menu m1 = null;
	private Menu m2 = null;
	private MenuItem mi1= null;
	private MenuItem mi2= null;
	private MenuItem mi3= null;
	private MenuItem mi4= null;
	private MenuItem mi5= null;
	public void isit()
	{
		f = new Frame("我的菜单");
		mb = new MenuBar();
		m1 = new Menu("文件");//这是一个菜单
		m2 = new Menu("新建");//这是一个菜单中的子菜单,下边还有条目
		mi1 = new MenuItem("打开");//这是文件菜单中的条目
		mi2 = new MenuItem("保存");
		mi3 = new MenuItem("退出");
		mi4 = new MenuItem("java");//这是子菜单中的子条目中的内容
		mi5 = new MenuItem("文本文件");

		f.setBounds(400,300,400,300);
		f.setLayout(new FlowLayout());
		f.setMenuBar(mb);//使用这个方法添加MenuBar菜单栏,而不是用add方法
		mb.add(m1);
		m1.add(m2);
		m2.add(mi4);
		m2.add(mi5);
		m1.add(mi1);
		m1.add(mi2);
		m1.add(mi3);
		
		myEvent();
		f.setVisible(true);
	}
	public void myEvent()
	{
		//点关闭按钮可以关掉窗体
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		//菜单中的退出条目,可以结束窗体
		mi3.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}
		});
	}
	
}
public class MyMenuDemo {
	public static void main(String[] args) 
	{
		new MenuDemo();
	}
}

运行结果:

这里写图片描述

文件对话框的使用:
保存文件和打开文件:

实例:

//练习,打开文件,和保存文件的过程
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class MenuDemo
{
	MenuDemo()
	{
		isit();
	}
	private Frame f = null;
	private MenuBar mb = null;
	private Menu m1 = null;
	private Menu m2 = null;
	private MenuItem mi1= null;
	private MenuItem mi2= null;
	private MenuItem mi3= null;
	private MenuItem mi4= null;
	private MenuItem mi5= null;
	private TextArea ta =null;
	private FileDialog open = null;
	private FileDialog save = null;
	private File file=null;
	public void isit()
	{
		f = new Frame("我的菜单");
		mb = new MenuBar();
		m1 = new Menu("文件");//这是一个菜单
		m2 = new Menu("新建");//这是一个菜单中的子菜单,下边还有条目
		mi1 = new MenuItem("打开");//这是文件菜单中的条目
		mi2 = new MenuItem("保存");
		mi3 = new MenuItem("退出");
		mi4 = new MenuItem("java");//这是子菜单中的子条目中的内容
		mi5 = new MenuItem("文本文件");
		ta = new TextArea();
		open = new FileDialog(f,"我的打开",FileDialog.LOAD);
		save= new FileDialog(f,"我的保存",FileDialog.SAVE);

		f.setBounds(300,200,600,500);
		f.setMenuBar(mb);//使用这个方法添加MenuBar菜单栏,而不是用add方法
		mb.add(m1);
		m1.add(m2);
		m2.add(mi4);
		m2.add(mi5);
		m1.add(mi1);
		m1.add(mi2);
		m1.add(mi3);
		f.add(ta);
		
		myEvent();
		f.setVisible(true);
	}
	public void myEvent()
	{
		//点关闭按钮可以关掉窗体
		f.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				System.exit(0);
			}
		});
		//菜单中的退出条目,可以结束窗体
		mi3.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				System.exit(0);
			}
		});
		//想要在点打开的时候,弹出一个文件对话框来:
		mi1.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				open.setVisible(true);
				//FileDialog对象获取到打开的文件的目录和文件名
				String dirPath = open.getDirectory();
				String fileName = open.getFile();
				//如果这个时候点了取消,返回的值都是空的,容易造成空指针异常,这里如果都为空就什么都不做
				if(dirPath==null || fileName==null)
					return;
				BufferedReader bufr = null;
				ta.setText("");//每一次读取之前把ta里边的数据清空
				try
				{
					file = new File(dirPath+fileName);
					bufr = new BufferedReader(new FileReader(file));
					String line = null;
					while((line = bufr.readLine())!=null)
					{
						ta.append(line+"\r\n");
					}
				}
				catch (IOException ex)
				{
					throw new RuntimeException("文件读取失败");
				}
				finally
				{
					if(bufr!=null)
						try
						{
							bufr.close();
						}
						catch (IOException ex)
						{
							ex.printStackTrace();
						}
				}
			}
		});
		//想要在点保存的时候,弹出一个保存的对话框
		mi2.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				save.setVisible(true);
				save.setVisible(true);
				String dirPath = save.getDirectory();
				String fileName = save.getFile();
				if(dirPath==null || fileName==null)
					return;
				file = new File(dirPath+fileName);
				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
				{
					if(bufw!=null)
					{
						try
						{
							bufw.close();
						}
						catch (IOException ex)
						{
							ex.printStackTrace();
						}
					}
				}
			}
		});
	}
	
}
public class MyMenuDemo {
	public static void main(String[] args) 
	{
		new MenuDemo();
	}
}

运行结果可以实现,文件的LOAD和SAVE

这里写图片描述

这里写图片描述

jar包双击执行

想要将写好的程序可以双击就执行的,就像某一个软件一样的,
我们以前学过的jar命令,将类文件编译到指定的文件夹。

javac -d e:\others\myclass MyMenuDemo.java
将类文件编译到指定的包中

在和mymenu包同级目录下,创建一个文本文件,取名为1.txt
里边写上:
这里写图片描述

jar -cvfm my.jar 1.txt mymenu
将指定的包打成jar包

这样的话就可以双击执行了。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值