--------------------- android培训、java培训、java学习型技术博客、期待与您交流! -------------------
GUI 图形界面设计
什么是GUI?
Awt什么意思?什么特点?
Swing有什么特点?
Component和其子类示意图?
Container和其他组件的区别?
什么是布局?
常见布局管理器有哪几种?分别是什么样的界面?
图形化界面和主程序是不是两个线程?
事件监听机制的特点以及原理?
图形化界面一般导入那些包?
体系图:
GUI图形界面设计:在java中,提供的类和接口都在java.awt和java.swing包中。
awt(abstract Window ToolKit)抽象窗口工具包。使用功能时,需要调用本地系统方法实现功能,属于重量控件。
swing:在awt的基础上建立了一套图形界面系统,其中提供了更多 的组件,而且完全由java实现,增强了移植性,因此,swing更稳定。属于轻量级控件。
对于控件组件的排列是一种布局:
1 流式布局FlowLayout:根据控件大小,按照顺序进行排放,一行排满自动下一行。
2 边界式布局BorderLayout:按照组件的东南西北中五个方位进行排放。若只有一个控件,则填充整个组件。默认边界式布局
3 格式布局GridBagLayout:按照网格布局
4 卡片布局CardLayout:一个窗口中有多个组件重叠在一起,可以选择切换。
5 目标式布局:位置随便放
GUI图形用户界面
GUI Graphical UserInterface 图形用户接口
用图形的方式,来显示计算机操作的界面,这样更方便更直观
CLI command-line interface,命令行用户接口
常见的DOS命令行操作,需要记忆一些常用的命令,操作不直观。
Java为GUI提供的对象都存在java.awt和javax.Swing两个包中。
AWT和SWING
AWT,Abstract Windowing Toolkit,抽象窗口工具包。需要调用本地系统方法实现功能。属于重量级控件。
SWING,在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由java实现。增强了移植性,属于轻量级控件。
Button 按钮
Label 标签,文字支持封装成组件对象就是label(作用就是封装文字)
Checkbox 复选框
Textcomponent 文本区域
Container (特殊子类)容器,常见子类 window 、panel(面板),可以通过add其他组件,而其他组件不能添加Container
Window下的子类,frame (框架)和dialog(对话框)
Filedialog文件对话框
布局管理器
常见布局管理器:
FlowLayout 流式布局管理器
从左到右的顺序排列,Panel默认布局管理器
Borderlayout边界布局管理器
东南西北中,排列,Frame默认布局管理器
GridLayout 网格布局管理器
规则的矩阵
CardLayout 卡片布局管理器
选项卡
GirdBagLayout网格包布局管理器
非规则矩阵
也有多种布局方式组合而成的布局,这是先将窗体布局,分成几个panel(面板),然后再将具体的布局管理器放入不同的面板
AWT的对象
Component:构造函数
Componentadd(Component comp, int index) 将指定组件添加到此容器的给定位置上。返回值类型也是Component
Frame() 构造函数:构造一个最初不可见的 Frame 新实例()。
setVisible(boolean b)根据参数 b 的值显示或隐藏此 Window。返回值是void。b - 如为 true,则使 Window 可见,否则隐藏 Window。
每次开启图形界面就会多一个线程,与主线程是多线程运行的
void setSize(intwidth, int height)调整组件的大小,使其宽度为 width,高度为 height。
传参数,第一个一般都是横坐标,第二个一般都是纵坐标。
f.setLocation(300,200):设置边距,距离屏幕最左边300.距离最上面200. Frame是流式布局管理器。从左到右的顺序排列
Button(String label),button构造函数,构造一个带指定标签的按钮。标签可以是字符串形式
FlowLayout()构造一个新的 FlowLayout,它是居中对齐的,默认的水平和垂直间隙是 5 个单位。
public voidsetLayout(LayoutManager mgr)设置此容器的布局管理器。 LayoutManager mgr 是指定的布局管理器
创建图形化界面:
1,创建frame窗体。
2,对窗体进行基本设置。
比如大小,位置,布局。
3,定义组件。
4,将组件通过窗体的add方法添加到窗体中。
5,让窗体显示,通过setVisible(true)
演示代码:
importjava.awt.*;
class AwtDemo
{
public static void main(String[] args)
{
Frame f =new Frame ("myawt");//利用Frame创建一个不可见的Frame新实例。
f.setSize(500,400);//void setSize(intwidth, int height)调整组件的大小,使其宽度为 width,高度为 height。
f.setLocation(300,200);//设置边距,距离屏幕最左边300.距离最上面200.
f.setLayout(new FlowLayout());//利用setLayout函数设置指定的布局管理器,FlowLayout是居中对齐的一种窗口布局
Button b = new Button("我是一个大按钮");//button构造函数,构造一个带指定标签的按钮。标签可以是字符串形式
f.add(b);//创建以后利用add函数将b添加到f窗口布局中来。如果没有设置布局管理,这个按钮默认全部填充到窗口中
f.setVisible(true);//setVisible(booleanb)根据参数 b 的值显示或隐藏此 Window。返回值是void。b - 如为 true,则使 Window 可见,否则隐藏 Window。
//这是运行程序会发现程序没有停止,因为有一个线程没有中断,这个线程就是多出现一个可见的窗口,但是很小。GUI出现就自动多线程,和主线程并行运行
}
}
新建的窗口无法关闭,是因为没有设置时事件监听机制
事件监听机制:
组成:
1 事件源(组件)
2 事件(Event)
3 监听器(Listener)
4 事件处理(引发事件后的处理方式)
模拟原理图:
事件源:就是awt包或者swing包中的那些图形界面组件。
事件:每一个事件源都有自己特有的对应事件和共性事件。
监听器:将可以触发某一个事件的动作(不只一个动作)都已经封装到了监听器中。
以上三者,在java中都已经定义好了。直接获取其对象来用就可以了。我们要做的事情是,就是对产生的动作进行处理。
窗体事件:
voidaddWindowListener(WindowListener l):添加指定的窗口侦听器,以从此窗口接收窗口事件。。WindowListener是窗口监听器。Listener结尾的都是监听器。
WindowListener 接口,内部有很多函数可以操作窗口,想要调用必须全部覆写其中的7个方法。所以可以直接使用子类WindowAdapter
WindowAdapter 抽象类,覆写了WindowListener的所有方法,同时方法为空。抽象类不让创建对象,但是内部都不是抽象类,就是为了方便监听器创建对象。
抽象类没有抽象方法,意义是不让其创建对象,WindowAdapter的作用是方便创建监听器的对象(匿名内部类)。
importjava.awt.*;
importjava.awt.event.*;//因为图形化界面有可能会用到event包,所以需要导入这个
class AwtDemo1
{
public static void main(String[] args)
{
Frame f = new Frame("myawt");
f.setSize(500,400);
f.setLocation(300,200);
f.setLayout(new FlowLayout());
Button b = new Button("我是一个按钮");
f.add(b);
f.addWindowListener(newWindowAdapter()//匿名内部类,定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
{
public voidwindowClosing(WindowEvent e)//WindowAdapter中的windowClosing的命令,用来关闭窗体
{
System.out.println("我关");
System.exit(0);//java虚拟机退出命令,如果点击关闭按钮,那么就可以关闭窗口了。比较简单的一个命令
}
public voidwindowActivated(WindowEvent e) //windowActivated命令,当激活窗口时调用此函数
{
System.out.println("我活了。");
}
public voidwindowOpened(WindowEvent e) //当窗口打开时调用此函数
{
System.out.println("我被打开了,hahahhahah");
}
});
f.setVisible(true);
//System.out.println("HelloWorld!");
}
}
Action事件
如何让按钮具备退出程序的功能?思路很重要的
按钮就是事件源。那么选择哪个监听器呢?
通过关闭窗体示例了解到,想要知道哪个组件具备什么样的特有监听器。需要查看该组件对象的功能。通过查阅button的描述。发现按钮支持一个特有监听addActionListener()
ActionListener是一个接口,并且是少数不需要适配器的一个接口,因为里面只有一个函数,方便覆盖。接口内部方法超过3个(包括3个)一般都有Adapter(适配器)
一般将事件和
演示代码:
importjava.awt.*;
importjava.awt.event.*;
class MouseAndKeyEvent
{
private Frame f;
private Button but;
private TextField tf;//建立一个文本框对象tf
MouseAndKeyEvent()//构造函数,初始化图形
{
init();
}
public void init()
{
f = new Frame("my frame");
f.setBounds(300,100,600,500);
f.setLayout(new FlowLayout());
tf = new TextField(20);//新建一个列数为20的新文本框,赋值给tf
but = new Button("mybutton");
f.add(tf);//添加文本框
f.add(but);//添加按钮。
myEvent();//执行窗口监听事件
f.setVisible(true);//将窗口可见
}
private void myEvent()//窗口监听事件。
{//确定事件源,确定事件,确定监听器,确定执行操作
f.addWindowListener(newWindowAdapter()
{
public voidwindowClosing(WindowEvent e)
{
System.exit(0);
}
});
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvente)
{
int code =e.getKeyCode();//建立一个code作为监听键盘获取的code值
if(!(code>=KeyEvent.VK_0&& code<=KeyEvent.VK_9))//只要不打印数字,就执行下面操作
{
System.out.println(code+".....是非法的");//输出code值和字符串
e.consume();//consume()不准备用默认的操作处理,放在这里就是不能输入非数字类的数值
}
}
});
//给But添加一个键盘监听。
but.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvente)//覆写KeyAdapter中的方法,接受对象是KeyEvent键盘事件
{ //button是事件源,在这上面建立了事件监听,当(if命令)有事件发生时,就执行下列操作
if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_ENTER)//e.isControlDown(),当监听Control按下的时候,并且按下ENTER时,执行下面的操作。KeyEvent.VK_ENTER静态常量,当输入ENTER时执行操作。
//System.exit(0);
System.out.println("ctrl+enteris run");
//System.out.println(KeyEvent.getKeyText(e.getKeyCode())+"...."+e.getKeyCode());e.getKeyCode()按键盘对应的键名,e.getKeyCode()键名所对应的的code值
}//KeyEvent.getKeyText()调用静态函数getKeyText可以显示shift和f1等键名
});
/*添加按钮监听机制
but.addActionListener(newActionListener()//button下的addActionListener函数,可以添加事件监听,监听ActionListener(),只要按钮有事件发现就执行下面的命令。这个时候可以监听到键盘和鼠标两个事件的发生。
{
public voidactionPerformed(ActionEvent e)
{
System.out.println("actionok");不论键盘和还是数据,只要检测到点击,那么就输出action ok
}
});
*/
/*
but.addMouseListener(newMouseAdapter()调用addMouseListener函数创建MouseAdapter()的监听机制。利用了匿名内部类
{
private int count = 1;
private int clickCount = 1;
public voidmouseEntered(MouseEvent e) 鼠标进入按钮区域,就执行下面的函数
{
System.out.println("鼠标进入到该组件"+count++);
}
public voidmouseClicked(MouseEvent e)鼠标点击,就执行下面的函数
{
if(e.getClickCount()==2)//如果鼠标点击次数为2,那么才执行下面的命令。也就是双击才能执行下面的命令
System.out.println("双击动作"+clickCount++);
}
});
*/
}
public static void main(String[] args)
{
new MouseAndKeyEvent();
}
}
自己总计的简单窗口设计步骤:
1 定义main方法类
2 定义另一个类处理窗体
|--定义容器和组件
|--进行公共内容的处理:如获取分辨率等
|--定义构造方法调用初始化方法
|--定义初始化方法A初始化组件
|--每个组件属性独立设置
|--需要向容器添加组件
|--用到组件时进行初始化
|--组件属性设置
|--添加
|--调用事件方法
|--单独定义事件方法,定义各组件的注册事件
练习:列出指定目录内容
importjava.awt.*;
importjava.io.*;
importjava.awt.event.*;
class MyWindowDemo
{
private Frame f;
private Button but;
private TextField tf;//文本输入区对象。
private TextArea ta;//文本显示区对象
MyWindowDemo()
{
init();//初始化图形
}
public void init()
{
f = new Frame("王潇贱专用窗口");
f.setBounds(300,100,600,500);//窗口大小
f.setLayout(new FlowLayout());//窗口框架
tf = new TextField(60);//行数
but = new Button("转到");//Button上面的字符串
ta = new TextArea(20,70);//文本区的行数和列数
f.add(tf);
f.add(but);
f.add(ta);//添加按钮和文本区
myEvent();//执行监听事件函数
f.setVisible(true);//将窗口设置成不隐藏
}
public void myEvent()
{
but.addActionListener(new ActionListener()
{
public voidactionPerformed(ActionEvent e)
{
String dirPath =tf.getText();//设置一个dirPath用来接收输入的文本
File dir = new File(dirPath);//建立一个file对象dir,用来接收输入的路径
if((dir.exists()&&dir.isDirectory()))//如果路径存在文件或者文件夹
{
ta.setText("");//先清空上次输入的信息
String[] names =dir.list();//建立一个names的字符串数组,用来接收dir的目录。
for (Stringname : names )//遍历
{
ta.appendText(name+"\r\n");//appendText()函数用来添加name并且可以保持上次添加的内容
}
}
//String text =tf.getText();
//ta.setText(text);//设置TextField输入的字符串为text,并把text输入到TextArea中
//System.out.println(text);//输出
//tf.setText("");//每次打印完再清空
}
});
f.addWindowListener(newWindowAdapter()//窗口监听,点检关机就关上窗口
{
public voidwindowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
public static void main(String[] args)
{
new MyWindowDemo();
}
}
对话框Dialog:
private Dialog d;
private Label lab;
private Button okBut;
d = new Dialog(f,"提示信息-self",true);//true模式代码本对话框不接受,前窗口无法操作
d.setBounds(400,200,240,150);//对话框大小
d.setLayout(new FlowLayout());//窗口模式
lab = new Label();//新的文字
okBut = new Button("确定");
d.add(lab);
d.add(okBut);
okBut.addActionListener(newActionListener()
{
public voidactionPerformed(ActionEvent e)
{
d.setVisible(false);//对话框结束那么就隐藏该对话框
}
});
在窗口中添加菜单
private MenuBar mb;//添加菜单用MenuBar
private Menu m,subMenu;//菜单对象
private MenuItem closeItem,subItem;//子菜单对象
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);//将文件这个菜单添加到窗口中
双击执行jar包:
首先将class文件配置到一个文件中,利用jar文件变成一个jar包
需要在一个文本里面写入(文件名随意,如1.txt)
Main-Class: myMenu.MyMenuTest
注意分号后有个空格,最好还要有个回车!Main-Class: 空格myMenu.MyMenuTest回车
然后编译时,使用 jar –cvfm my.jar 1.txt mymenu
这样双击就可以打开了
Jar包:
Javac –d –cvfmy.jar
自定义jar包中,添加属性,自动执行默认class文件。
如建立1.txt,内容为:
Main-Class: mymenu.MyMenuTest (分号后面有个空格,最后还要有个回车)
Javac –d –cvfm1.txt mymenu
经典案例:模拟记事本
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class MenuDemo
{
public static void main(String[] args)
{
new MyMenu();
}
}
class MyMenu
{
private Frame frame;
private MenuBar mb;
private Menu menu1;
private MenuItem mitOpen;
private MenuItem mitSave;
private MenuItem mitCancel;
private FileDialog openFileDlo;
private FileDialog saveFileDlo;
//定义文件对象
File file;
private TextArea texta;
MyMenu()
{
menuDemo();
}
public void menuDemo()
{
frame=new Frame("模拟记事本");
frame.setBounds(300, 200, 600, 500);
frame.setVisible(true);
//不用布局,使用默认的边界式布局即可
//frame.setLayout(new FlowLayout());
texta=new TextArea();
texta.setVisible(true);
frame.add(texta);
//创建资源管理器,是Dialog的子类,文件对话框 指定要打开读取的文件,默认LOAD
openFileDlo=new FileDialog(frame,"我要打开",FileDialog.LOAD);
//指定保存文件,即写出文件
saveFileDlo=new FileDialog(frame,"我要保存",FileDialog.SAVE);
mb=new MenuBar();
menu1=new Menu("文件");
mitOpen=new MenuItem("打开");
mitSave=new MenuItem("保存");
mitCancel=new MenuItem("退出");
mb.add(menu1);
menu1.add(mitOpen);
menu1.add(mitSave);
menu1.add(mitCancel);
frame.setMenuBar(mb);
myEvent();
}
public void myEvent()
{
//窗口关闭事件
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
//菜单项退出活动事件
mitCancel.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//判断文件是否存在,不存在时进行创建
if(file==null)
{
saveFileDlo.setVisible(true);
//同样要获取保存的路径名和文件名
String fileDir=saveFileDlo.getDirectory();
String fileName=saveFileDlo.getFile();
//判断选择是否为空
if(fileDir==null || fileName==null)
return;
//封装成对象
file=new File(fileDir,fileName);
}
//存在该文件,直接写入,及时保存
try
{
BufferedWriter bufw=
new BufferedWriter(new FileWriter(file));
//获取文本域内容
String text=texta.getText();
//写入文件,写的文本是文本域的内容
bufw.write(text);
bufw.flush();
bufw.close();
}
catch (IOException ie)
{
ie.getStackTrace();
}
System.exit(0);
}
});
//菜单项打开活动事件
mitOpen.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
openFileDlo.setVisible(true);
//打开文件操作
//获取文件路径名
String fileDir=openFileDlo.getDirectory();
//获取文件名
String fileName=openFileDlo.getFile();
//如果文件为空,直接返回
if(fileDir==null || fileName==null)
return;
//当文件有效时,进行文本域的清空,这时父类中的方法
texta.setText("");
//将文件封装成对象
file=new File(fileDir,fileName);
try
{
BufferedReader bufr=
new BufferedReader(new FileReader(file));
//文件读取,按照行读取
String line=null;
while((line=bufr.readLine())!=null)
{
texta.append(line+"\r\n");
}
bufr.close();
}
catch (IOException ie)
{
ie.getStackTrace();
}
}
});
//菜单项保存活动事件
mitSave.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//判断文件是否存在,不存在时进行创建
if(file==null)
{
saveFileDlo.setVisible(true);
//同样要获取保存的路径名和文件名
String fileDir=saveFileDlo.getDirectory();
String fileName=saveFileDlo.getFile();
//判断选择是否为空
if(fileDir==null || fileName==null)
return;
//封装成对象
file=new File(fileDir,fileName);
}
//存在该文件,直接写入,及时保存
try
{
BufferedWriter bufw=
new BufferedWriter(new FileWriter(file));
//获取文本域内容
String text=texta.getText();
//写入文件,写的文本是文本域的内容
bufw.write(text);
bufw.flush();
bufw.close();
}
catch (IOException ie)
{
ie.getStackTrace();
}
}
});
}
}
简单总结:
1. Frame窗体
|-- 构造方法(标题)
|-- setBounds(x,y,width,height)
|-- setVisible(true)
|-- setLayout(null)取消了布局,所有其他组件必须定义位置和尺寸
|-- add()添加组件
|-- setMenuBar()为窗体添加菜单
2. Button
|-- 构造方法(标题)
|-- setBounds(x,y,width,height)
3. TextField 单行
|-- 构造方法(标题)
|-- setBounds(x,y,width,height)
|-- String getText()获取文本框内的内容
|-- void setText()设置文本框的内容
4. TextArea 多行,有滚动条
|-- 构造方法(标题)
|-- setBounds(x,y,width,height)
|-- String getText()获取文本框内的内容
|-- void setText()设置文本框的内容
5. Label 文本标签
|-- 构造方法(标题)
|-- setBounds(x,y,width,height)
6. Dialog 对话框
|-- 构造方法(属于哪个窗体,标题,模式 true)
|-- setVisible(true)
7. FileDialog
|-- 构造方法(属于哪个窗体,标题,模式 save load)
|-- setVisible(true)
|-- String getDirectory()获取选中的目录
|-- String getFile()获取选中的文件名
8. MenuBar
|-- 添加到窗体中
|-- Menu
|-- 添加到MenuBar
|-- MenuItem
|-- 添加到Menu
|-- 子菜单
|-- 将Menu添加到Menu
9. 事件监听器
|-- 窗体事件 WindowListener
窗体.addWindowListener(new 窗体适配器(){
覆盖需要的方法
});
|-- 鼠标事件 MouseListener
按钮.addMouseListener(new 鼠标适配器(){
覆盖需要的方法
});
|-- 键盘事件 KeyBordListener
|-- 活动事件 ActionListener