一、 GUI概述
1、GUI(Graphic User Interface):图形用户接口;用图形的方式来显示计算机操作的界面,这样更方便更直观。
2、CLI(Command Line User Interface):命令行用户接口;就是常见的DOS命令行,需要记忆一些常见的命令,操作不直观。
3、Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。
Awt和Swing:
java.Awt: Abstract Window ToolKit(抽象窗口工具包),需要调用本地系统方法实现功能,属于重量级控件。
Javax.Swing: 在Awt的基础上建立的一套图形界面系统,其中提供了更多的组件,而且完全由java实现;增强了移植性,属于轻量级控件。
4、GUI中的继承关系图
Container:为容器,是一个特殊的组件。该组件中可以通过add方法添加其他组件进来。
二、布局管理器
1、布局:容器中组件的排放位置。
2、常见的布局管理器
1)、FlowLayout(流式布局管理器)
从左到右的顺序排列,是Panel的默认布局管理器。
2)、BorderLayout(边界布局管理器)
东、南、西、北、中;是Frame的默认布局管理器。
3)、GridLayout(网格布局管理器)
规则的矩阵。
4)、CardLayout(卡片布局管理器)
选项卡。
5)、GridBagLayout(网格包布局管理器)
非规则的矩阵。
三、 GUI各类相关操作
1、创建一个简单的图形化界面
创建图形化界面思路:
1)、创建Frame窗体;
2)、对窗体进行基本设置;如大小、布局、位置。
3)、定义组件;
4)、将组件通过窗体的add方法添加到窗体中;
5)、通过setVisible(true)让窗体显示。
演示示例:
import java.awt.*;
class AwtDemo
{
public static void main(String[] args)
{
Frame f = new Frame("java");//创建窗体;
f.setSize(500,400);//设置尺寸;
f.setLocation(500,400);//设置位置;
f.setLayout(new FlowLayout());//设置布局;
Button b = new Button("button");//创建按钮;
f.add(b);//将按钮添加到窗体;
f.setVisible(true);//设置窗体可见;
}
}
2、事件监听机制
1)、事件监听机制流程图
2)、事件监听机制的特点
A、事件源;是awt包或者Swing包中的图形界面组件。
B、事件;每一个事件源都有自己特有的对应事件和共性事件。
C、监听器;讲可以触发某一个事件的动作(不止一个动作)都已封装到监听器中。
D、事件处理;
3、窗体事件
在Frame窗体中,可以使用Window类对窗体进行各种监听。Window 对象是一个没有边界和菜单栏的顶层窗口。窗口的默认布局是 BorderLayout。在Window类中我们发现了addWindowListener(WindowListener 1)方法可以添加对窗体的各种监听。
WindowListener是一个接口,该接口下有7个方法可以监听不同的事件状态,但由于WindowListener是一个接口,如果使用该接口的话,就需要覆盖它的7个方法,这种做法很麻烦。我们可以继续发现WindowListener接口下还有各种子类,其中的抽象子类WindowAdapter复写了其所有方法,但此类中的方法为空。此类存在的目的是方便创建侦听器对象。
所以我们可以创建方法来继承WindowAdapter,再按照我们的需求来复写其中的各种方法来实现我们的目的。
演示示例:
import java.awt.*;
import java.awt.event.*;
class AwtDmeo1
{
private Frame f;
private Button b;
AwtDmeo1()
{
init();
}
public void init()
{
f = new Frame("java test");
f.setBounds(500,400,500,400);
f.setLayout(new FlowLayout());
b = new Button("Button");
f.add(b);
myEvent();
f.setVisible(true);
}
private void myEvent()
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.out.println("退出");
System.exit(0);
}
});
}
public static void main(String[] args)
{
new AwtDmeo1();
}
}
4、Action事件
ActionListener:用于接收操作事件的侦听器接口。对处理操作事件感兴趣的
类可以实现该接口,而使用该类创建的对象可使用组件的 addActionListener方法向该组件注册。在发生操作事件时,调用该对象的 actionPerformed 方法。
如果想要按钮具备退出功能,通过查找Button的API文档,我们知道了Button中也具备一个添加监听器的方法:addActionListener(addActionListener 1),再通过
查看接口ActionListener接口,我们知道了该接口只有一个方法actionPerformed(actionEvent e),所以我们只需要覆盖该方法就可以实现我们想要的结果。
5、鼠标、键盘事件
MouseListener:用于接收组件上“感兴趣”的鼠标事件,(按下、释放、单击、进入或离开)的侦听器接口。(要跟踪鼠标移动和鼠标拖动,请使用 MouseMotionListener。)
KeyListener: 用于接收键盘事件(击键)的侦听器接口。旨在处理键盘事件的类要么实现此接口(及其包含的所有方法),要么扩展抽象 KeyAdapter 类(仅重写有用的方法)。 然后使用组件的 addKeyListener 方法将从该类所创建的侦听器对象向该组件注册。按下、释放或键入键时生成键盘事件。然后调用侦听器对象中的相关方法并将该 KeyEvent 传递给它。
演示示例:
import java.awt.*;
import java.awt.event.*;
class MouseAndKeyEvent
{
private Frame f;
private Button b;
private TextField tf;
MouseAndKeyEvent()
{
init();
}
public void init()//初始化窗体;
{
f = new Frame("java test");
f.setBounds(500,400,500,400);
f.setLayout(new FlowLayout());
b = new Button("Button");
tf = new TextField(20);
f.add(tf);
f.add(b);
myEvent();
f.setVisible(true);
}
private void myEvent() //自定义事件触发源;
{
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.out.println("退出");
System.exit(0);
}
});
b.addActionListener(new ActionListener()//添加动作监听器;
{
public void actionPerformed(ActionEvent e)
{
System.out.println("action ok!!!");
}
});
b.addMouseListener(new MouseAdapter()//添加鼠标监听器;
{
int count = 1;
public void mouseEntered(MouseEvent e)
{
System.out.println("鼠标进入Button范围"+count++);
}
public void mouseExited(MouseEvent e)
{
System.out.println("鼠标离开Button范围----"+count++);
}
public void mouseWheelMoved(MouseWheelEvent e)
{
System.out.println("滚轮滚动"+count++);
}
public void mouseClicked(MouseEvent e)
{
if(e.getClickCount() == 2)
System.out.println("点击鼠标!");
}
});
//在Button上加上一个键盘监听;
b.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER)//当同时按下Ctrl+Enter键时,退出系统;
System.exit(0);
//System.out.println(e.getKeyChar()+"...."+e.getKeyCode());//打印键盘上的字符以及对应的ASCII值;
}
});
tf.addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if(!(e.getKeyCode() >= e.VK_0 && e.getKeyCode() <= e.VK_9))
{
System.out.println(e.getKeyCode()+"是非法字符!");
e.consume(); //让非法字符不进入文本框;
}
}
});
}
public static void main(String[] args)
{
new MouseAndKeyEvent();
}
}
练习:用java编写一个类似于目录索引的对话框,当输入正确的目录时,将目录中的子目录输出到文本域中。如果输入错误的路径,则弹出对话框提示错误。
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class MyWindowDemo
{
private Frame f;
private TextField tf;
private Button b;
private TextArea ta;
private Dialog d;
private Label lab;
private Button okBut;
MyWindowDemo()
{
init();
}
public void init()
{
f = new Frame("Java test");
b = new Button("转到");
tf = new TextField(60);
ta = new TextArea(25,80);
d = new Dialog(f,"错误信息",true);
d.setBounds(350,150,300,150);
d.setLayout(new FlowLayout());
lab = new Label();
d.add(lab);
okBut = new Button("确定");
d.add(okBut);
f.add(tf);
f.add(b);
f.add(ta);
f.setBounds(300,100,600,500);
f.setLayout(new FlowLayout());
myEvent();
f.setVisible(true);
}
private void myEvent()
{
b.addActionListener(new ActionListener()//设置“转到”按钮监听器;
{
public void actionPerformed(ActionEvent e)
{
showDir();
}
});
tf.addKeyListener(new KeyAdapter()//设置文本框监听器,当在文本框中点击回车符时,
{ //启用showDir()方法;
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ENTER)
showDir();
}
});
d.addWindowListener(new WindowAdapter()//设置对话框的窗口监听;
{
public void windowClosing(WindowEvent e)
{
d.setVisible(false);
}
});
okBut.addActionListener(new ActionListener()//设置对话框中的按钮监听;
{
public void actionPerformed(ActionEvent e)
{
d.setVisible(false);
}
});
okBut.addKeyListener(new KeyAdapter()//设置键盘监听;
{
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ENTER)
d.setVisible(false);
}
});
f.addWindowListener(new WindowAdapter()//设置主窗体的窗口监听;
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
/*该方法的作用是,当文本框中输入的是正确的目录路径,就进入该目录下,
将该目录下的子目录列出来,显示在文本域中;如果路径错误,则弹出对话“错误信息”
对话框,显示路径错误,但点击对话框中的“确定”按钮,或者“关闭”是就隐藏对话框*/
public void showDir()
{
ta.setText("");
String dirPath = tf.getText();
File dir = new File(dirPath);
if(dir.exists() && dir.isDirectory())
{
String[] names = dir.list();
for(String name: names)
{
ta.append(name+"\r\n");
}
}
else
{
String info = "您输入的"+dirPath+"是错误路径,请重新输入!";
lab.setText(info);
d.setVisible(true);
}
tf.setText("");
}
public static void main(String[] args)
{
new MyWindowDemo();
}
}
6、设置菜单栏
Menu:Menu对象是从菜单栏部署的下拉式菜单组件。
MenuBar:类封装绑定到框架的菜单栏的平台概念。为了将该菜单栏与 Frame
对象关联,可以调用该框架的 setMenuBar 方法。
MenuItem:默认的 MenuItem
对象包含一个简单的加标签的菜单项。
下面通过编写一个类似于记事本中具备打开、保存、关闭功能的java小程序来演示在窗体中添加菜单栏。
需求:在窗体中添加菜单栏,在菜单栏中添加打开、保存、关闭。并实现其对应的具体功能。该程序中需要使用到的类,及其方法:
FileDialog:该类显示一个对话框窗口,用户可以从中选择文件。由于它是一个模式对话框,当应用程序调用其show方法显示对话框时,它将阻塞其余应用程序,直到用户选择一个文件。
String getDirectory(): 获取此文件对话框的目录;
String getFile(): 获取此文件对话框的选定文件;
Static int LOAD: 此常量值指示文件对话框窗口的作用是查找要读取的文件。
Static int SAVE: 此常量值指示文件对话框窗口的作用是查找要写入的文件。
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class MenuDemo
{
private File file;
private Frame f;
private Menu fileMenu;
private MenuBar menuBar;
private MenuItem closeItem,saveItem,openItem;
private FileDialog openDialog,saveDialog;
private TextArea ta;
MenuDemo()
{
init();
}
public void init()
{
f = new Frame();
f.setBounds(500,300,600,600);
//f.setLayout(new FlowLayout());
menuBar = new MenuBar(); //创建菜单栏;
fileMenu = new Menu("文件");//创建菜单;
closeItem = new MenuItem("退出");//创建菜单条目;
openItem = new MenuItem("打开");
saveItem = new MenuItem("保存");
menuBar.add(fileMenu); //将菜单添加到菜单栏中;
fileMenu.add(openItem); //将各条目添加到菜单中;
fileMenu.add(saveItem);
fileMenu.add(closeItem);
openDialog = new FileDialog(f,"打开",FileDialog.LOAD);//创建文件对话框;
saveDialog = new FileDialog(f,"保存",FileDialog.SAVE);
ta = new TextArea(); //创建文本域;
myEvent();
f.setMenuBar(menuBar);//在窗体中加入菜单栏;
f.add(ta); //窗体中加入文本域;
f.setVisible(true);
}
public void myEvent()
{
saveItem.addActionListener(new ActionListener() //设置菜单中保存条目所具备的功能;
{
public void actionPerformed(ActionEvent e)
{
if(file==null)//当文本域中的数据在硬盘中没有对应的文件存储时,
{ //将弹出对话框创建一个新文件来保存写入文本域中的数据;
saveDialog.setVisible(true);
String dirPath = saveDialog.getDirectory();//获取对话框中选中文件的目录;
String fileName = saveDialog.getFile(); //获取对话框中选中的文件;
if(dirPath==null || fileName==null)//当目录或者文件不存在时不做任何动作,做此动作是为了防止出现空指针异常;
return ;
file = new File(dirPath,fileName);
}
try
{ //将文本域中的内容写入到对应的文件中;
BufferedWriter bufw = new BufferedWriter(new FileWriter(file));
String text = ta.getText();
bufw.write(text);
bufw.flush();
bufw.close();
}
catch (IOException ex)
{
throw new RuntimeException("写入失败!");
}
}
});
openItem.addActionListener(new ActionListener()//设置菜单中打开条目所具备的功能;
{
public void actionPerformed(ActionEvent e)
{
openDialog.setVisible(true);
String dirPath = openDialog.getDirectory();
String fileName = openDialog.getFile();
//System.out.println(dirPath+"...."+fileName);
if(dirPath==null || fileName==null)
return ;
ta.setText(""); //在对话框选中的文件时有效文件之前,清空文本域中的内容;
file = new File(dirPath,fileName);
try
{
BufferedReader bufr = new BufferedReader(new FileReader(file));
String line = null;
while((line=bufr.readLine()) != null)
{
ta.append(line+"\r\n");//将选中文件中的内容添加到文本域中;
}
bufr.close();
}
catch (IOException ex)
{
throw new RuntimeException("读取失败!");
}
}
});
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 MenuDemo();
}
}
7、jar包双击执行
以上面的MenuDemo.class为例。该文件的源文件存放在F:\Java test\day22目录中,我们使用命令提示符进入到该盘符,输入命令:javac –d d:\test MenuDemo.java。将其生产的.class文件打包存放在D:\test文件夹中,其文件夹名称为mymenu。然后在该目录下新建一个文本文档并输入如下字符:Main-Class: mymenu.MenuDemo,单击回车,保存命名为1.txt(一定要按照以上格式,不然编译可能出错)。再将命令提示符切换到d:\test,输入命令:jar –cvfm menu.jar mymenu,将文件夹mymenu打包成.jar文件。此时可以将1.txt中的命令添加到.jar文件中的MANIFEST.MF文件中。此时我们双击使用java就可以直接打开该.jar文件并执行它了。