java之GUI

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java之GUI相关的知识,希望对你有一定的参考价值。

一、GUI概述

  GUI:

    Graphical User Interface图形用户接口。

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

  CLI:

    Command Line User Interface命令行用户接口

    就是常见的Dos命令行操作,需要记住一些常用的命令,操作不直观。

java为GUI提供的对象都存在java.awt和javax.swing两个包中。


二、awt和swing包的概述

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

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


三、GUI继承体系

技术分享


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

package cn5;

import java.awt.Frame;
/**
 * 创建一个最简单的窗体  
 */
public class AWTDemo {
	public static void main(String[] args) {
		//创建一个最初不可见的窗体对象
		Frame f = new Frame();
		//设置窗体标题
		f.setTitle("哈哈 呵呵 嘻嘻 笨笨");
		//设置窗体大小
		f.setSize(400, 300);//单位:默认像素
		//设置窗体坐标
		f.setLocation(400, 200);
		//让窗体可见
		f.setVisible(true);
	}

}

技术分享

其他方法实现上图的效果

package cn5;

import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Point;

public class AWTDemo2 {
	public static void main(String[] args) {
		//创建一个不可见的窗体
		Frame f = new Frame();
		//设置标题
		f.setTitle("哈哈");
		//设置位置
		f.setLocation(new Point(400, 200));
		//设置大小
		f.setSize(new Dimension(400, 300));
		//使得窗体可见
		f.setVisible(true);
	}

}
package cn5;

import java.awt.Frame;

public class AWTDemo2 {
	public static void main(String[] args) {
		//创建一个不可见的窗体
		Frame f = new Frame();
		//设置标题
		f.setTitle("哈哈");
		f.setBounds(400,200,400,300);
		//使得窗体可见
		f.setVisible(true);
	}

}

实现窗体关闭

package cn5;

import java.awt.Frame;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
/**
 * 事件监听机制
 * 		事件源:事件发生的地方。
 * 		事件:就是要发生的事情。
 * 		事件处理:就是针对发生的事情做出的处理方案。
 * 		事件监听:就是把事件源和事件关联起来。
 * 
 * 举例:人受伤事件
 * 		事件源:人(具体的对象)
 * 			Person p1 = new Person("张三");
 * 			Person p2 = new Person("李四");
 * 		事件:受伤
 * 			interface 受伤接口{
 * 				一拳();
 * 				一脚();
 * 				一板砖();
 * 			}
 * 		事件处理:
 * 			事件处理类 implements 受伤接口{
 * 				一拳(){
 * 					System.out.println("鼻子流血了,去医院");
 * 				}
 * 				一脚(){
 * 					System.out.println("晕倒了");
 * 				}
 * 				一板砖(){
 * 					System.out.println("头破血流");
 * 				}
 * 			}
 *		事件监听:
 *			p1.注册监听(受伤接口)
 *			p2.注册监听(受伤接口)
 */
public class AWTDemo3 {
	public static void main(String[] args) {
		//创建一个最初不可见的窗体对象
		Frame f = new Frame("窗体关闭");
		//设置窗体属性
		f.setBounds(400, 200, 400, 300);
		
		//让窗体关闭
		//事件源:窗体f
		//事件:对窗体的处理
		//事件处理:关闭窗体(System.exit(0))
		//事件监听:
		f.addWindowListener(new WindowListener() {
			
			@Override
			public void windowOpened(WindowEvent e) {
				
			}
			
			@Override
			public void windowIconified(WindowEvent e) {
				
			}
			
			@Override
			public void windowDeiconified(WindowEvent e) {
				
			}
			
			@Override
			public void windowDeactivated(WindowEvent e) {
			}
			
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
			
			@Override
			public void windowClosed(WindowEvent e) {
				
			}
			
			@Override
			public void windowActivated(WindowEvent e) {
				
			}
		});
		//使得窗体可见
		f.setVisible(true);
		
	}

}

  按照上面的代码,是不是有很多多余的代码,为啥子?且看下面分解。  


四、适配器模式

package cn6;

public interface IUserDAO {
	/**
	 * 增加用户
	 */
	public void add();
	/**
	 * 删除用户
	 */
	public void delete();
	/**
	 * 修改用户
	 */
	public void update();
	/**
	 * 查询用户
	 */
	public void find();

}
package cn6;

public class UserDAOImpl implements IUserDAO {

	@Override
	public void add() {
		System.out.println("用户增加");
	}

	@Override
	public void delete() {
		System.out.println("用户删除");
	}

	@Override
	public void update() {
		System.out.println("用户修改");
	}

	@Override
	public void find() {
		System.out.println("用户查询");
	}

}
package cn6;

public class Test {
	public static void main(String[] args) {
		IUserDAO userDAO = new UserDAOImpl();
		userDAO.add();
		userDAO.delete();
		userDAO.find();
		userDAO.update();
	}

}

用户增加

用户删除

用户查询

用户修改

  但是如果我只想要用户增加功能,此时,你会想,我不调用delete(),find()和update()方法不就可以了吗?

package cn6;

public interface IUserDAO {
	/**
	 * 增加用户
	 */
	public void add();
	/**
	 * 删除用户
	 */
	public void delete();
	/**
	 * 修改用户
	 */
	public void update();
	/**
	 * 查询用户
	 */
	public void find();

}
package cn6;

public class UserDAOImpl implements IUserDAO {

	@Override
	public void add() {
		System.out.println("用户增加");
	}

	@Override
	public void delete() {
		System.out.println("用户删除");
	}

	@Override
	public void update() {
		System.out.println("用户修改");
	}

	@Override
	public void find() {
		System.out.println("用户查询");
	}

}
package cn6;

public class Test {
	public static void main(String[] args) {
		IUserDAO userDAO = new UserDAOImpl();
		userDAO.add();
		
	}

}

是的,但是,你在接口的实现类中是不是还要重写接口中定义的方法,即使你不写具体实现。但是,老子就是讨厌写很多多余的代码,我有洁癖,你拿我怎么办?


哼哼,在接口和具体的实现类之间加一个抽象类(适配器类)。

接口--适配器(抽象类)--具体实现类

package cn6;

public interface IUserDAO {
	/**
	 * 增加用户
	 */
	public void add();
	/**
	 * 删除用户
	 */
	public void delete();
	/**
	 * 修改用户
	 */
	public void update();
	/**
	 * 查询用户
	 */
	public void find();

}
package cn6;

public abstract class UserAdapter implements IUserDAO {

	@Override
	public void add() {
		
	}

	@Override
	public void delete() {
		
	}

	@Override
	public void update() {
		
	}

	@Override
	public void find() {
		
	}
	

}
package cn6;

public class UserDAOAddImpl extends UserAdapter {

	@Override
	public void add() {
		System.out.println("用户添加");
	}
	
	
	
	

}

注意:如果此时在UserDAOAddImpl类中不写任何方法,是不会报错了,因为抽象类UserAdapter已经实现了接口,虽然仅仅都是空实现而已。

package cn6;

public class UserDAOAddImpl extends UserAdapter {

}

但是因为我只想要用户增加功能,所以呢?我就写了一个类来实现用户增加功能啦,这样是不是很省事,这样我就不用再去实现4个方法了。

package cn6;

public class UserDAOAddImpl extends UserAdapter {
	@Override
	public void add() {
		System.out.println("用户增加");
	}
	
	
	
	

}

如果我现在只想要用户删除功能,我就写一个类来实现用户删除的功能就可以了,当然必须继承这个抽象类了。

package cn6;

public class UserDAODeleteImpl extends UserAdapter {
	@Override
	public void delete() {
		System.out.println("用户删除");
	}
}

其它的,依次类推即可。

package cn6;

public class Test {
	public static void main(String[] args) {
		//用户增加
		IUserDAO userDAO = new UserDAOAddImpl();
		userDAO.add();
		//用户删除
		userDAO = new UserDAODeleteImpl();
		userDAO.delete();
		
	}

}

但是看到这边,你可以觉得好像很刚开始那种没什么两样。

package cn6;

public class UserDAOImpl implements IUserDAO {

	@Override
	public void add() {
		System.out.println("用户增加");
	}

	@Override
	public void delete() {
		System.out.println("用户删除");
	}

	@Override
	public void update() {
		System.out.println("用户修改");
	}

	@Override
	public void find() {
		System.out.println("用户查询");
	}

}

但是,实际却不是如此,上面的这个代码产生了很多垃圾代码,因为我就只要要用户增加功能,而你却实现了用户增加、用户删除等等,这个时候,你可能会想,我去,你想要用户增加功能是吧,可以。看下面的代码。

package cn6;

public class UserDAOImpl implements IUserDAO {

	@Override
	public void add() {
		System.out.println("用户增加");
	}

	@Override
	public void delete() {
	}

	@Override
	public void update() {
	}

	@Override
	public void find() {
	}

}

但是,老子现在想要用户增加和用户修改的功能,这个你就郁闷了,又要修改代码,是不是很烦,没办法,顾客就是小白,顾客的需求总是在变化,我们能做的就是以不变应万变。所以,如果采用适配器模式,你想怎么改变需求,可以,老子,就给你创建一个满足你功能的实现类,这样你无话可说了吧。

注意】如果接口中的功能就只要一个,就没有必要使用适配器模式,用了,和没用有区别吗?


五、运用适配器模式解决窗口关闭的多余代码

技术分享

技术分享

技术分享技术分享

package cn5;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
/**
 * 事件监听机制
 * 		事件源:事件发生的地方。
 * 		事件:就是要发生的事情。
 * 		事件处理:就是针对发生的事情做出的处理方案。
 * 		事件监听:就是把事件源和事件关联起来。
 * 
 * 举例:人受伤事件
 * 		事件源:人(具体的对象)
 * 			Person p1 = new Person("张三");
 * 			Person p2 = new Person("李四");
 * 		事件:受伤
 * 			interface 受伤接口{
 * 				一拳();
 * 				一脚();
 * 				一板砖();
 * 			}
 * 		事件处理:
 * 			事件处理类 implements 受伤接口{
 * 				一拳(){
 * 					System.out.println("鼻子流血了,去医院");
 * 				}
 * 				一脚(){
 * 					System.out.println("晕倒了");
 * 				}
 * 				一板砖(){
 * 					System.out.println("头破血流");
 * 				}
 * 			}
 *		事件监听:
 *			p1.注册监听(受伤接口)
 *			p2.注册监听(受伤接口)
 */
public class AWTDemo3 {
	public static void main(String[] args) {
		//创建一个最初不可见的窗体对象
		Frame f = new Frame("窗体关闭");
		//设置窗体属性
		f.setBounds(400, 200, 400, 300);
		
		//让窗体关闭
		//事件源:窗体f
		//事件:对窗体的处理
		//事件处理:关闭窗体(System.exit(0))
		//事件监听:
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		//使得窗体可见
		f.setVisible(true);
		
	}

}


六、把按钮添加到窗体,并添加点击事件

package cn7;

import java.awt.Button;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * 需求:把按钮添加到窗体,并对按钮添加一个点击事件
 * 		1.创建窗体对象
 *      2.创建按钮对象
 *      3.把按钮添加到窗体
 *      4.窗体显示
 *
 */
public class AWTDemo {
	public static void main(String[] args) {
		//创建窗体对象
		Frame f = new Frame("把按钮添加到窗体,并对按钮添加一个点击事件");
		//设置窗体属性
		f.setBounds(400, 200, 400, 300);
		//创建按钮对象
		Button button = new Button("我是按钮");
		button.setSize(20,10);
		//把按钮添加到窗体
		f.add(button);
		//设置窗体可以关闭
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		//窗体显示
		f.setVisible(true);
	}
}

技术分享

丑的我都吃不下饭了,哪有按钮这么大的,而且我设置了按钮的大小了,但是怎么不起作用呢?

技术分享

package cn7;

import java.awt.Button;
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;

/**
 * 需求:把按钮添加到窗体,并对按钮添加一个点击事件
 * 		1.创建窗体对象
 *      2.创建按钮对象
 *      3.把按钮添加到窗体
 *      4.窗体显示
 *
 */
public class AWTDemo {
	public static void main(String[] args) {
		//创建窗体对象
		Frame f = new Frame("把按钮添加到窗体,并对按钮添加一个点击事件");
		//设置窗体属性
		f.setBounds(400, 200, 400, 300);
		//创建按钮对象
		Button button = new Button("我是按钮");
		//设置点击事件
		button.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				System.out.println("你再看试试");
			}
		});
		//Frame的布局默认是边界布局,现在修改为流式布局
		f.setLayout(new FlowLayout());
		//把按钮添加到窗体
		f.add(button);
		//设置窗体可以关闭
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		//窗体显示
		f.setVisible(true);
	}
}

技术分享


七、练习

package cn8;

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

public class AWTDemo {
	public static void main(String[] args) {
		//创建窗体对象
		Frame f = new Frame("数据转移");
		//设置窗体属性
		f.setBounds(400, 200, 400, 300);
		//设置窗体布局
		f.setLayout(new FlowLayout());
		
		//创建文本框
		final TextField tf = new TextField(20);
		//创建按钮
		Button bt = new Button("数据转移");
		//创建文本域
		final TextArea tx = new TextArea(10,40);
		
		//把组件添加到窗体
		f.add(tf);
		f.add(bt);
		f.add(tx);
		
		//设置关闭事件
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		
		//对按钮添加事件
		bt.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				//获取文本框的值
				String tf_str = tf.getText().trim();
				//清空数据
				tf.setText("");
				//设置给文本库并换行
				tx.append(tf_str+"\r\n");
				//文本框获取光标
				tf.requestFocus();
			}
		});
		//让窗体显示
		f.setVisible(true);
	}

}

技术分享

package cn9;
/**
*鼠标点击事件
*/
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 AWTDemo {
	public static void main(String[] args) {
		final Frame f = new Frame("更改背景色");
		f.setBounds(400, 200, 400, 300);
		f.setLayout(new FlowLayout());
		
		//创建按钮
		Button bt1 = new Button("红色");
		Button bt2 = new Button("黑色");
		Button bt3 = new Button("绿色");
		Button bt4 = new Button("黄色");
		
		//添加按钮
		f.add(bt1);
		f.add(bt2);
		f.add(bt3);
		f.add(bt4);
		
		
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		bt1.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				f.setBackground(Color.RED);
			}
		});
		bt2.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				f.setBackground(Color.BLACK);
			}
		});
		bt3.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				f.setBackground(Color.GREEN);
			}
		});
		bt4.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				f.setBackground(Color.YELLOW);
			}
		});
		f.setVisible(true);
	}
}

技术分享

package cn9;

import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * 鼠标移动事件
 */
public class AWTDemo {
	public static void main(String[] args) {
		final Frame f = new Frame("更改背景色");
		f.setBounds(400, 200, 400, 300);
		f.setLayout(new FlowLayout());
		
		//创建按钮
		Button bt1 = new Button("红色");
		Button bt2 = new Button("黑色");
		Button bt3 = new Button("绿色");
		Button bt4 = new Button("黄色");
		
		//添加按钮
		f.add(bt1);
		f.add(bt2);
		f.add(bt3);
		f.add(bt4);
		
		
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		bt1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				f.setBackground(Color.RED);
			}
		});
		bt2.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				f.setBackground(Color.BLACK);
			}
		});
		bt3.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				f.setBackground(Color.GREEN);
			}
		});
		bt4.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				f.setBackground(Color.YELLOW);
			}
		});
		f.setVisible(true);
	}
}

技术分享

package cn10;

import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class AWTDemo {
	public static void main(String[] args) {
		Frame f = new Frame("QQ校验");
		f.setBounds(400, 200, 400, 300);
		f.setLayout(new FlowLayout());
		
		Label l = new Label("请输入你的QQ号码,不能是非数字");
		TextField tf = new TextField(30);
		f.add(l);
		f.add(tf);
		
		tf.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				char c = e.getKeyChar();
				if(!(c >= ‘0‘ && c <=‘9‘)){
					e.consume();
				}
			}
		});
		
		
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		f.setVisible(true);
	}

}


八、菜单组件

技术分享

菜单组件概述

MenuBar,Menu,MenuItem

先创建菜单条,再创建菜单,每一个菜单中建立菜单项。

也可以菜单添加到菜单中,作为子菜单。

通过setMenuBar()方法,将菜单添加到Frame中。

package cn11;

import java.awt.Frame;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
 * 一级菜单
 */
public class Demo {
	public static void main(String[] args) {
		Frame f = new Frame("一级菜单");
		f.setBounds(400, 200, 400, 300);
		
		//创建菜单栏
		MenuBar bar = new MenuBar();
		//创建菜单
		Menu m = new Menu("文件");
		//创建菜单项
		MenuItem mi = new MenuItem("退出系统");
		
		//设置菜单栏
		f.setMenuBar(bar);
		bar.add(m);
		m.add(mi);
		
		
		mi.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
				
			}
		});
		
		f.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		f.setVisible(true);
		
		
	}

}

技术分享


本文出自 “11831428” 博客,请务必保留此出处http://11841428.blog.51cto.com/11831428/1874458

以上是关于java之GUI的主要内容,如果未能解决你的问题,请参考以下文章

java 24 - 11 GUI之制作登陆注册页面

java之 22天 GUI 图形界面编程

java 24 - 7 GUI之 创建多级菜单窗体

java 24 - 6 GUI之 创建只能输入数字的文本框

JAVA之AOP

Java语言基础之方法的设计