一、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(); } }
用戶增加
用戶刪除
用戶查詢
用戶修改
我()和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 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); } }