java Gui初识
主要有两类:AWT 和Swing类库 AWT 在java.awt包,swing 在javax.swing包中
AWT是早期的,可以提供基本的gui,swing则更加全面。包括了awt中具有的所有组件。并且提供了更加丰富的功能和部件。
但swing会用到许多awt中的许知识。swing组件都以J开头.
组件:文本框,按钮,列表框,对话框等。我们称之为gui组件。java都提供了对应的java组件类。这些组件类都是
java.awt.Component的直接或间接子类。
对于众多的gui组件,根据其作用分为两大类:基本组件(下面就全部简称为组件)和容器。
组件又被称为构件。在上面不能容纳其他的组件,容器其实也是一种组件,是一种比较特殊的组件,它可以用来容纳其他组件,如窗口,对话框等。所有的容器类都是java.awt.Container的直接或间接子类。container类是Component类的一个子类。由此可见容器本身也具有组件的功能和特点。也可以被当为基本组件一样使用。
java中的事件处理机制由3部分构成
1,事件(event object)
2.事件源(event source)
3.事件监听器(event listener):当事件发生时被通知到接受事件的事件监听对象,然后调用事件监听对象中对应的方法响应该事件。
有许多书将事件分为两大类:低级事件和语义事件(又叫高级事件); 很难记住哪些属于哪一类。有种
简单的方法区分,如果某个事件的监听器接口中只有一种方法法,那么这个事件就是语义事件。如
ActionListener中只有一个方法,ActionEvent就是一种语义事件。反之,则为低级事件。另外。从字面上,
我们也能理解:语义事件关心的是一个具有特殊作用的gui组件对应的动作发生了,而不关心这个动作是
怎样发生的。
对组件的响应和处理:
1)为组件注册实现规定接口的事件监听器
2)实现事件监听器接口中声明的事件处理抽象方法。
如:
JButton button=new JButton("Press");
buttton.addActionListener(new ButtonHandler());
鼠标单击,触发事件ActionEvent,将调用方法actionPerformed
Class ButtonHandler implements ActionListener{ //实现事件监听接口的类
public void actionPerformed(ActionEvent event) // 实现事件处理方法
{
、、、//事件处理代码
}
java对事件进行处理的方法是放在一个类对象中,这个类对象就是事件监听器,我们必须将一个事监听器对象同某个事件源的某种事件进行关联,这样,当这个事件源上方生了,关联的事件监听器对象中有关代码才会被执行。这个过程称为想事件源注册事件监听器对象。
从图中可以看到,事件处理器(事件监听器)首先与组件(事件源)建立关联,当组件接受外部作用(事件)时,
组件就会尝试一个相应的事件对象,并把此对象传给与之关联的事件处理器,事件处理器就是被启动并执行相关的的代码
来处理该事件
public class TestFrame {
public static void main(String[] args) {
// TODO Auto-generated method stub
Frame f=new Frame("IT jiao liu");
f.add(new Button("ok"));
f.setSize(300,300);
f.setVisible(true);
}
}
窗口不会关闭。
程序运行结束后窗口不会关闭。 main线程结束后,但程序兵马没有结束。窗口还显示在桌面上。
对java来说,只要还有一个前台线程在运行,整个进程就不会结束。这说明程序还有其他线程在运行,那么其他线程是谁创建的。
可以简单的理解,程序在产生frame对象时,创建了一个新的线程,称之为AWT线程,
在上面的程序中,可以调用Frame.dispose()方法关闭框架窗口.
java语法规定必须实现接口的所有方法。(只写自己想要实现的方法,别的方法体留空)
import java.awt.Button; import java.awt.Frame; import java.awt.Window; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; public class TestFrame { public static void main(String[] args) { // TODO Auto-generated method stub Frame f=new Frame("IT jiao liu"); f.add(new Button("ok")); f.setSize(300,300); f.setVisible(true); //f.dispose(); f.addWindowListener(new MyWindowListener()); } class MyWindowListener implements WindowListener { @Override public void windowOpened(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowClosing(WindowEvent e) { // TODO Auto-generated method stub e.getWindow().setVisible(false); ((Window)e.getComponent()).dispose(); System.exit(0); } @Override public void windowClosed(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowIconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowDeiconified(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowActivated(WindowEvent e) { // TODO Auto-generated method stub } @Override public void windowDeactivated(WindowEvent e) { // TODO Auto-generated method stub } } }
但是上面的程序会报错,No enclosing instance of type TestFrame is accessible. Must qualify the allocation with an enclosing instance of type TestFrame (e.g. x.new A() where x is an instance of TestFrame).参考下一篇文章
在class MyWindowListener 加上static;
上面用来2中方法来获取事件源对象。区别在哪里?
在上面的例子中,事件监听器的类MyWindoListener和产生gui组件的类TestFrame是两个完全分开的类,事件监听器的类中的
代码中访问其他的非事件源的gui组件,程序就得想别的办法了,如果我们想单击ok按钮来关闭框架窗口并退出程序,这要求
程序在按钮的事件监听器代码中要访问框架窗口,
事件监听器的类代码访问其它非事件源的gui组件,一个简单的方法是将事件监听器和产生gui的最近的代码放在同一个类中实现。
import java.awt.Button; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestFrame implements ActionListener { Frame f=new Frame("IT资讯交流网"); public static void main(String [] args) { TestFrame tf=new TestFrame(); tf.init(); } public void init() { Button btn=new Button("退出"); btn.addActionListener(new TestFrame()); f.add(btn); f.setSize(300,300); f.setVisible(true); } public void actionPerformed(ActionEvent e) { f.setVisible(false); f.dispose(); System.exit(0); } }
将在main 方法中调用gui初始化代码 全部放在了init方法中,在main方法中只要调用这个init方法就可以了,init是非静态的,可以直接方法非静态的成员变量。
上面的代码按button按钮不能关闭。
程序创建了2个TestFrame对象,桌面上先生的是第一个TestFrame的f对象,而退出按钮的花四溅处理代码中关闭的是第二个TestFrame中的f对象。
所以我们看到窗口没有关闭。将init方法中的btn.addActionListener(new TestFrame());改为btn.add(ActionListener(this)); 就可以了
如果一个事件监听器类只用于在一个组件上注册监听器事件对象,为了让程序代码更紧凑,我们可以用匿名内置类的语法来产生这个事件监听器对象,。
import java.awt.*; import java.awt.event.*; class TestFrame { Frame f=new Frame("IT资讯交流网"); public static void main(String [] args) { new TestFrame().init(); } public void init() { Button btn=new Button("退出"); btn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { f.setVisible(false); f.dispose(); //不要加System.exit(0);
} }); f.add(btn); f.setSize(300,300); f.setVisible(true); } }