------- android培训、java培训、期待与您交流! ----------
>>Graphical user Interface图形用户接口
相对CLI:Command line user Interface。命令行用户接口
为GUI提供的对象都在
java.Awt:AbstractWindow oolkit(抽象窗口工具包)(需要调用本地系统方法实现功能。即和系统的耦合性很高。属于重量级控件)
和
java.Swing:(在Awt基础上建立的一套图形界面系统,其中提供更多的组件,而且完全由JAVA实现。增强了移植性,属于轻量级控件)
两个包中。
>>继承关系
Component
|--Container:是一个特殊的容器,其中可以使用ADD存放其它组件
|--Window
|--Frame
|--Dialog
|--FileDialog
|--Panel
|--Button
|--Label
|--Checkbox
|--TextComponent
|--TextArea
|--TextField
>>Frame
类 Frame
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
构造方法:
Frame(String title) //构造一个新的、最初不可见的、具有指定标题的 Frame 对象。
eg:演示生成一个窗口,关不掉!
import java.awt.*;
class FrameDemo
{
publicstatic void main(String[] args)
{
Framef = new Frame("My java Frame");//可以传入窗口标题
f.setVisible(true);//让窗口显示
System.out.println("hello!");
}
}
为什么关不掉呢?
hello!都输出了代表主线程结束了。证明awt是一个独立的线程!
eg:更加具体的设置
import java.awt.*;
import java.awt.event.*;
class FrameDemo
{
publicstatic void main(String[] args)
{
Framef = new Frame("my frame");//1,通过frame创建窗体。
//2,对窗体进行简单设置。
f.setSize(500,400);//2.1大小。
f.setLocation(400,100);//2.2设置窗体的屏幕上的位置。
//2.3给窗体设置指定的布局。 窗体默认布局是边界布局:BorderLayout
f.setLayout(newFlowLayout());
//3,给窗体添加一个组件。
Buttonbut = new Button("my button");//创建一个按钮对象。
f.add(but); //4,将组件添加到窗体中。
f.setVisible(true);//让窗体进行显示。
System.out.println("HelloWorld!");
}
}
关于2.3设置布局,有一个专门的接口:
接口LayoutManager
所有已知子接口:LayoutManager2
同时,设置使用的方法为Frame的父类Container的方法:
voidsetLayout(LayoutManager mgr) //设置此容器的布局管理器。
下面,来解决窗体不能关闭的问题,还有按钮起点作用,需要一个监听器。
涉及到事件监听机制,按钮作为事件源(组件),事件(Event),监听器(Listener),事件处理(引发事件后处理方式)。每一个事件的发生,对应的动作可能有很多。将这些动作都与事件源相关联即可。只要有一个动作发生,就引发了对应的事件。
可是多个动作直接和事件源关联,这样不利于应用和扩展。所以,将这些动作进行了封装。封装成了一个对象。让这个对象和事件源关联即可。这个封装后的对象就形象的称为监听器.
监听器和事件源相关联,也就是将监听器注册到了事件源身上.
当有外部动作作用到该事件源上时,监听器会自动判断这个动作,如果该动作符合监听中的某一个动作,
那么这时,监听动作所对应的事件就发生了,该事情会被封装成一个事件对象,并传递给正在发生的这个动作.
该动作其实就是一个函数,这个函数就会执行.并对事件进行处理。
eg:监听器的伪代码举例
人
受伤事件
受伤监听器
{
一拳(受伤事件 x)
一脚()。
一板砖()。
}
因为一拳方法的处理方式不确定,
所以应该由事件的处理者来定义。
需要对一拳这个方法进行覆盖。
class sub受伤监听器
{
一拳(受伤事件 x)
{
System.out.println("疼!。");
}
一脚()
{
System.out.println("晕,熏晕!。");
}
}
人.添加受伤监听(new 受伤监听器());
当真的给了人一拳,该动作就被监听到,而且一拳会引发受伤事件,该事件会封装成一个对象。
这个打包事件对象和传递是自动完成。
eg:演示关于窗口和按钮的监听器
import java.awt.*;
import java.awt.event.*;
class FrameDemo
{
publicstatic void main(String[] args)
{
Framef = new Frame("My java Frame");//给出标题
f.setSize(500,400);//设定窗口大小
f.setLayout(newFlowLayout());//设定窗口布局
System.out.println("hello!");
//匿名内部类直接调用适配器
f.addWindowListener(newWindowAdapter()
{
//打开窗口是显示一条信息到控制台
publicvoid windowOpened(WindowEvent e)
{
System.out.println("opening");
}
});
//调用继承适配器的监听器类
f.addWindowListener(newJianTingQi());
//创建一个按钮
Button button = new Button("震我一下");
f.add(button);//添加按钮到窗口
button.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
System.out.println("关闭");
System.exit(0);
}
});//按钮的动作监听器,其中ActionListener接口只有一个方法
f.setVisible(true);
}
}
/*监听接口中,只要方法没有超过3个,该接口就没有Adapter。
一般都有适配器。只有2,3个没有适配器的。后面会使用到。*/
class JianTingQi extends WindowAdapter
{
/*publicvoid windowOpened(WindowEvent e)
{
System.out.println("opening");
} */
publicvoid windowClosing(WindowEvent e)//这个“e”的机制和catch类似
{
System.out.println("closing");
System.exit(0);
}
}
/*
自己发现:关于windowOpened方法的API定义:
void windowOpened(WindowEvent e)窗口首次变为可见时调用。
即如果将f.setVisible(true);写在了方法调用的前面,这样:
………………
f.setVisible(true);
f.addWindowListener(newJianTingQi());
………………
windowOpened中的信息不会被体现在控制台
*/
>>键盘事件
eg:
演示键盘控制按钮,组合键,文本框限定输入,错误弹窗以及错误弹窗的信息显示和按钮操作等。
import java.awt.*;
import java.awt.event.*;
import java.lang.System.*;
class KeyMouseDemo
{
publicstatic void main(String[] args)
{
AwtDemoat = new AwtDemo();
}
}
class AwtDemo
{
//一般设计中,都把控件和事件封装
privateFrame f;//主窗口
privateButton button;//主窗口按钮“震我一下”
privateTextField tf;//只允许输入数字的文本框
privateDialog d;//错误弹窗
privateLabel lab;//错误提示信息
privateButton okBut;//错误弹窗的“确定”按钮
AwtDemo()
{
init();
}
publicvoid init()
{
//主窗口参数
f= new Frame();
f.setSize(500,400);
f.setLocation(400,100);
f.setLayout(newFlowLayout());
//添加按钮
button= new Button("震我一下");
f.add(button);
//添加文本框
tf= new TextField(10);
f.add(tf);
//错误弹窗参数
//true表示弹出错误信息后锁定主窗口
//false表示弹出错误信息后仍可以操作主窗口
d= new Dialog(f,"错误提示信息",true);
d.setSize(300,200);
d.setLocation(500,100);
d.setLayout(newFlowLayout());
//弹窗的按钮
okBut= new Button("确定");
//弹窗信息
lab= new Label();
d.add(lab);
d.add(okBut);
myEvent();
f.setVisible(true);
}
//监听功能的函数
privatevoid myEvent()
{
//主窗口匿名内部类,“X”关闭功能
f.addWindowListener(newWindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
System.out.println("叉叉关闭主窗口");
System.exit(0);
}
publicvoid windowOpened(WindowEvent e)
{
System.out.println("打开主窗口");
}
});//匿名内部类结束
//主窗口按钮匿名内部类,按钮关闭功能
button.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
System.out.println("按钮关闭主窗口");
System.exit(0);
}
});//匿名内部类结束
//主窗口键盘匿名内部类,组合键关闭功能
button.addKeyListener(newKeyAdapter()
{
publicvoid keyPressed(KeyEvent e)
{
//System.out.println("键盘关闭");
//System.out.println(e.getKeyChar()+":"+e.getKeyCode());//返回按的键
//但是getKeyChar()不能表示诸如Shift这样的键,改进
//System.out.println(e.getKeyText(e.getKeyCode())+":"+e.getKeyCode());
//既然知道了键盘的代码,我们能不能使用组合键呢?
//涉及到类InputEvent的方法
if(e.isControlDown()&& e.getKeyCode() == KeyEvent.VK_ENTER)
{
System.out.println("ctrl+enterrun!");
System.exit(0);
}
}
});//匿名内部类结束
//定义一个文本框,该框中只能输入数字,因为接收是qq号。
tf.addKeyListener(newKeyAdapter()
{
publicvoid keyPressed(KeyEvent e)
{
intcode = e.getKeyCode();
if(!(code>=KeyEvent.VK_0&& code<=KeyEvent.VK_9))
{
//System.out.println("只能是数字,别的不行");
lab.setText("\n"+"只能是数字,"+e.getKeyChar()+"不行!");
d.setVisible(true);
e.consume();
//取消事件的默认处理效果。使得输入的错误信息不留在文本框内
}
}
});//结束
//错误弹窗按钮,关闭功能
okBut.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
System.out.println("按钮关闭弹窗!");
d.setVisible(false);//不使用exit(0),否则主窗口都退出了
}
});//匿名内部类结束
d.addWindowListener(newWindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
System.out.println("叉叉关闭弹窗!");
d.setVisible(false);//让弹窗不可见
}
});
}
}
>>有了键盘监听事件,当然还有鼠标监听
java.awt.event
接口 MouseListener
所有超级接口:
EventListener
所有已知子接口:
MouseInputListener
方法:
void mouseClicked(MouseEvent e) 鼠标按键在组件上单击(按下并释放)时调用。
void mouseEntered(MouseEvent e) 鼠标进入到组件上时调用。
void mouseExited(MouseEvent e) 鼠标离开组件时调用。
void mousePressed(MouseEvent e) 鼠标按键在组件上按下时调用。
void mouseReleased(MouseEvent e) 鼠标按钮在组件上释放时调用。
eg:演示鼠标接触按钮,释放功能,双击效果
………………
//监听功能的函数
private void myEvent()
{
//新玩具,鼠标事件,使用主窗口的按钮
button.addMouseListener(newMouseAdapter()
{
publicvoid mouseEntered(MouseEvent e)
{
System.out.println("鼠标路过");
}
//释放才执行动作
/*publicvoid mousePressed(MouseEvent e)
{
System.out.println("我点!");
}*/
//想双击怎么办?
publicvoid mouseClicked(MouseEvent e)
{
//愿意三击也没问题
if(e.getClickCount()== 2)
System.out.println("鼠标双击");
}
});
………………
>>练习:设计一个程序,输入目录,打印该目录下的文件和文件夹
要求有一个执行按钮,一个输入框,一个输出区域
eg:如果不是目录则弹出提示框
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class MyWindow
{
publicstatic void main(String[] args)
{
Windowsswin = new Windowss();
}
}
class Windowss
{
privateFrame f;
privateButton button;
privateTextField tf;
privateTextArea ta;
//错误提示框组件
privateLabel lab;
privateDialog d;
privateButton okButton;
Windowss()
{
init();
}
publicvoid init()
{
f= new Frame("--myWindow--");
f.setSize(500,600);
f.setLocation(530,200);
f.setLayout(newFlowLayout());
button= new Button("转到");
tf= new TextField(40);
ta= new TextArea(25,60);
f.add(button);
f.add(tf);
f.add(ta);
//错误提示框
d= new Dialog(f,"出错",true);
d.setSize(300,200);
d.setLocation(500,100);
d.setLayout(newFlowLayout());
lab= new Label();
okButton= new Button("确定");
d.add(lab);
d.add(okButton);
myEvent();
f.setVisible(true);
}
privatevoid showDir()//显示目录的方法单独封装
{
ta.setText("");
StringstrDir = tf.getText();
Filefile = new File(strDir);
if(file.exists()&& file.isDirectory())
{
String[]name = file.list();
for(Stringnames:name)
{
ta.append(""+names+"\r\n");
}
}
else
{
//ta.setText("目录错误!");
//改为弹出对话框
lab.setText("目录错误");
d.setVisible(true);
}
}
privatevoid myEvent()
{
f.addWindowListener(newWindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
System.out.println("主窗口关闭!");
System.exit(0);
}
});
//按钮与文本框、文本区域相关联
button.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
showDir();
/*初期试验的简单功能
//获取文本框中的数据
Stringtext = tf.getText();
//将获取的数据输入文本区域
//ta.setText(text);
//连续添加,不会覆盖
ta.append(text+"\r\n");
tf.setText("");
*/
}
});
//避免每次都去点按钮,设定回车输入
tf.addKeyListener(newKeyAdapter()
{
publicvoid keyPressed(KeyEvent e)
{
if(e.getKeyCode()== KeyEvent.VK_ENTER)
{
showDir();
}
}
});
//错误提示关闭方法
okButton.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
d.setVisible(false);
}
});
}
}
>>awt中的菜单(menu)
继承体系:
Menu Component
|--MenuItem菜单项
|--Menu
|--MenuBar菜单栏
eg:演示在窗体添加一个菜单条,其中有文件菜单,文件菜单中有关闭功能
import java.awt.*;
import java.awt.event.*;
class MyMeunDemo
{
publicstatic void main(String[] args)
{
newMenus();
}
}
class Menus
{
privateFrame f;
privateMenuBar mb;
privateMenuItem mi;
privateMenu me;
Menus()
{
init();
}
publicvoid init()
{
f= new Frame("菜单演示");
//Frame父类方法,整合了setSize、setLocation
f.setBounds(400,100,550,500);
mb= new MenuBar();//菜单条
me= new Menu("文件");//菜单条中的菜单项
mi= new MenuItem("关闭");//菜单项中选项
//注意添加关系
mb.add(me);
me.add(mi);
f.setMenuBar(mb);
menuEvent();
f.setVisible(true);
}
privatevoid menuEvent()
{
//窗体关闭
f.addWindowListener(newWindowAdapter()
{
publicvoid windowClosing(WindowEvent e)
{
System.exit(0);
}
});
//关闭选项监听
mi.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
}
}
>>子菜单
eg:在“文件”菜单中添加子菜单
………………
class Menus
{
privateFrame f;
privateMenuBar mb;
privateMenuItem mi,mi2;
privateMenu me,me2;
………………
//在文件菜单添加子菜单
me2= new Menu("子菜单");
mi2= new MenuItem("演示子菜单");
me.add(me2);
me2.add(mi2);
f.setMenuBar(mb);
………………
//这样,在文件菜单下,就有“关闭”和“子菜单”两项,子菜单后有一个箭头,鼠标放上去,出现“演示子菜单”!
>>练习,利用菜单打开文本文件,保存文本
关键类Dialog下有一个类:
java.awt
类 FileDialog
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Dialog
java.awt.FileDialog
FileDialog类显示一个对话框窗口,用户可以从中选择文件。
由于它是一个模式对话框,当应用程序调用其show 方法来显示对话框时,它将阻塞其余应用程序,直到用户选择一个文件。
eg:演示一个简单的文本编辑器,实现打开文件,保存文件,关闭文件功能。
保存文件要做到,如果是新文件,弹窗;如果是打开的文件,不弹窗直接保存!
关闭文件要做到关闭的同时保存好已经编辑的文件!
并且要注意的是,关闭文件实际上是保存后清空textArea!但是这个时候如果再点击保存,上一次打开的文件内容会被清空!要解决这个问题!
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class MenuOpenFileDemo
{
publicstatic void main(String[] args)
{
newOpenFileDemo();
}
}
class OpenFileDemo
{
privateFrame frame;
privateMenuBar mBar;
privateMenu wenJian;
privateMenuItem daKai,baoCun,guanBiFile,guanBi;
privateTextArea textArea;
privateFileDialog fileDia;
privateFile files;
OpenFileDemo()
{
init();
}
publicvoid init()
{
//窗体设置
frame= new Frame("show File");
frame.setBounds(400,100,640,480);
//添加菜单栏
mBar= new MenuBar();
frame.setMenuBar(mBar);
//添加菜单
wenJian= new Menu("文件");
mBar.add(wenJian);
//添加菜单项
daKai= new MenuItem("打开");
baoCun=new MenuItem("保存");
guanBiFile= new MenuItem("关闭文件");
guanBi=new MenuItem("关闭");
wenJian.add(daKai);
wenJian.add(baoCun);
wenJian.add(guanBiFile);
wenJian.add(guanBi);
//添加文本区域
textArea= new TextArea();
frame.add(textArea);
//“打开”功能界面方法
fileDia= new FileDialog(frame);
myEvent();
frame.setVisible(true);
}
publicvoid myEvent()
{
//窗口关闭功能
frame.addWindowListener(newWindowAdapter()
{
publicvoid windowClosing(WindowEvent we)
{
System.out.println("窗口关闭");
System.exit(0);
}
});
//“关闭”按钮监听
guanBi.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent ae)
{
System.out.println("关闭按钮");
System.exit(0);
}
});
//“打开”按钮监听
daKai.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent ae2)
{
fileDia.setTitle("OpenFile");
fileDia.setMode(FileDialog.LOAD);
//模式有LOAD和SAVE,对应不同的窗口,也就是熟悉的打开和另存为
fileDia.setVisible(true);
Stringstr_dir = fileDia.getDirectory();
Stringstr_file = fileDia.getFile();
//System.out.println(str_dir+"....."+str_file);
if(str_dir==null|| str_file==null)
return;
textArea.setText("");
//为了获取数据。
files= new File(str_dir,str_file);
//通过字符读取流进行数据的获取。
BufferedReaderbufr = null;
try
{
bufr= new BufferedReader(new FileReader(files));
Stringline = null;
while((line=bufr.readLine())!=null)
{
textArea.append(line+"\r\n");
}
bufr.close();
}
catch(IOException iox)
{
iox.printStackTrace();
thrownew RuntimeException("读取失败");
}
}
});
//“保存”按钮监听
baoCun.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent ae2)
{
saveFunction();
}
});
//“关闭文件”按钮监听
guanBiFile.addActionListener(newActionListener()
{
publicvoid actionPerformed(ActionEvent ae)
{
saveFunction();
files= null;//防止覆盖文件
textArea.setText("");//清空界面
}
});
}
//单独封装保存文件的方法
//当要操作的文件已经存在,文件保存对话框是不需要弹出的。
//只要要操作的文件不存在是,才会弹出对话框,进行文件目录和文件名称的指定。
privatevoid saveFunction()
{
if(files== null)
{
fileDia.setTitle("OpenFile");
fileDia.setMode(FileDialog.SAVE);
//模式有LOAD和SAVE,对应不同的窗口,也就是熟悉的打开和另存为
fileDia.setVisible(true);
Stringstr_dir = fileDia.getDirectory();
Stringstr_file = fileDia.getFile();
files= new File(str_dir,str_file);
}
Stringtext = textArea.getText();
BufferedWriterbufw = null;
try
{
bufw= new BufferedWriter(new FileWriter(files));
bufw.write(text);
bufw.flush();
bufw.close();
}
catch(IOExceptionioe)
{
thrownew RuntimeException("写入失败");
}
}
}
>>以上的程序还要通过命令行执行,但也可以封装成“.jar”文件双击执行
第一步:加上package GUIappEdit;
第二步:控制台执行javac -d . MenuOpenFileDemo.java命令,“.”表示当前目录,出现一个叫GUIappEdit的文件夹
第三步:这个时候执行jar命令虽然也可以生成jar文件,但是会执行失败,原因在于jar文件中有META-INF文件夹,其中的MANIFEST.MF记录配置信息,配置信息中并没有主函数的信息!
第四步:新建一个txt文件,我取名叫名叫:MenuOpenFileDemoInfo.txt,其中加入主函数信息:Main-Class:GUIappEdit.MenuOpenFileDemo。注意Main-Class:后有一个空格,MenuOpenFileDemo后一定要回车。
第五步:执行命令jar -cvfm GUIappEdit.jar MenuOpenFileDemoInfo.txt GUIappEdit
分别是:生成的jar文件名,主函数信息文件,包文件夹!
第六步:双击GUIappEdit.jar,可以执行了。
小插曲:
如果是使用绿色版本jre的机器(不是安装版的jre),还需要配置“文件夹选项”中的“文件类型”(winxp)!
操作方法:
1.新建,扩展名为jar
2.高级,选择一个图标
3.新建,命名为open,浏览,关联bin中的javaw.exe(图形化界面解析工具)后面空格,跟一个参数-jar
GUI告一段落!!!