(96)GUI:鼠标事件、键盘事件、按钮事件、窗体事件
布局管理器:
容器中的组件的排放发生,就是布局。
常见而定布局管理器:
BorderLayout:若没有指定方向,则填充整个容器
创建图形化界面步骤:
1,创建frame窗体
2,对窗体进行基本设置,比如大小、位置、布局
3,定义组件
4,将组件通过窗体的add方法添加到窗体中
5,让窗体显示,同过setVisible(true)
事件监听机制:
特点:事件源、事件、监听器、事件处理
事件源:就是awt包或者swing包中的那些图形界面组件
事件:每一个事件源都有自己特有的而对应事件和共性事件
监听器:将可以触发某个事件的动作(不止一个)都已经封装到了监听器中。
以上三者,在java中都已经定义好了。编程人员可做的就是对产生的动作进行处理。
①Window类中public void addWindowListener(WindowListener l):添加指定的窗口监听器,以从此窗口接收窗口事件(为窗体注册监听器)。
②WindowListener:接口,内部有六个抽象方法(接口中全是抽象方法,不用显式写)。
但是平时程序开发并不需要将这六个全部实现,可以在“所有已实现的接口”类中寻找实现的子类 WindowAdapter(在Java.awt.event包中)。
③WindowAdapter:它实现了其父类的6个方法,但是其方法内部为空{},因为其方法的方法体全为空,所以创建对象没有意义,所以定义成了抽象类,该类的作用,就是让其他类继承该类。
import java.awt.*;
public class demo {
public static void main(String[] args) {
Frame f=new Frame("my awt");
f.setSize(500, 400);
f.setLocation(300, 200);
f.setLayout(new FlowLayout());
Button b=new Button("我是按钮");
f.add(b);//将按钮和窗体相结合
f.addWindowListener(new MyListener());//窗体注册监听器
f.setVisible(true);
}
}
import java.awt.event.*;
public class MyListener extends WindowAdapter {
public void windowClosing(WindowEvent e) {
System.out.println("我关");
System.exit(0);
}
public void windowActivated(WindowEvent e) {
System.out.println("我活了哈哈");//窗体前置
}
public void windowOpened(WindowEvent e) {
System.out.println("我被打开了");
}
}
若只是实现一个方法,就创建一个类,比较麻烦,可以写匿名内部类
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("我关");
System.exit(0);
}
});
其实在实际开发中,要将要做的窗体以及里面的控件等封装成类,在main中只做测试
import java.awt.*;
import java.awt.event.*;
public class FrameDemo {
//定义该图形中所需要的组件的引用
private Frame f;
private Button but;
FrameDemo(){
init();
}
public void init() {
f=new Frame("my frame");
//对frame进行基本设置
f.setBounds(300, 100, 600, 500);
f.setLayout(new FlowLayout());
but=new Button("我的按钮");
//将组件添加到frame中
f.add(but);
//加载一下窗体事件
myEvent();
//显示窗体
f.setVisible(true);
}
public void myEvent() {
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.out.println("我关");
System.exit(0);
}
});
}
}
按钮事件
需求:让按钮具备退出程序的功能
按钮是事件源,应该选择哪个监听器呢?
通过关闭窗体示例了解到,想要知道哪个组件具备什么样的特有监听器,需要查看该组件对象的功能。通过查阅Button的描述,发现按钮支持一个特有监听public void addActionListener(ActionListener l)
ActionListener:是个接口,内部只含一个方法:void actionPerformed(ActionEvent e)
but.addActionListener(new ActionListener()//只要是点击按钮就能触发该事件
{
public void actionPerformed(ActionEvent e) {
System.out.println("action OK");
}
});
鼠标事件是所有组件的共性事件,所以它定义在Component中:public void addMouseListener(MouseListener l)
MouseListener是个接口,因为其方法较多,所以有适配器MouseAdapter,创建匿名内部类方便
but.addMouseListener(new MouseAdapter() {
private int count=1;
private int clickCount=1;
public void mouseEntered(MouseEvent e) {
System.out.println("鼠标进入组件(按钮)"+count++);
}
public void mouseClicked(MouseEvent e) {
if(e.getClickCount()==2)
System.out.println("点击动作"+clickCount);
}
});
↑ 鼠标双击事件:属于鼠标事件,只是鼠标两次点击触发的事件,在MouseEvent类中有方法:public int getClickCount()返回与事件关联的鼠标单击次数【这个次数是在两次时间间隔很短的情况下发生的才会获取为2次,时间长则为1次】
键盘事件
char getKeyChar( ):返回与此事件中的键关联的字符
int getKeyCode( );返回与此事件有关的整数keyCode
该类中提供了常量字段,方便操作键盘,比如KeyEvent.VK_ENTER就是enter的整数值,不用再通过getKeyCode获取了。
1)需求:按键盘enter实现窗体退出
but.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if((e.getKeyCode()==KeyEvent.VK_ENTER))
System.exit(0);
}
});
2)需求:通过按ctrl+enter来退出窗体
在Java.awt.event.InputtEvent中有方法:public boolean isControlDown():判断ctrl是否按下。
因为KeyEvent继承了InputtEvent,所以KeyEvent可以直接用这个方法(keyevent并没有进行覆盖操作)
but.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if(e.isControlDown()&&(e.getKeyCode()==KeyEvent.VK_ENTER))
System.exit(0);
}
});
}
3)需求:向文本框中输入0-9,其他输入都非法,不会输入到文本框中
InputEvent类中public void consume()使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理此事件。
(比如文本框监听键盘按下,默认输入到文本框,非法字符不输入到文本框中(非默认方式consume))
private TextField tf;
f.add(tf);
tf.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
int code=e.getKeyCode();
if(code>=KeyEvent.VK_0&&code<=KeyEvent.VK_9)
e.consume();
}
});