------- android培训、java培训、期待与您交流! ----------
————————————————————————————————————————————
java之图形化界面(GUI)
概述
用户与计算机进行交换的方式有两种:
GLI:Command lin User Interface(命令行用户接口),也就是常见的dos窗口,它需要记住一些常用的命令,操作不直观方便。
GUI:Graphical User Interface(图形用户接口),用图形的方式,来显示计算机操作的界面,这样更方便直观。
这两种交换方式就对应两种交互界面:命令行界面和图形化界面。
现在图形化界面是主流。
Java为GUI提供的对象都在java.awt和javax.swing这两个包中。
Awt和Swing
java.awt:bstractWindow ToolKit(抽象窗口工具集,需要调用本地系统方法实现功能,属于重量级控件。
java.swing:在AWT的基础上,建立的一套图形界面系统,其中提供更多的组件,而且完全由java实现,增强了移植性,属于轻量级控件。
小知识点:这里的“重量级”是指跟平台结合紧密,轻量级与之相反。
AWT继承关系图
Frame
Frame是windows的子类,它启动时,要通过setVisiable(true)方法来启动窗口。
GUI中,启动一个窗体就是启动一个前台线程,虽然main函数运行完了,但前台线程没结束,所以程序也就不会结束。
窗口的布局管理器
容器中的组件的排放方式,就是布局。
常见的布局管理器:•
FlowLayout(流式布局管理器):从左到右的顺序排列。Panel默认的布局管理器。
BorderLayout(边界布局管理器):东,南,西,北,中。Frame默认的布局管理器。
GridLayout(网格布局管理器):规则的矩阵。
CardLayout(卡片布局管理器):选项卡。
GridBagLayout(网格包布局管理器):非规则的矩阵。
事件监听机制
事件监听机制由四部分组成:事件源(组件)、事件(Event)、监听器(Listener)和事件处理(引发事件后的处理方式)。
1.事件源:就是java.awt和javax.swing包中的GUI组件。
2.事件:每个事件源都有自己的特有事件和共性事件(鼠标事件和键盘事件即是它们的共性事件)。
3.监听器:将可以触发某一事件的动作(不止一个)都封装在了监听器中。
4.事件处理:事件源、事件和监听器在java中已经定义好了,直接获取其对象来用就可以了,我们要做的是对产生的动作进行处理。
窗体事件
WindowEvent事件对于的是WindowListener,事件对象作为参数,传入监听器的处理事件方法中。
WindowListener,是一个接口,对应的Window组件体系。查看该接口发现它有7个方法需要实现,这起个方法对应7个动作。如果我仅对其中的1个动作进行处理,却需要同时复写其他的6个方法,这样不方便与编程,所以java提供了一个WindowListener的抽象子类WindowAdapter。WindowAdapter虽然是抽象的,但没有抽象方法,它定义为抽象,是为不能直接建立对象,而让你去继承,复写你要想处理的动作方法。编程中,对事件监听器用匿名内部类的比较多。
当监听器接口的方法多于3个时,一般该监听器接口都用相应的Adapter(适配器)。
代码示例:
- /*
- 创建图形化界面步骤:
- 1.创建fram窗体。
- 2.对窗体进行基本设置。
- 比如大小,位置,布局。
- 3.定义组件。
- 4.将组件通过窗体的add方法添加到窗体中
- 5.让窗体显示,通过setVisible(true)方法。
- */
- import java.awt.*;
- import java.awt.event.*;
- class AwtDemo
- {
- public static void main(String[] args)
- {
- Frame f =new Frame("my awt");
- f.setSize(500,400);//设置窗体大小500是宽,400是高
- f.setLocation(300,200);//设置初始显示位置,300是x坐标,200是y坐标
- // 上边两个方法可以用它 f.setBounds(x, y, width, height)来统一设置
- 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);//这个方法的 关闭的是虚拟机,退出虚拟机,当然就退出了程序
- }
- public void windowActivated(WindowEvent e)
- {
- System.out.println("我活动的");
- }
- public void windowOpened(WindowEvent e)
- {
- System.out.println("我被打开了");
- }
- });
- //设置frame显示,这时图形界面线程才启动
- f.setVisible(true);
- }
- }
- class MyWin extends WindowAdapter
- {
- public void windowClosing(WindowEvent e)
- {
- System.exit(0);
- //System.out.println("MyWin------------"+e.toString());
- }
- }
Action事件
按钮对应的是ActionEvent事件,ActionEvent对应的是ActionListener监听器。
只用按钮活动,就能执行,而键盘和鼠标都能让按钮活动。所以,如果对按钮处理的动作只有一种,最好使用ActionListener,因为鼠标键盘都会触发它。
ActionListener监听器接口只用一个方法,所以没有相应的Adapter,它是三个没有配适器的监听器接口之一。
代码示例:
- import java.awt.*;
- import java.awt.event.*;
- class FrameDemo
- {
- //定义该图形中所需的组件的引用。
- private Frame f;
- private Button but;
- FrameDemo()
- {
- init();
- }
- //初始化图形界面
- public void init()//初始化
- {
- f= new Frame("day22-MyFrame");
- //对frame进行基本设置。
- f.setBounds(300,100,600,500);
- f.setLayout(new FlowLayout());
- but = new Button("my button");
- //将组件添加到Frame中
- f.add(but);
- //加载一下窗体上的事件。
- myEvent();
- //显示窗体
- f.setVisible(true);
- }
- //最好把事件处理和GUI组件的基本初始化分离开
- public void myEvent()//这些都是组件的特有事件,还有共性事件。
- {
- f.addWindowListener(new WindowAdapter()
- {
- public void windowClosing(WindowEvent e)
- {
- System.out.println("关闭窗口");
- System.exit(0);//这个方法的 关闭的是虚拟机,退出虚拟机,当然就退出了程序
- }
- });
- //让按钮具备退出程序的功能。
- /*
- 按钮就是事件源,那么选择哪一个监听器呢?通过关闭窗体实例了解到。想要知道那个组件具备什么样的特与监听器,
- 需要查看该组件对象的功能。那么通过查阅button的描述,发现支持一个特有监听addActionListener(ActionListener l);
- 是没有适配器的少数组件之一,只要事件方法超过3个的组件,都有配适器(Adapter);
- */
- but.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- System.out.println("退出,按钮干的");
- System.exit(0);
- }
- });
- }
- //主函数,用于测试
- public static void main(String[] args)
- {
- new FrameDemo();
- }
- }
鼠标事件
MouseEvent,它是所有组件都有的共性事件,所以它的添加监听器方法是定义在Component抽象类中,键盘事件也是共性事件。
它对应的是MouseListener。
鼠标单击次数是定义在MouseEvent事件对象中的,在MouseEvent事件对象中还能还封装了触发事件的是鼠标的一些相关信息。
MouseListener有对应的MouseAdapter。
键盘事件
KeyEvent事件对象,内部封装了对应于键盘各个键的字段和触发事件的具体按键的信息。
这些信息可以通过该对象对外提供的方法获取到。
keyEvent 对应的事件监听器的KeyListener·,有对应的KeyAdapter。
代码示例:
- import java.awt.*;
- import java.awt.event.*;
- class MouseAndKeyEvent
- {
- //定义该图形中所需的组件的引用。
- private Frame f;
- private Button but;
- private TextField tf;
- MouseAndKeyEvent()
- {
- init();
- }
- public void init()//初始化
- {
- f= new Frame("day22-MyFrame");
- //对frame进行基本设置。
- f.setBounds(300,100,600,500);
- f.setLayout(new FlowLayout());
- but = new Button("my button");
- tf = new TextField(10);
- f.add(but);
- f.add(tf);
- myEvent();
- f.setVisible(true);
- }
- public void myEvent()
- {
- f.addWindowListener(new WindowAdapter()
- {
- public void windowClosing(WindowEvent e)
- {
- System.exit(0);
- }
- });
- //给but添加一个键盘侦听器
- but.addKeyListener(new KeyAdapter()
- {
- private int count;
- public void keyPressed(KeyEvent e)
- {
- //判断组合键
- if(e.isControlDown() && e.getKeyCode()==KeyEvent.VK_ENTER)//从父类InputEvent 找isControlDown
- //System.exit(0);
- System.out.println("Ctrl + Enter is down");
- //System.out.println("按下某个键了---"+count++);
- //System.out.println(e.getKeyChar());
- //打印按下的键上在字符串,及键值。
- System.out.println(KeyEvent.getKeyText(e.getKeyCode())+"....."+e.getKeyCode());
- }
- });
- tf.addKeyListener(new KeyAdapter()
- {
- public void keyPressed(KeyEvent e)
- {
- //限定键值的范围
- int code =e.getKeyCode();
- if(!(code>=KeyEvent.VK_0 && code<=KeyEvent.VK_9))
- {
- //不处理,取消掉事件,具有屏蔽键的作用,如果键入是字符非法则不写入文本框。
- e.consume();//从父类InputEvent中获取的方法consume,不按照默认的方法处理该事件。
- System.out.println(code + "....是非法的");
- }
- }
- });
- /*
- //给but添加监听器
- but.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- System.out.println("button action");
- }
- });
- //给but添加鼠标监听器
- but.addMouseListener(new MouseAdapter()
- {
- private int count;
- private int clickCount;
- public void mouseEntered(MouseEvent e)
- {
- System.out.println("鼠标进入组件区域啦--"+count++);
- }
- public void mouseClicked(MouseEvent e)
- {
- if(e.getClickCount()==2)
- System.out.println("鼠标双击Button了--"+clickCount++);
- }
- });
- */
- }
- public static void main(String[] args)
- {
- new MouseAndKeyEvent();
- }
- }
对话框
Dialog在构造时,可以设置模式,如果为true那么,在该对话框关闭前,程序的其他窗口都不能被操作。
其体系如下:
|----Dialog
|----FileDialog文件对话框,可以从中选择文件。
|----JDialog
模拟系统文件目录浏览器
- import java.awt.*;
- import java.awt.event.*;
- import java.io.*;
- class MyWindowDemo
- {
- private Frame f;
- private TextField tf;
- private Button but;
- private TextArea ta;
- private Dialog d;
- private Label lab;
- private Button okBut;
- MyWindowDemo()
- {
- init();
- }
- public void init()
- {
- f = new Frame("My Window");
- f.setBounds(300,100,500,400);
- f.setLayout(new FlowLayout());
- tf = new TextField(40);
- but = new Button("转到");
- ta = new TextArea(20,50);
- d = new Dialog(f,"提示信息-self",true);
- d.setBounds(400,200,240,100);
- d.setLayout(new FlowLayout());
- lab =new Label();
- okBut=new Button("确定");
- d.add(lab);
- d.add(okBut);
- f.add(tf);
- f.add(but);
- f.add(ta);
- myEvent();
- f.setVisible(true);
- }
- public void myEvent()
- {
- //添加按钮活动事件监听器
- but.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- showDir();
- }
- });
- //添加tf的键盘监听器
- tf.addKeyListener(new KeyAdapter()
- {
- public void keyPressed(KeyEvent e)//用keyTyped事件不成功
- {
- if(e.getKeyCode()==KeyEvent.VK_ENTER)
- {
- showDir();
- }
- }
- });
- //添加确定按钮活动监听器,鼠标和键盘都能触发。
- okBut.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- d.setVisible(false);
- }
- });
- //添加对话框监听器
- d.addWindowListener(new WindowAdapter()
- {
- public void windowClosing(WindowEvent e)
- {
- d.setVisible(false);
- }
- });
- //添加Frame监听器
- f.addWindowListener(new WindowAdapter()
- {
- public void windowClosing(WindowEvent e)
- {
- System.exit(0);
- }
- });
- }
- //将展示目录内容的功能封装起来,以方便使用
- private void showDir()
- {
- //获取文本框内容,并封装成File 对象
- String dirPath = tf.getText();
- File dir = new File(dirPath);
- //判断File对象是否存并且是否是目录
- if(dir.exists()&&dir.isDirectory())
- {
- //清空文本区域内容
- ta.setText("");
- //使用File的list方法列出目录下的文件名字
- String [] names = dir.list();
- for(String name:names)
- {
- //append方法可以说实现对文本区域添加文本
- ta.append(name+"\r\n");
- }
- }
- else//如果不是目录则弹出错误对话框
- {
- //其实这个dialog窗体要在这时创建,以优化内存,将其在初始化时就创建是为了演示。
- String info="您输入的信息("+dirPath+"):是错误的,请重新输入";
- lab.setText(info);
- d.setVisible(true);
- }
- //清空文本框内容
- tf.setText("");
- }
- public static void main(String[] args)
- {
- new MyWindowDemo();
- }
- }
菜单
主要由三个类组成:MenuBar,Menu和MenuItem。
MenuBar:菜单条,里边只能添加Menu。
Menu:可以添加MenuItem菜单条目,如果这个MenuItem是一个Menu,那么这个Menu是一个子菜单。
MenuItem:菜单条目。
注意:其继承体系如下:
|---MenuComponent
|---- MenuBar
|---- MenuItem
|-----Menu
练习:简单模拟记事本
- import java.awt.*;
- import java.awt.event.*;
- import java.io.*;
- import javax.swing.JDialog;
- public class MyMenuTest
- {
- private Frame f;
- private MenuBar mb;
- private Menu m;
- private MenuItem closeItem,openItem,saveItem;
- private TextArea ta;
- private FileDialog diaOpen,diaSave;
- private File file;
- MyMenuTest()
- {
- init();
- }
- public void init()
- {
- f = new Frame("MyMenuTest");
- f.setBounds(400,300,600,500);
- //f.setLayout(new FlowLayout());//使用默认的边界布局管理器
- //设置菜单
- mb = new MenuBar();
- m = new Menu("文件");
- openItem = new MenuItem("打开");
- saveItem = new MenuItem("保存");
- closeItem= new MenuItem("退出");
- m.add(openItem);
- m.add(saveItem);
- m.add(closeItem);
- mb.add(m);
- //设置文本区域
- ta = new TextArea();
- //建立文件打开和保存对话框
- diaOpen = new FileDialog(f,"打开",FileDialog.LOAD);
- diaSave = new FileDialog(f,"保存",FileDialog.SAVE);
- //将菜单条添加到Frame上。
- f.setMenuBar(mb);
- f.add(ta);
- //添加事件
- myEvent();
- //设置显示
- f.setVisible(true);
- }
- public void myEvent()
- {
- //打开文件
- openItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- //启动文件打开对话框
- diaOpen.setVisible(true);
- //获得选取的文件所在的目录
- String dirPath = diaOpen.getDirectory();
- //获得选取的文件的文件名字,如果没有选取,则返回null(即点击的是取消按钮),这要处理一下
- String fileName = diaOpen.getFile();
- if(dirPath==null && fileName==null)
- return;
- //选取有效文件后,清空文本区域
- ta.setText("");
- //将选取的文件读到文本区域中
- file = new File(dirPath,fileName);
- //对IO异常进行处理,将文件内容加到文本区域中
- try
- {
- BufferedReader bufr = new BufferedReader(new FileReader(file));
- StringBuilder sb = new StringBuilder();
- String line = null;
- while((line=bufr.readLine())!=null)
- {
- sb.append(line+"\r\n");
- }
- ta.append(sb.toString());
- bufr.close();
- }
- catch (IOException ex)
- {
- throw new RuntimeException("读取失败");
- }
- }
- });
- //保存文件
- saveItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- //文件是否存在
- //如果文件不存在,就打开文件保存对话框
- if(file==null)
- {
- diaSave.setVisible(true);
- String dirPath = diaSave.getDirectory();
- String fileName = diaSave.getFile();
- file = new File(dirPath,fileName);
- //防止点击取消按钮产生异常,这时直接返回
- if(dirPath==null && fileName==null)
- return;
- }
- //上边的代码保证了文件肯定存在,然后开始保存数据
- try
- {
- BufferedWriter bufw = new BufferedWriter(new FileWriter(file));
- bufw.write(ta.getText());
- bufw.close();
- }
- catch (IOException ex)
- {
- throw new RuntimeException();
- }
- }
- });
- //通过菜单关闭
- closeItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent e)
- {
- System.exit(0);
- }
- });
- //frame关闭事件处理
- f.addWindowListener(new WindowAdapter()
- {
- public void windowClosing(WindowEvent e)
- {
- System.exit(0);
- }
- });
- }
- public static void main(String[] args)
- {
- new MyMenuTest();
- }
- }
GUI双击jar包执行
写好读到GUI程序,可以封装成jar包,通过对系统进行设置,使得双击jar包后,程序可以执行。以上边的写的记事本程序为例:
操作步骤:
1. 在源文件的第一行加上包:package mymenu
2. dos命令行中启动“javac -d c:\myclassMyMenuTest.java”命令。
3. 在menu包所在目录下,新建一个名为“1.txt”的文本文档,里边录入一下内容:
Main-Class: mymenu.MyMenuTest
注意:1,冒号后面要有一个空格;2,末尾一定要加换行符,即敲一下Enter键。
4. 在在dos切换到c:\myclass目录下,启动”jar –cvfm my.jar 1.txt menu” 命令,这时得到的jar包即可启动。
在此之前要先将jar文件注册的系统中,其过程如下:
xP系统:工具à文件夹选项à文件类型à新建扩展名为jar的文件类型à选中jar,
点击“高级”按钮à更改图标,图标可以任意选;点击”新建”按键à添加open操作,操行名称写完“open”,用于执行操作的程序选择JDK目录下的javaw工具,并在末尾加上–jar参数。
Win7系统:
1、选择默认程序:右击jar包,打开方式->选择默认程序->浏览,选中jre下bin文件中javaw.exe(比如我的javaw.exe在D:\ProgramFiles\Java\jre6\bin下)。
2、编辑注册表:HKEY_CLASSES_ROOT\Applications\javaw.exe\shell\open\command,修改数据数值为"D:\ProgramFiles\Java\jdk1.6.0_21\jre\bin\javaw.exe" -jar "%1"(只要在原来的数值下添加-jar即可)。
错误示例:
jar时出现: invalid header field错误提示,
原因是
Main-Class:mymenu.MyMenuTest
冒号后边少一个空格,改为
Main-Class: mymenu.MyMenuTest
即可。