Swing是目前Java中不可缺少的窗口工具组是用户建立图形化用户界面(GUI)程序的强大工具Java Swing组件自动产生各种事件来响应用户行为如当用户点击按钮或选择菜单项目时Swing组件会产生一个ActionEventSwing组件会产生许多事件如ActionEventsChangeEventsItemEvents等来响应用户的鼠标点击行为列表框中值的改变计时器的开始计时等行为在Java Swing编程中通过注册监听器我们可以监听事件源产生的事件从而在事件处理程序中处理我们所需要处理的用户行为
Java Swing中处理各组件事件的一般步骤是
. 新建一个组件(如JButton)
. 将该组件添加到相应的面板(如JPanel)
. 注册监听器以监听事件源产生的事件(如通过ActionListener来响应用户点击按钮)
. 定义处理事件的方法(如在ActionListener中的actionPerformed中定义相应方法)
以上步骤我们可以用多种方法实现但人们通常用二种方法第一种方法是只利用一个监听器以及多个if语句来决定是哪个组件产生的事件第二种方法是使用多个内部类来响应不同组件产生的各种事件其具体实现又分两种方式一种是匿名内部类一种是一般内部类
为了说明如何使用上述三种方法实现事件的处理方法我们建立一个简单的应用程序该程序界面有两个按钮当用户点击相应的按钮就会弹出一个对话框显示相应的内容通过这个简单程序你可以实现自己更多更复杂的用户界面程序
首先我们利用单个监听器来实现该程序我们定义一个名为Simple的类来包括所有代码所有的用户行为(如点击按钮)由一个监听器SimpleListenner中的actionPerformed方法来处理以下是代码
/*
* Simplejava 处理事件的第一种方法
* 在这个例子中利用一个ActionListener来监听事件源产生的事件
* 用一些if语句来决定是哪个事件源
*/
import javaawt*;
import javaawtevent*;
import javaxswing*;
public class Simple
{
private static JFrame frame; // 定义为静态变量以便main使用
private static JPanel myPanel; // 该面板用来放置按钮组件
private JButton button; // 这里定义按钮组件
private JButton button; // 以便让ActionListener使用
public Simple() // 构造器 建立图形界面
{
// 新建面板
myPanel = new JPanel();
// 新建按钮
button = new JButton(按钮); // 新建按钮
button = new JButton(按钮);
SimpleListener ourListener = new SimpleListener();
// 建立一个actionlistener让两个按钮共享
buttonaddActionListener(ourListener);
buttonaddActionListener(ourListener);
myPaneladd(button); // 添加按钮到面板
myPaneladd(button);
}
private class SimpleListener implements ActionListener
{
/*
* 利用该内部类来监听所有事件源产生的事件
* 便于处理事件代码模块化
*/
public void actionPerformed(ActionEvent e)
{
// 利用getActionCommand获得按钮名称
// 也可以利用getSource()来实现
// if (egetSource() ==button)
String buttonName = egetActionCommand();
if (buttonNameequals(按钮))
JOptionPaneshowMessageDialog(frame
按钮 被点击);
else if (buttonNameequals(按钮))
JOptionPaneshowMessageDialog(frame
按钮 被点击);
else
JOptionPaneshowMessageDialog(frame
Unknown event );
}
}
public static void main(String s[])
{
Simple gui = new Simple(); // 新建Simple组件
frame = new JFrame(Simple); // 新建JFrame
// 处理关闭事件的通常方法
frameaddWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{Systemexit();} });
framegetContentPane()add(myPanel);
framepack();
framesetVisible(true);
}
}
让我们来看看以上代码是如何工作的在main方法中我们定义了一个JFrame然后将面板Jpanel添加到窗体中该面板包括两个按钮相应的变量Framebuttonbutton定义在程序的开头部分
在程序入口main方法中首先新建Simple组件通过构造器建立用户GUI定义一个面板Jpanle增加两个按钮然后利用JButtonaddActionListerner将两个按钮加入到一个活动监听器SimpleLister中最后两个按钮添加到面板当GUI建立后我们将面板添加到窗体并显示结果当用户点击按钮时程序调用actionPerformed方法通过if语句来判断是哪一个按钮被点击然后在对话框中显示相应的内容
利用一个监听器来处理事件的缺点是当程序比较复杂时需要一大串的if 语句来实现程序代码较难阅读与维护当然如果处理的事件较少这种方式比较简单
通过使用匿名内部类可以解决上述存在的问题使用简单的匿名内部类作为addActionListener的变量即可以下是实现代码
/*
* Simplejava 处理事件的第二种方法
* 在这个例子中利用匿名内部类来监听每一个事件源产生的事件
* 避免使用一些if语句来决定是哪个事件源
*/
import javaawt*;
import javaawtevent*;
import javaxswing*;
public class Simple
{
private static JFrame frame; // 定义为静态变量以便main使用
private static JPanel myPanel; // 该面板用来放置按钮组件
private JButton button; // 这里定义按钮组件
private JButton button; // 以便让ActionListener使用
public Simple() // 构造器 建立图形界面
{
// 新建面板
myPanel = new JPanel();
// 新建按钮
button = new JButton(按钮); // 新建按钮
button = new JButton(按钮);
// 每一个事件源需要一个监听器
// 定义一个匿名内部类来监听事件源产生的事件
buttonaddActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JOptionPaneshowMessageDialog(frame
按钮 被点击);
}
}
);
buttonaddActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
JOptionPaneshowMessageDialog(frame
按钮 被点击);
}
}
);
myPaneladd(button); // 添加按钮到面板
myPaneladd(button);
}
public static void main(String s[])
{
Simple gui = new Simple(); // 新建Simple组件
frame = new JFrame(Simple); // 新建JFrame
// 处理关闭事件的通常方法
frameaddWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{Systemexit();} });
framegetContentPane()add(myPanel);
framepack();
framesetVisible(true);
}
}
使用匿名内部类同样存在许多另外的问题首先根据组件在代码中被定义的不同位置类的定义以及处理事件的代码将分散在程序的各个部分不是集中在一块同样不便于阅读与维护各事件的处理全部由嵌套的程序块组成视觉上很难定位程序代码如果事件处理程序比较复杂内部类中的代码将变得很长你将找不到相应的组件定义位置最后当工具栏菜单栏目等需要处理同样的用户行为时该方法将使代码更难维护
我们使用一般的命名内部类可以解决以上许多问题所有的事件处理方法都集中在一块并且都具有有意义的名称程序非常容易阅读与维护单个的事件处理程序也可以被工具栏菜单栏等重复使用
以下是实现代码
/*
* Simplejava 处理事件的第三种方法
* For this example we will use inner member classes to
* 在这个例子中利用一般内部类来监听每个事件源产生的事件
* 该方法避免了第二种方法中由于使用匿名内部类而导致的代码混乱
* 便于集中处理事件代码
* 每一个Hander可以被工具栏或菜单多次使用
*/
import javaawt*;
import javaawtevent*;
import javaxswing*;
public class Simple
{
private static JFrame frame; // 定义为静态变量以便main使用
private static JPanel myPanel; // 该面板用来放置按钮组件
private JButton button; // 这里定义按钮组件
p