------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
GUI概述
以前我们接触的操作窗口就是dos窗口,而且该窗口也有很大的局限性,比如只能使用dos命令,而且效率也比较低,所以Java为我们提供了GUI(图形用户话界面),用来可以直接操作图形
GUI和其他类一样也封装哎java.awt和javax,Swing这两个包中
区别:java awt这个包调用的是本地系统的方法,依赖于系统,跨平台性较差,属于重量级控件
javax.swing这个包是在awt的基础上,建立了一套图形用户界面的系统,提供了更多的控件,而且这些控件全部都是用Java写的,并且跨平台性更强。属于轻量级控件。
Java中布局
容器中的排列顺序就是布局
流式布局(FlowLayOut):默认时居中对齐,从左往右排序,如果一行不能够放下,那么就换行,依然也是居中对齐(Pannel默认的布局管理器)
边界布局(BorderLayOut):东南西北中,默认时居中对齐,如果没有指定控件的边界,那么该控件遍铺满整个窗体(Frame默认的布局管理器);
GrideLayOut():网格式布局
GridBagLayOut:网格包式布局:
CardLayOut:卡片式布局:
实例一:
需求:创建一个简单的GUI图形界面
/*
创建图形化界面的步骤:
1创建一个窗体framme
2设置窗体的基本属性,比如大小,位置,以及布局
3创建组件
4将组件添加到窗体中去.
*/
/*通过实验我们发现图形化界面是用另一个线程来控制,只要开启图形化界面,就会开启一个线程*/
import java.awt.*;
class GUIdemo1_1
{
public static void main(String[] args)
{
Frame f=new Frame("我的窗体");//创建一个不可见的窗体
f.setVisible(true);
f.setLocation(300,400);
f.setSize(400,400);
f.setLayout(new FlowLayout());
Button b=new Button("按钮");
f.add(b);
}
}
运行结果如下:
事件监听机制的流程:
事件处理机制的的特点:
1事件源:在java中是awt或者swing包中的组件。
2事件:每一个事件源都有对应的特有事件和共性的事件。
3监听器:将有可能触发的动作(有可能有多个)封装在监听器中
4事件处理程序:由程序员来编写。
前面三种在java中已经编写好。不需要程序员进行编写。
窗体事件的演示
实例:在关闭Frame窗口时,提示关闭汉字。
演示实例如下:
import java.awt.*;
import java.awt.event.*;
class GUIDemo1_2
{
public static void main(String[] args)
{
//创建一个窗体:(1事件源)
Frame f=new Frame();
f.setSize(300,300);
f.setLocation(213,121);
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);//关闭虚拟机2014-12-20
}
public void windowOpened(WindowEvent e)
{
System.out.println("打开了");
}
});//定义一个匿名的时间监听器,将监听器注册到事件源上,并覆盖WindowClosing方法,创建自己的时间处理程序。
*/
f.addWindowListener(new MyListener());
f.setVisible(true);
}
}
//WindowAdapter是WindowListener接口的实现子类,而且这个类是一个抽象类,复写了接口中的所有方法,但是方法的内容都是null,所以我们可以自定义一个事件处理程序,那样就只需要写我们需要监听的事件,如果我们直接继承自WindowListenner,那么我们就需要复写接口里面所有的方法,那样效率太低。
class MyListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)//只要外部有动作引用事件,那么就让那个动作封装成一个对象,并赋给e
{
System.out.println("我关");
System.exit(0);
}
public void windowActivated(WindowEvent e)//注意窗体先打开触发的是windowActivated(也就是窗体前置这个动作)这个事件。然后才是触发windowOpened这个事件。
{
System.out.println("激活了");
}
public void windowOpened(WindowEvent e)
{
System.out.println("窗体打开了");
}
}
接下来,我们讨论一下容器的鼠标事件和键盘事件。
代码如下:
import java.awt.*;
import java.awt.event.*;
class GUIDemo1_4
{
private Frame f;
private Button btn;
GUIDemo1_4()
{
init();
}
public void init()
{
f=new Frame();
btn=new Button("我的按钮");
f.setBounds(100,200,400,500);
f.setLayout(new FlowLayout());
f.add(btn);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.out.println("窗口已经关闭");
System.exit(0);//关闭虚拟机
}
});
//btn.addActionListener(new ActionListener(){
//actionPerformed这个事件是表示组件发生操作时就会被调用,比如触发这个事件的动作可能是键盘触发的,也可能是鼠标触发的。
/*public void actionPerformed(ActionEvent e)
{
System.out.println("窗口关闭,是按钮干的");
System.exit(0);
}
});
*/
//通过查阅Java API文档我们发现Component这个顶级容器都支持addMouseListener这个监听器。
btn.addMouseListener(new MouseAdapter(){
int clickCount=1;
int enterCount=1;
public void mouseClicked(MouseEvent e)
{
if(e.getClickCount()==2)
{
System.out.println("鼠标双击触发");
}
else
{
System.out.println("鼠标点击事件触发,点击次数"+clickCount++);
}
}
public void mouseEntered(MouseEvent e)
{
System.out.println("鼠标进入事件触发,进入次数"+enterCount++);
}
});
}
public static void main(String[] args)
{
new GUIDemo1_4();
}
}
运行结果如下:
接下我们我们来继续组件的键盘事件,
需求:
接下来我们在文本框来判断输入的文字是否是数字
代码如下:
import java.awt.*;
import java.awt.event.*;
class GUIDemo1_5
{
private Frame f;
private Button btn;
private TextField tf;
GUIDemo1_5()
{
init();
}
public void init()
{
f=new Frame("我的窗体");
btn=new Button("按钮一");
tf=new TextField(20);
f.setBounds(100,200,400,400);
f.setLayout(new FlowLayout());
f.add(tf);
f.add(btn);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
//给按钮添加一个键盘监听
btn.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
// if(KeyEvent.)
// System.out.println(e.getKeyChar()+"……"+e.getKeyCode());//获取键盘录入字符和字符所对应的ASCii码
//System.out.println(KeyEvent.getKeyText(e.getKeyCode()));//获取键盘录入所对应的字符串文本形式。
if(e.getKeyCode()==KeyEvent.VK_X)
{
System.out.println("您按下的是X键");
}
}
});
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
//用于校验文本框是否是输入的数字.
tf.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
int keycode=e.getKeyCode();
if(!(keycode>=KeyEvent.VK_0&&keycode<=KeyEvent.VK_9))
{
System.out.println("您输入的不是数字:"+e.getKeyChar()+"……"+e.getKeyCode());
//通过查询KeyEvent的基类InputEvent发现有一个方法就是consume(),这个方法来屏蔽键。
e.consume();
}
}
});
}
public static void main(String[] args)
{
new GUIDemo1_5();
}
}
运行结果如下:
通过上面的代码我们发现,其实图形用户化界面和我们以前使写过的Dos命令行代码使用的思想是一样的,只不过我们将展示的页面展现给用户。
接下来我们将实现一个小的Demo:
需求:在文本框中输入一个目录名,然后在另一个文本框中显示该目录名下所有的文件。
代码如下:
import java.awt.*;
import java.io.*;
import java.awt.event.*;
class GUIDemo1_6
{
private Frame f;
private Button btn;
private TextField tf;
private TextArea ta;
GUIDemo1_6()
{
init();
}
public void init()
{
f=new Frame();
btn=new Button("转入");
tf=new TextField(40);
ta=new TextArea(40,60);
f.setBounds(100,200,600,600);
f.setLayout(new FlowLayout());
f.add(tf);
f.add(btn);
f.add(ta);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
sop("窗口关闭");
System.exit(0);
}
});
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
File dir=new File(tf.getText());
if(dir.exists()&&dir.isDirectory())
{
String[] names=dir.list();
for(String name:names)
{
ta.append(name+"\r\n");
}
}
tf.setText("");
}
});
}
public static void main(String[] args)
{
new GUIDemo1_6();
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
运行结果如下:
接下来我们将结束对话框的使用方法。
通过查阅Java API文档我们发现,其实Dialog就是一个容器,我们可以向里面添加需要的组件,比如Button和Label等组件。使用代码如下:
import java.io.*;
import java.awt.*;
import java.awt.event.*;
class GUIDemo1_7
{
private Frame f;
private Button btn;
private Dialog dia;
private Label lab;
private Button btnOk;
private TextField tf;
private TextArea ta;
GUIDemo1_7()
{
init();
}
public void init()
{
f=new Frame("我的窗体");
btn=new Button("转到");
btnOk=new Button("确定");
dia=new Dialog(f,"提示消息",true);//构造一个最初不可见的、无模式的 Dialog,它带有指定的所有者 Frame 和标题。第三个参数表示如果为true,表示如果不对对话框进行操作,如果没有操作,就不能操作其他的窗口。
dia.setBounds(100,200,300,150);
tf=new TextField(40);
ta=new TextArea(40,50);
lab=new Label();
f.setBounds(100,200,600,600);
f.setLayout(new FlowLayout());
dia.setLayout(new FlowLayout());
dia.add(lab);
dia.add(btnOk);
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)
{
//录入目录后,如果用户按下Enter键,开始显示录入目录下对应的所有文件。
if(e.getKeyCode()==KeyEvent.VK_ENTER)
{
searchDir();
}
}
});
btnOk.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
dia.setVisible(false);
}
});
dia.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
dia.setVisible(false);
}
});
f.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
searchDir();
}
});
}
public static void main(String[] args)
{
new GUIDemo1_7();
}
private void searchDir()
{
File dir=new File(tf.getText());
//如果输入的是文件夹名
if((dir.exists()&&dir.isDirectory()))
{
String[]names=dir.list();
for(String name :names)
{
ta.append(name+"\r\n");
}
}
//如果输入的不是文件夹名
else
{
lab.setText("错误提示:"+dir+"不是文件夹,请重新输入");
dia.setVisible(true);
}
tf.setText("");
}
}
运行结果如下:
接下来,我们将接着继续使用Menu这个组件的使用方法。
代码如下:
import java.awt.*;
import java.awt.event.*;
class GUIDemo1_8
{
private Frame f;
private MenuBar mb;
private Menu m1,m2;
private MenuItem mi,m3;
GUIDemo1_8()
{
init();
}
private void init()
{
f=new Frame("我的窗口");
f.setBounds(100,200,400,400);
f.setLayout(new FlowLayout());
mb=new MenuBar();
m1=new Menu("文件");
mi=new MenuItem("退出");
m2=new Menu("操作");
m3=new MenuItem("编辑");
m1.add(mi);
mb.add(m1);
m1.add(m2);
m2.add(m3);
f.setMenuBar(mb);
myEvent();
f.setVisible(true);
}
private void myEvent()
{
mi.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
}
public static void main(String[] args)
{
new GUIDemo1_8();
}
}
通过上面的实例我们发现,Frame通过setMenuBar()将指定的MenuBar添加到frame中,然后将指定的Menu添加到指定的MenuBar中,如果Menu中没有子菜单了,那么就可以使用MenuItem来代替。有子菜单就只能使用Menu。
运行结果如下:
接来下,我们使用Menu和MenuBar的使用实例:
实例:使用Menu和MenuBar来模拟记事本。
代码如下:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class GUIDemo1_9
{
private Frame f;
private MenuBar mb;
private Menu m;
private MenuItem mi1,mi2,mi3;
private FileDialog fdia;
private TextArea ta;
private String fileTemp=null;
GUIDemo1_9()
{
init();
}
public void init()
{
f=new Frame("我的窗口");
f.setBounds(100,100,500,500);
mb=new MenuBar();
m=new Menu("文件");
mi1=new MenuItem("打开");
mi2=new MenuItem("保存");
mi3=new MenuItem("退出");
ta=new TextArea();
fdia=new FileDialog(f,"文件打开",FileDialog.LOAD);
fdia.setBounds(100,100,400,400);
m.add(mi1);
m.add(mi2);
m.add(mi3);
f.setMenuBar(mb);
f.add(ta);
mb.add(m);
myEvent();
f.setVisible(true);
}
public void myEvent()
{
//模拟记事本打开文件的操作。
mi1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
fdia.setVisible(true);
ta.setText("");
String dirPath=fdia.getDirectory();//获取选取文件的目录名。
String filename=fdia.getFile();//获取文件夹的文件
if(dirPath==null&&filename==null)
return;
File f=new File(filename);
fileTemp=dirPath+filename;
System.out.println(dirPath+filename);
BufferedReader br=null;
try
{
br=new BufferedReader(new FileReader(dirPath+filename));
String line=null;
while((line=br.readLine())!=null)
{
ta.append(line+"\r\n");
}
}
catch (IOException e1)
{
throw new RuntimeException("文件复制失败");
}
finally
{
try
{
if(br!=null)
br.close();
}
catch (IOException e2)
{
throw new RuntimeException("字符读取流关闭失败");
}
}
}
});
//点击保存按钮也可以保存文件。
mi2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
save();
}
});
ta.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
//使用快键键也可以保存文件
if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_S)
{
save();
}
}
});
mi3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
}
private void save()
{
BufferedWriter bw=null;
String text=ta.getText();
try
{
bw=new BufferedWriter( new FileWriter(fileTemp));
bw.write(text);
bw.flush();
ta.setText("");
}
catch (IOException e1)
{
throw new RuntimeException("文件保存失败");
}
finally
{
try
{
if(bw!=null)
bw.close();
}
catch (IOException e2)
{
throw new RuntimeException("字符写入流关闭失败");
}
}
}
public static void main(String[] args)
{
new GUIDemo1_9();
}
}