黑马程序员-GUI(图形用户接口)

来源:互联网 发布:矩阵a的n次方的行列式 编辑:程序博客网 时间:2024/06/04 17:59

-----------android培训java培训、java学习型技术博客、期待与您交流! ------------


一、概念

 

1、计算机和用户交互的形式:GUI和CLI

(1)GUI:Graphical User Interface(图形用户接口)
用图形的方式,来显示计算机操作的界面,这样更方面更直观
(2)CLI:Command line User Interface(命令行用户接口)
就是常见的Dos命令行操作。需要记忆一些常见的命令,操作不直观
例:比如:创建文件夹,或者删除文件夹等

 

2、Awt和Swing

java为GUI提供的对象都存在java.Awt和javax.String两个包中
(1)java.Awt包:Abstract Window Toolkit(抽象窗口工具包),要调用本地系统方法实现功能,属重量级控件。对本地系统的依赖性比较高。
(2)javax.Swing包:在AWT的基础上建立的一套图形界面系统,其中提供了更多的组件,且完全有java实现,增强了移植性,属轻量级控件。

 

二、继承关系图

 

三、常见的布局管理器:



FlowLayout(流式布局管理器)
 |---从左到右的顺序排列。
 |---Panel默认的布局管理器。

BorderLayout(边界布局管理器)
 |---东,南,西,北,中
 |---Frame默认的布局管理器。

GridLayout(网格布局管理器)
 |---规则的矩阵

CardLayout(卡片布局管理器)
 |---选项卡

GridBagLayout(网格包布局管理器)
 |---非规则的矩阵


 

四、创建图形化界面:

Container常用子类:Window Panel(面板, 不能单独存在。)
Window常用子类:Frame Dialog


简单的窗体创建过程:


1、创建frame窗体。
Frame f=new Frame("my awt");//可设置标题,my awt就是标题


2、对窗体进行基本设置。
比如大小,位置,布局。
f.setSize(400, 400);//设置组件的长500,高400
f.setLocation(300, 200);//设置窗口组件的在屏幕的位置长200.高300
f.setLayout(new FlowLayout());//设置布局是流式布局管理,不设置的话,Frame窗体默认是边界布局管理器


3、定义组件。
Button b=new Button("我是一个按钮");//可设置组件名称。如:我是一个按钮

4、将组件通过窗体的add方法添加到窗体中。
f.add(b);
5、让窗体显示,通过setVisible(true)//true显示组件窗体,false不显示组件窗体

代码示例:

import java.awt.*;import java.awt.event.*;class FrameDemo {public static void main(String[] args) {Frame f = new Frame("my awt");f.setSize(500, 400);f.setLocation(300, 200);f.setLayout(new FlowLayout());Button b = new Button("我是一个按钮");f.add(b);f.setVisible(true);}}

 


五、事件监听机制

 

1、事件监听机制组成


(1)事件源(组件)就是awt包或者swing包中的那些图形界面组件
(2)事件(Event)每一个事件源都有自己特有的对应和共性事件
(3)监听器(Listener)将可以触发某一个事件的动作(不止一个动作)都已经封装到了监听器中。

以上三者,在java中都已经定义好了,直接获取其对象来用就可以了。
我们要做的就是对产生的动作进行处理。


(4)事件处理(引发事件后处理方式)

2、流程图

 

3、编程步骤:

(1)确定事件源(容器或组件)
(2)通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上。
(3)该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
(4)一般用匿名内部类来表示。
(5)在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。
(6)事件触发后会把事件打包成对象传递给该变量。(其中包括:事件源对象。通过getSource()或者,getComponent()获取。)

 

4、代码示例:

import java.awt.*;import java.awt.event.*;class ListenerDemo {public static void main(String[] args) {Frame f = new Frame("我的窗体"); // 创建窗体Button b = new Button("按钮"); // 构造按钮f.setSize(500, 300); // 设置窗口大小f.setLocation(300, 150); // 设置打开时显示的位置f.setLayout(new FlowLayout()); // 设置布局管理f.add(b); // 添加按钮到窗体中f.setVisible(true); // 设置显示窗体f.addWindowListener(new MyWin()); // 添加窗体监听器// f.dispose();}}// 窗体监听器class MyWin extends WindowAdapter {// 将 Window 设置为活动 Window 时调用。public void windowActivated(WindowEvent e) {System.out.println("1窗口前置");// System.exit(0);}// 因对窗口调用 dispose 而将其关闭时调用。public void windowClosed(WindowEvent e) {System.out.println("2关闭窗口");// System.exit(0);}// 用户试图从窗口的系统菜单中关闭窗口时调用。public void windowClosing(WindowEvent e) {System.out.println("3从菜单关闭窗口");System.exit(0);}// 当 Window 不再是活动 Window 时调用。public void windowDeactivated(WindowEvent e) {System.out.println("4不是活动窗口");// System.exit(0);}// 窗口从最小化状态变为正常状态时调用。public void windowDeiconified(WindowEvent e) {System.out.println("5取消最小化");// System.exit(0);}// 窗口从正常状态变为最小化状态时调用。public void windowIconified(WindowEvent e) {System.out.println("6窗口最小化");// System.exit(0);}// 窗口首次变为可见时调用。public void windowOpened(WindowEvent e) {System.out.println("7窗口打开");// System.exit(0);}}

 


六、事件(Event)

 

1、Action事件

事件源:按钮
监听器:addActionListener
通过查阅Button的描述,发现按钮支持一个特有的监听器addActionListener

 

代码示例:定义一个窗体,在窗体中添加一个按钮具备关闭该窗体的功能。
(用匿名内部类建立事件监听对象)

import java.awt.*;import java.awt.event.*;class ListenerDemo2 {public static void sop(Object obj) {System.out.println(obj);}public static void main(String[] args) {new ListenerDemo2();}private Frame f; // 创建窗体的引用private Button but; // 创建按钮的引用ListenerDemo2() {init();} // 构造函数// 初始化组件public void init() {f = new Frame("我的窗体"); // 创建窗体f.setBounds(300, 100, 600, 500); // 设置距左距上 宽高f.setLayout(new FlowLayout()); // 设置布局管理器f.setVisible(true); // 显示窗体but = new Button("退出"); // 创建组件的引用f.add(but); // 将组件添加进窗体myEvent(); // 加载窗体上的事件}// 监听事件private void myEvent() {// 添加窗口监听器,返回窗口事件f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {sop("点击窗体菜单关闭窗口");System.exit(0);}});// 添加按钮活动监听器,返回按动作事件but.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {sop("点击退出按钮关闭窗口");System.exit(0);}});}}

 

2、鼠标事件

java.awt.event
类 MouseEvent

指示组件中发生鼠标动作的事件。

当且仅当动作发生时鼠标光标处于特定组件边界未被遮掩的部分上,才认为在该组件上发
生了鼠标动作。对于轻量级组件,比如 Swing 的组件,当在某个组件上启用某个鼠标事件
类型之后,此类鼠标事件仅被指派给该组件。

对于以下动作,组件对象将生成此低级别事件:

鼠标事件:
 按下鼠标按键
 释放鼠标按键
 单击鼠标按键(按下并释放)
 鼠标光标进入组件几何形状的未遮掩部分
 鼠标光标离开组件几何形状的未遮掩部分
鼠标移动事件:
 移动鼠标
 拖动鼠标

本实例中:

addMouseListener() 添加鼠标监听器
addActionListener() 添加活动监听器
addWindowListener() 添加窗口监听器

ActionEvent 活动事件
actionPerformed 活动执行
System.exit(0) 退出程序

MouseAdapter 鼠标适配器

mouseEntered(MouseEvent e) 鼠标移进组件
mouseExited(MouseEvent e) 鼠标移出组件
mousePressed(MouseEvent e) 鼠标按下按钮
mouseReleased(MouseEvent e) 鼠标释放按钮

本实例中:
e.getButton()==1 左键
e.getButton()==2 中键
e.getButton()==3 右键
e.getClickCount()==1 单击
e.getClickCount()==2 双击

本实例实现了许多鼠标事件,但是双击一次同时也出现了单击的问题并没有解决

 

import java.awt.*;import java.awt.event.*;class MouseEventDemo {public static void sop(Object obj) {System.out.println(obj);}public static void main(String[] args) {new MouseEventDemo();}private Frame f; // 创建窗体的引用private Button but; // 创建按钮的引用MouseEventDemo() {init();} // 构造函数public void init() {f = new Frame("我的窗体"); // 创建窗体f.setBounds(300, 200, 600, 500); // 设置距左距上和宽高值f.setLayout(new FlowLayout()); // 设置布局管理器f.setVisible(true); // 显示窗体but = new Button("退出"); // 创建按钮f.add(but); // 将组件添加进窗体myEvent(); // 加载窗体上的事件}// 窗体事件private void myEvent() {// 添加窗口监听器,返回窗口事件f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {sop("点击窗体菜单关闭窗口");System.exit(1);}});// 添加按钮活动监听器,返回活动事件but.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {sop("活动事件");}});// 添加鼠标监听器,返回鼠标各种动作事件but.addMouseListener(new MouseAdapter() {private int count1 = 1;public void mouseEntered(MouseEvent e) {sop("鼠标移进按钮" + count1++ + "次");}private int count2 = 1;public void mouseExited(MouseEvent e) {sop("鼠标移出按钮" + count2++ + "次");}private int count3 = 1;public void mousePressed(MouseEvent e) {sop("鼠标按下按钮" + count3++ + "次");}private int count4 = 1;public void mouseReleased(MouseEvent e) {sop("鼠标释放按钮" + count4++ + "次");}// 单击与双击。问题?双击一次就有一次单击,怎么解决?public void mouseClicked(MouseEvent e) {// 双击if (e.getClickCount() == 2) {if (e.getButton() == 1)sop("双击左键");if (e.getButton() == 2)sop("双击中键");if (e.getButton() == 3)sop("双击右键");}// 单击else {if (e.getButton() == 1)sop("单击左键");if (e.getButton() == 2)sop("单击中键");if (e.getButton() == 3)sop("单击右键");}}});}}

 

3、键盘事件

java.awt.event
类 KeyEvent

表示组件中发生键击的事件。

当按下、释放或键入某个键时,组件对象(如文本字段)将生成此低级别事件。该事件被
传递给每一个 KeyListener 或 KeyAdapter 对象,这些对象使用组件的 addKeyListener
方法注册,以接收此类事件。(KeyAdapter 对象实现 KeyListener 接口。)发生事件时,
所有此类侦听器对象都将获得此 KeyEvent。

按下和释放键盘上的键会导致(依次)生成以下键事件:
    KEY_PRESSED
    KEY_TYPED(只在可生成有效 Unicode 字符时产生。)
    KEY_RELEASED

方法:
 char getKeyChar()
  返回与此事件中的键关联的字符。
 int getKeyCode()
  返回与此事件中的键关联的整数 keyCode。
 int getKeyLocation()
  返回产生此按键事件的键位置。
static String getKeyModifiersText(int modifiers)
  返回描述修改键的 String,如 "Shift" 或 "Ctrl+Shift"。
static String getKeyText(int keyCode)
  返回描述 keyCode 的 String,如 "HOME"、"F1" 或 "A"。
 boolean isActionKey()
  返回此事件中的键是否为“动作”键。
 String paramString()
  返回标识此事件的参数字符串。
 void setKeyChar(char keyChar)
  设置 keyCode 值,以表示某个逻辑字符。
 void setKeyCode(int keyCode)
  设置 keyCode 值,以表示某个物理键。

继承的方法:
从类 java.awt.event.InputEvent 继承的方法
 consume, getModifiers, getModifiersEx, getModifiersExText, getWhen, isAltDown,
 isAltGraphDown, isConsumed, isControlDown, isMetaDown, isShiftDown

从类 java.awt.event.ComponentEvent 继承的方法
 getComponent()返回事件的始发者。

从类 java.awt.AWTEvent 继承的方法
 getID()返回事件类型。
 setSource(Object newSource)将事件的目标更改为新的源。
 toString()返回此对象的字符串表示形式。

从类 java.util.EventObject 继承的方法
 getSource() 最初发生 Event 的对象。

从类 java.lang.Object 继承的方法
 clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

本例:
consume() 使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理此事件。
TextField(20) 创建文本框,可指定文本框列数为20

 

代码示例:输入数字检验及按组合键退出窗体

import java.awt.*;import java.awt.event.*;class KeyEventDemo {public static void sop(Object obj) {System.out.println(obj);}public static void main(String[] args) {new KeyEventDemo();}private Frame f;private Button but;private TextField tf;// 创建TextField对象引用KeyEventDemo() {init();}// 初始化图形界面public void init() {f = new Frame("我的窗体");f.setBounds(300, 200, 600, 500);f.setLayout(new FlowLayout());f.setVisible(true);tf = new TextField(20); // 创建文本框,指定列数f.add(tf);but = new Button("退出"); // 创建按钮f.add(but);myEvent();}// 监听器private void myEvent() {f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {sop("点击窗体菜单关闭窗口");System.exit(0);}});// 添加按钮活动监听器,返回活动事件but.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.exit(0);}});// 判断输入的是否是0到9数字tf.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {int code = e.getKeyCode(); // 获取输入的codeint num1 = KeyEvent.VK_0;int num2 = KeyEvent.VK_9;if (!(code >= num1 && code <= num2)) { // 如果不是0-9e.consume(); // 停止键盘动作sop("只能输入数字0-9");}}});// 添加键盘监听器,返回键盘事件tf.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {sop(e.paramString()); // 返回标识此事件的参数字符串。sop(e.isActionKey()); // 返回此事件中的键是否为“动作”键。sop(e.getKeyLocation()); // 返回产生此按键事件的键位置。sop(e.getKeyChar()); // 返回与此事件中的键关联的字符。sop(e.getKeyCode()); // 返回与此事件中的键关联的整数 keyCode。sop(KeyEvent.getKeyText(e.getKeyCode()));// 当按下Eso键退出程序String k = KeyEvent.getKeyText(KeyEvent.VK_ESCAPE); // k=Escsop("按" + k + "退出程序");if (e.getKeyCode() == 27)System.exit(0);// 当按下Ctrl+Enter的组合键就退出程序。isControlDown()判断是否被按下sop("按Ctrl+Enter退出程序");if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER)System.exit(0);}});}}


 

练习:


利用图形化界面遍历指定目录下的文件和文件夹

做一个界面,界面顶端一行左边是一个文本框,右边是一个按钮,下边是文本域。
在文本框里输入目录,点击按钮,在文本域中显示该目录下的所有文件。
setEnabled(true/false) 设置是否可以操作组件

import java.io.*;import java.awt.*;import java.awt.event.*;class MyWindow {public static void sop(Object obj) {System.out.println(obj);}public static void main(String[] args) {new MyWindow();}MyWindow() {init();}private Frame f;private Button fb;private TextField tf;private TextArea ta;private Dialog d;private Button db;private Label dl;private String path1;private String path2; // 最后一次有效的pathprivate int position; // 输入点位置// 窗体public void init() {// 创建组件f = new Frame("扫描文件"); // 主窗体(名称)tf = new TextField(57); // 文本框(列数)ta = new TextArea(25, 81); // 文本域(行数,列数)fb = new Button(" 遍 历 "); // 按钮(文字)d = new Dialog(f, "提示!", true); // 提示框dl = new Label(); // 提示框标签db = new Button("确定"); // 提示框确定f.add(new Label("请输入路径:"));f.add(tf);f.add(fb);f.add(ta);d.add(dl);d.add(db);// 设置主窗体属性f.setVisible(true); // 显示窗体f.setBounds(500, 300, 600, 460); // 左上角位置和宽高f.setLayout(new FlowLayout()); // 布局模式f.setResizable(false); // 调整大小// 设置提示框属性d.setBounds(600, 400, 200, 100); // 设置窗口左上角和宽高d.setResizable(false); // 禁止调整窗体大小d.setLayout(new FlowLayout()); // 设置布局模式d.setSize(300, 150); // 设置对话框宽高d.setLocation(650, 450); // 重新设置对话框左上角,相对于屏幕d.setTitle("提示信息!"); // 重新设置标题d.setResizable(false); // 是否可以调整大小myEvent();}// 监听器private void myEvent() {// 主窗体监听器f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});// 主窗体按钮监听器fb.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {butAction();d.setVisible(false);}});// 提示对话框窗体监听器d.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {d.setVisible(false);}});// 提示对话框按钮监听器db.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {d.setVisible(false);tf.requestFocus();// 获取焦点}});// 键盘监听器tf.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {if (e.getKeyCode() == KeyEvent.VK_ENTER)butAction();d.setVisible(false);}});}// 提交按钮事件public void butAction() {path1 = tf.getText();position = tf.getCaretPosition(); // 返回文本插入符的位置。sop(position);if (path1 != "") {File path = new File(path1);if (path.exists() && path.isDirectory()) {ta.setText(""); // 先清空文本域的内容path2 = path.toString();tf.requestFocus(); // 文本框获取焦点// tf.setCaretPosition(position); //文本框焦点位置String[] names = path.list();for (String name : names) {ta.append(name + "\r\n"); // 添加数据到文本域}} else {tf.setText(path2); // 如果路径无效,就设置文本框的内容为最后一次正确输入的路径tf.setCaretPosition(position); // 设置文本插入符的位置。// tf.selectAll(); //选择此文本组件中的所有文本。String d_Info = "你输入的“" + path + "”不是有效路径!";dl.setText(d_Info);d.setVisible(true);}}}}


 

七、对话框Dialog


Dialog 是一个带标题和边界的顶层窗口,出现错误操作时,调用Dialog对象来完成错误信息提示对话框。

 

代码示例:

import java.awt.*;import java.awt.event.*;import java.io.File;/* * 列出指定目录的内容 */public class MyDialog {private Frame f;private TextField tf;private Button btn;private TextArea ta;private Dialog d;private Label lbl;private Button okbtn;public MyDialog() {init();}public void init() {f = new Frame("my window");f.setBounds(300, 100, 600, 600);f.setLayout(new FlowLayout());tf = new TextField(30);btn = new Button("转到");ta = new TextArea(15, 40);d = new Dialog(f, "提示信息——自己的self", true);// true代表如果不操作对话框,模式操作不了d.setBounds(400, 200, 250, 100);d.setLayout(new FlowLayout());lbl = new Label();okbtn = new Button("确定");d.add(lbl);d.add(okbtn);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) {if (e.getKeyCode() == KeyEvent.VK_ENTER) {show();}}});okbtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubd.setVisible(false);}});d.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {d.setVisible(false);}});f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});btn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubshow();}});}private void show() {String path = tf.getText();File dir = new File(path);if (dir.isDirectory() && dir.exists()) {String[] names = dir.list();ta.setText("");for (String name : names) {ta.append(name + "\r\n");}tf.setText("");} else {String info = "您输入的信息:" + path + "是错误的";lbl.setText(info);d.setVisible(true);}}public static void main(String[] args) {new MyDialog();}}


 

八、菜单

 

1、继承体系:

MenuBar 菜单栏:可以添加菜单和条目
Menu: 菜单,有右三角图标存在,可以添加Menu和MenuItem
MenuItem 条目,无右三角图标存在是最终的菜单项

 

2、步骤:


先创建菜单栏,再创建菜单,每一个菜单中建立菜单条目
也可以菜单添加到菜单中,作为子菜单。
通过setMenuBar()方法,将菜单栏添加到Frame中。

 

3、代码示例:完成一个菜单窗口的创建。

import java.awt.*;import java.awt.event.*;class MyMenuDemo {private Frame f;private MenuBar mb;private Menu m, subMenu;private MenuItem closeItem, subItem;MyMenuDemo() {init();}// 构造函数public void init() {f = new Frame("my window");f.setBounds(300, 100, 500, 600);f.setLayout(new FlowLayout());// 流式布局mb = new MenuBar();// 菜单栏初始化m = new Menu("文件");// 菜单初始化subMenu = new Menu("子菜单");// 子菜单初始化subItem = new MenuItem("子条目");closeItem = new MenuItem("退出");subMenu.add(subItem);m.add(subMenu);m.add(closeItem);// 菜单添加菜单项mb.add(m);// 菜单栏添加菜单f.setMenuBar(mb);// 菜单栏设置进窗口myEvent();// 调用监听事件f.setVisible(true);// 设置窗口可见}private void myEvent() {closeItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.exit(0);}});f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});}public static void main(String[] args) {new MyMenuDemo();}}

 

九、jar包如何才能双击执行?

 

既然是图形化界面,就需要通过图形化界面的形式运行程序,而不是是用Dos命令行执行,那么如何通过双击程序就执行程序呢?这就需要将程序的class文件打包,步骤如下:

1、首先要在java文件中导入一个包,没有则需创建一个包,如package mymenu;

2、生成包:通过编译javac -d c:\myclass MyMenu.java,此时则在c盘下的myclass文件夹下生成了所有的.class文件

3、在此目录下新建一个文件,如1.txt或者其他任意名称任意扩展名的文件都可,然后在其中编辑固定的格式:“Main-Class: mymenu.MenuDemo”,只写引号中的内容。需要需要在冒号后有一个空格,在文件末尾要回车。

4、编译:jar -cvfm my.jar 1.txt mymenu即可。如果想添加其他信息,则直接编译jar即可得出相应的命令

5、此时双击即可执行。


说明:

1)在固定格式中:

a.如果无空格:在编译的时候,就会报IO异常,提示无效的头字段,即invalid header field。这说明1.txt在被IO流读取。

b.如果无回车:在列表清单.MF中不会加入相应的加载主类的信息,也就是说配置清单的属性主类名称不会加载进清单中,也就不会执行。

2)jar文件必须在系统中注册,才能运行。注册方法如下:

A.对于XP系统:

   a.打开任意对话框,在菜单栏点击工具按钮,选择文件夹选项

   b.选择新建--->扩展名,将扩展名设置为jar,确定

   c.选择高级,可更改图标,然后点击新建,命名为open,

   d.在用于可执行应用程序中,点浏览,将jdk下的bin的整个文件路径添加进来,并在路径后添加-jar即可。

B.对于win7系统:

   a.改变打开方式:右击.jar文件,点击打开方式,选择默认程序为jdk下bin中的javaw.exe应用程序。

   b.修改关联程序的注册表:打开注册表(win+r),找到注册表路径\HKEY_CLASSES_ROOT\Aplications\javaw.exe\shell\open\command下的字符串值,右击点修改,将值改为:"C:\Program Files\Java\jre6\bin\javaw.exe" -jar "%1"其中-jar前的路径就是javaw.exe的路径。保存

   c.双击即可执行jar程序,如果仍不能执行,则需下载最新版的jdk。

 


 

原创粉丝点击