概念
GUI(图形用户界面)
Graphical User Interface(图形用户接口)。用图形的方式,来显示计算机操作的界面,这样更方便更直观。
Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。
Awt与 Swing
java.Awt:Abstract Window ToolKit (抽象窗口工具包),需要调用本地系统方法实现功能。属重量级控件。
javax.Swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由Java实现。增强了移植性,属轻量级控件。
下图是Awt包中类的继承关系图
Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。
容器中的组件的排放方式,就是布局。
常见的布局管理器:
FlowLayout(流式布局管理器)
从左到右的顺序排列。
Panel默认的布局管理器。
BorderLayout(边界布局管理器)
东,南,西,北,中
Frame默认的布局管理器。
GridLayout(网格布局管理器)
规则的矩阵
CardLayout(卡片布局管理器)
选项卡
GridBagLayout(网格包布局管理器)
非规则的矩阵
Container常用子类:Window Panel(面板,不能单独存在。)
Window常用子类:Frame Dialog
简单的窗体创建过程:
Frame f = new Frame(“my window”);
f.setLayout(new FlowLayout());
f.setSize(500,400);//设置窗体大小
f.setLocation(300,200);//设置窗体出现在屏幕的位置
f.setVisible(true);
事件监听机制
事件监听机制流程图
确定事件源(容器或组件)
通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上。
该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
一般用匿名内部类来表示。
在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。
事件触发后会把事件打包成对象传递给该变量。(其中包括事件源对象。通过getSource()或者,getComponent()获取。)
监听机制的特点
1、事件源
2、事件
3、监听器
4、事件处理
事件源:就是Awt或者Swing包中的那些图形界面组件
事件:每一个事件源都有自己的特有对应时间和共性时间
监听器:可以触发某一动作(不只一个动作)都已经封装到监听器中
以上三者都已经定义好了,直接获取其对象来用就可以了
我们要做的事情是对产生的动作进行处理
窗体事件
public void addWindowListener(WindowListener l)
添加指定的窗口侦听器,以从此窗口接收窗口事件。如果 l 为 null,则不抛出任何异常,且不执行任何操作。
public abstract class WindowAdapter extends Object
implements WindowListener, WindowStateListener, WindowFocusListener
接收窗口事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
代码示例:点击右上角关闭图标关闭窗体
public class AwtDemo {
public static void main(String[] args) {
Frame f = new Frame("my awt");
f.setLayout(new FlowLayout());
f.setSize(300, 200);
f.setLocation(500, 200);
f.setVisible(true);
TextField tx = new TextField();
f.add(tx);
Button b = new Button();
f.add(b);
//点击右上角关闭图标关闭窗体
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("我关");
System.exit(0);
}
});
}
}
Action事件
public void addActionListener(ActionListener l)添加指定的动作侦听器,以接收发自此按钮的动作事件。当用户在此按钮上按下或释放鼠标时,发生动作事件。如果 l 为 null,则不抛出任何异常,也不执行任何动作。
代码示例:点击按钮或当焦点在按钮上时候按空格关闭窗体
public class FrameDemo {
private Frame frame;
private Button but;
public FrameDemo() {
init();
}
private void init() {
frame = new Frame();
but = new Button("My Button");
frame.setBounds(500, 200, 300, 200);
frame.setLayout(new FlowLayout());
frame.add(but);
myEvent();
frame.setVisible(true);
}
private void myEvent() {
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("我关");
System.exit(0);
}
});
but.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按钮关的");
System.exit(0);
}
});
}
public static void main(String[] args) {
new FrameDemo();
}
}
鼠标事件
public interface MouseListenerextends EventListener
用于接收组件上“感兴趣”的鼠标事件(按下、释放、单击、进入或离开)的侦听器接口。(要跟踪鼠标移动和鼠标拖动,请使用 MouseMotionListener。)
旨在处理鼠标事件的类要么实现此接口(及其包含的所有方法),要么扩展抽象类 MouseAdapter(仅重写所需的方法)。
public abstract class MouseAdapter
extends Object
implements MouseListener, MouseWheelListener, MouseMotionListener
接收鼠标事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
鼠标事件使用户能够跟踪鼠标何时被按下、释放、单击、移动、拖动、何时进入一个组件、何时退出、何时滚动鼠标滚轮。
键盘事件
public interface KeyListenerextends EventListener
用于接收键盘事件(击键)的侦听器接口。旨在处理键盘事件的类要么实现此接口(及其包含的所有方法),要么扩展抽象 KeyAdapter 类(仅重写有用的方法)。
public abstract class KeyAdapter
extends Object
implements KeyListener
接收键盘事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
public class KeyEvent
extends InputEvent
表示组件中发生键击的事件。
当按下、释放或键入某个键时,组件对象(如文本字段)将生成此低级别事件。该事件被传递给每一个 KeyListener 或 KeyAdapter 对象,这些对象使用组件的 addKeyListener 方法注册,以接收此类事件。(KeyAdapter 对象实现 KeyListener 接口。)发生事件时,所有此类侦听器对象都将获得此 KeyEvent。
代码示例:监听鼠标和键盘
public class MouseAndKeyDemo {
private Frame frame;
private Button but;
private TextField tx;
public MouseAndKeyDemo() {
init();
}
private void init() {
frame = new Frame();
but = new Button("My Button");
tx = new TextField(20);
frame.setBounds(500, 200, 300, 200);
frame.setLayout(new FlowLayout());
frame.add(tx);
frame.add(but);
myEvent();
frame.setVisible(true);
}
private void myEvent() {
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("我关");
System.exit(0);
}
});
but.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
System.out.println("鼠标进入");
}
public void mouseExited(MouseEvent e) {
System.out.println("鼠标离开");
}
// 优先于ActionListener执行,因为他行为更具体
public void mouseClicked(MouseEvent e) {
System.out.println(e.getClickCount());
if (e.getClickCount() == 2) {
System.out.println("鼠标双击");
}
System.out.println("鼠标单击");
}
});
but.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
// 按shift键
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
System.exit(0);
}
// 同时按住ctrl和回车键
if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER) {
System.exit(0);
}
System.out.println(KeyEvent.getKeyText(e.getKeyCode()) + "..." + e.getKeyCode());
}
});
tx.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (!(e.getKeyCode() > KeyEvent.VK_0 && e.getKeyCode() < KeyEvent.VK_9)) {
System.out.println(KeyEvent.getKeyText(e.getKeyCode()) + "是非法的字符");
}
}
});
}
public static void main(String[] args) {
new MouseAndKeyDemo();
}
}
菜单继承体系
MenuBar,Menu,MenuItem
先创建菜单条,再创建菜单,每一个菜单中建立菜单项。
也可以菜单添加到菜单中,作为子菜单。
通过setMenuBar()方法,将菜单添加到Frame中。
代码示例:模拟记事本
public class MyMenuDemo {
private Frame frame;
private MenuBar bar;
private Menu fileMenu;
private MenuItem openMenu, saveMenu, closeMenu;
private TextArea textArea;
private File file;
private FileDialog fileDialog;
private FileDialog saveDialog;
MyMenuDemo() {
init();
}
public void init() {
frame = new Frame();
frame.setBounds(300, 100, 750, 600);
bar = new MenuBar();
fileMenu = new Menu("文件");
openMenu = new MenuItem("打开");
saveMenu = new MenuItem("保存");
closeMenu = new MenuItem("退出");
textArea = new TextArea();
// 文件对话框
fileDialog = new FileDialog(frame, "浏览文件", FileDialog.LOAD);
fileDialog.setBounds(700, 300, 200, 150);
saveDialog = new FileDialog(frame, "保存文件", FileDialog.SAVE);
saveDialog.setBounds(700, 300, 200, 150);
frame.setMenuBar(bar);
frame.add(textArea);
bar.add(fileMenu);
fileMenu.add(openMenu);
fileMenu.add(saveMenu);
fileMenu.add(closeMenu);
myEvent();
frame.setVisible(true);
}
public void myEvent() {
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("窗口关的");
System.exit(0);
}
});
closeMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("菜单关的");
System.exit(0);
}
});
openMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fileDialog.setVisible(true);
String dirPath = fileDialog.getDirectory();
String fileName = fileDialog.getFile();
if (dirPath == null || fileName == null) {
return;
}
textArea.setText("");
file = new File(dirPath, fileName);
try {
BufferedReader buf = new BufferedReader(new FileReader(file));
while ((buf.readLine()) != null) {
textArea.append(buf.readLine() + "\r\n");
}
buf.close();
} catch (Exception e2) {
throw new RuntimeException();
}
}
});
// 按保存按钮保存
saveMenu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
saveFile();
}
});
//按CTRL+S保存
textArea.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_S) {
saveFile();
}
}
});
}
// 抽取保存文件的方法
public void saveFile() {
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 bfw = new BufferedWriter(new FileWriter(file));
bfw.write(textArea.getText());
bfw.close();
} catch (Exception e2) {
throw new RuntimeException();
}
}
public static void main(String[] args) {
new MyMenuDemo();
}
}