在java编程中swing包中的组件处理事件时,swing的事件处理机制_1

  在java编程中swing包中的组件处理事件时,swing的事件处理机制

  管理监听程序列表

  如果我们正在创建自己的组件,并希望它们触发事件,我们需要维护一个要通知的侦听器列表。如果监听器列表用于AWT事件,我们可以使用AWTEventMulticaster类进行列表管理。对于Swing库,如果事件不是预定义的AWT事件类型,我们需要自己管理侦听器列表。通过使用javax.swing.event包中的EventListenerList类,我们不再需要手动管理侦听器列表,也不再需要担心线程安全。如果我们需要获取侦听器列表,我们可以通过公共事件侦听器[] getlistener (classlistener类型)或类似于JButton的getActionListeners()方法的特定于类型的方法来请求组件。这允许我们从内部管理列表中删除侦听器,从而有助于垃圾收集。

  AWTEventMulticaster类

  不管我们是否意识到,AWT组件使用AWTEventMulticaster类来管理事件侦听器列表。此类实现所有AWT事件侦听器(ActionListener、AdjustmentListener、ComponentListener、ContainerListener、FocusListener、Hierarchy BoundListener、InMethodListener、ItemListener、Key Listener、MouseMotionListener、MouseWheel Listener、TextListener、WindowFocusListener、WindowListener和WindowStatListener)。每当我们调用一个组件的方法来添加或删除一个侦听器时,AWTEventMulticaster将被用作支持。

  如果我们想创建自己的组件并管理AWT事件/侦听器对的侦听器列表,我们可以使用AWTEventMulticast。作为一个例子,让我们看看如何创建一个通用组件,当在组件内按下键时,它将生成一个ActionEvent对象。该组件使用KeyEvent的公共静态字符串getkeytext (int keycode)方法将键码转换成相应的文本字符串,并将该文本字符串作为ActionEvent的动作命令发回。因为该组件是ActionListener观察器的源,所以它需要一对add/remove方法来处理侦听器注册。这就是AWTEventMulticaster类的用处,因为它管理侦听器列表变量中侦听器的添加或删除:

  private action listener ActionListener list=null;

  public void addActionListener(ActionListener action listener){

  actionListenerList=awteventmulticaster . add(

  actionListenerList,action listener);

  public void remove action listener(action listener action listener){

  actionListenerList=awteventmulticaster . remove(

  actionListenerList,action listener);

  }

  定义的其余部分描述了如何处理内部事件。要向ActionListener发送击键,您需要注册一个内部KeyListener。此外,组件必须能够获得输入焦点;否则,所有击键都将到达其他组件。完整的类定义如清单2-4所示。用于侦听器通知的代码行以粗体显示。这一行通知所有注册的侦听器。

  /**

  包swingstudy.ch02

  导入Java . awt . awteventmulticaster;

  导入Java . awt . color;

  导入Java . awt . event . action event;

  导入Java . awt . event . action listener;

  导入Java . awt . event . key adapter;

  导入Java . awt . event . key event;

  导入Java . awt . event . key listener;

  导入Java . awt . event . mouse adapter;

  导入Java . awt . event . mouse event;

  导入Java . awt . event . mouse listener;

  导入javax . swing . jcomponent;

  * @作者联想

  公共类KeyTextComponent扩展JComponent{

  private action listener ActionListener list=null;

  public KeyTextComponent() {

  setBackground(颜色。青色);

  key listener internalKeyListener=new key adapter(){

  公共void按键(KeyEvent事件){

  if(actionListenerList!=null) {

  int key code=event . get key code();

  string keyText=event . get keyText(key code);

  ActionEvent action event=new action event(this,action event。ACTION_PERFORMED,keyText);

  actionlistenerlist . action performed(action event);

  mouse listener internalMouseListener=new mouse adapter(){

  public void mouse pressed(mouse event事件){

  requestFocusInWindow();

  addkey监听器(internalKeyListener);

  addmouse侦听器(internalMouseListener);

  public void addActionListener(action listener操作侦听器){

  action listener list=awteventmulticaster。add(actionListener列表,动作监听器);

  public void删除操作侦听器(操作侦听器操作侦听器){

  action listener list=awteventmulticaster。remove(actionListener列表,action listener);

  public boolean isFocusable() {

  返回真实的

  }

  图2-5显示所有的组件。图中上部分是组件,而下底部则是一个文本输入框。为了显示按下键的文本字符串,向更新文本框的KeyTextComponent注册了一个ActionListener

  示例源码如列表2-5所示。

  /**

  包swingstudy.ch02

  导入Java。awt。borderlayout

  导入Java。awt。事件队列;

  导入Java。awt。事件。动作事件;

  导入Java。awt。事件。动作监听器;

  导入javax。挥棒。jframe

  导入javax。挥棒。jtextfield

  * @作者联想

  公共类KeyTextTester {

  * @param args

  公共静态void main(String[] args) {

  //TODO自动生成的方法存根

  Runnable runner=new Runnable() {

  公共无效运行(){

  JFrame frame=新JFrame(关键文本示例);

  框架。setdefaultcloseoperation(JFrame .EXIT _ ON _ CLOSE);

  KeyTextComponent KeyTextComponent=new KeyTextComponent();

  final JTextField textField=new JTextField();

  操作监听器操作监听器=新操作监听器(){

  已执行公共无效操作(操作事件事件){

  string keyText=事件。getactioncommand();

  文本字段。settext(keyText);

  keytextcomponent。addactionlistener(动作监听器);

  frame.add(keyTextComponent,BorderLayout .中心);

  frame.add(textField,BorderLayout .南);

  frame.setSize(300,200);

  框架。设置可见(真);

  事件队列。稍后调用(runner);

  }

  EventListenerList类

  尽管AWTEventMulticaster类很容易使用,然而他却并不能用于管理自定义的事件监听器列表或是javax.swing.event中的摇摆事件器。我们可以创建一个这个类的自定义扩展用于处理我们需要管理的每一种类型的事件监听器列表,或者我们可以将列表存储在一个如矢量或是合框架的数据结构中。尽管使用矢量或是合框架可以工作得很好,当我们使用这种方法时,我们需要考虑同步问题。如果我们没有正确的编写列表管理,监听器通知也许会发生错误的监听器集合。

  为了简化这种情况,摇摆组件库包含了一个特殊的事件监听吕地类事件列表列表。这个类的一个实例可以管理一个组件的所有不同的事件监听器。为了演示这个类的用法,我们来看一下如何使用EventListenerList替换AWTEventMulticaster来重写前面的例子。注意,在这个特定例子中,使用AWTEventMulticaster类实际上是一种更为简单的解决方法。然而,想像一个类似的情况下,在这种情况下事件监听器并不是一个预定义的高级废水处理高次废水处理事件监听器或者是我们需要维护多个监听器列表。

  添加或是移除监听器类似于在前面的例子中AWTEventMulticaster所用的技术。我们需要创建一个合适的变量类型-这次是事件列表列表-同时定义添加与移除监听器方法。这两种方法之间的主要区别在于初始的EventListenerList并不为空,而另一个初始时则是零。首先必须创建一个到空的EventListenerList的引用。这避免了在后面多次检测空列表变量的需要。添加与移除监听器的方法也有一些不同。因为EventListenerList可以管理任意类型的监听器列表,当我们添加或是移除监听器时,我们必须提供起作用的监听器类类型。

  事件侦听器列表actionlistener list=新事件侦听器列表();

  public void addActionListener(action listener操作侦听器){

  actionListener列表添加(操作监听器。类,动作监听器);

  public void删除操作侦听器(操作侦听器操作侦听器){

  actionListener列表删除(操作侦听器。类,动作监听器);

  }

  这只留下了要处理的监听器通知。在这个类中并不存在通用方法来通知有事件发生的特定类型的监听器,所以我们必须创建我们自己的代码fireActionPerformed(actionEvent)的调用将会替代前面例子中的actionlistenerlist。执行的操作(操作事件)。这行代码会以数据形式由列表中获取一份一个特定类型的所有监听器的拷贝(以线程安全方式)。然后我们需要在这个列表中循环并通知合适的监听器。

  受保护的void fireActionPerformed(ActionEvent ActionEvent){

  EventListener listenerList[]=

  actionlistener列表获取侦听器(操作侦听器。类);

  for (int i=0,n=listenerList.length我

  新的改进类的完整代码显示在列表2-6中。当使用EventListenerList类时,不要忘记这个类位于javax.swing.event包中。除了组件类的名字,测试程序并没有改变。

  /**

  包swingstudy.ch02

  导入Java。awt。颜色;

  导入Java。awt。事件。动作事件;

  导入Java。awt。事件。动作监听器;

  导入Java。awt。事件。密钥适配器;

  导入Java。awt。事件。关键事件;

  导入Java。awt。事件。关键听众;

  导入Java。awt。事件。鼠标适配器;

  导入Java。awt。事件。鼠标事件;

  导入Java。awt。事件。鼠标监听器;

  导入Java。util。事件侦听器;

  导入javax。挥棒。jcomponent

  导入javax。挥棒。事件。事件侦听器列表;

  * @作者联想

  公共类KeyTextComponent2扩展JComponent{

  私有事件侦听器列表actionlistener list=新事件侦听器列表();

  public KeyTextComponent2() {

  设置背景(颜色。青色);

  密钥侦听器internalKeyListener=新密钥适配器(){

  公共空的按键(关键事件事件){

  if(actionListenerList!=null) {

  int键码=事件。获取键码();

  string keyText=事件。获取keyText(键码);

  ActionEvent动作事件=新动作事件(this,动作事件.ACTION_PERFORMED,keyText);

  fireActionPerformed(actionEvent);

  鼠标监听器internalMouseListener=新鼠标适配器(){

  公共void鼠标被按下(鼠标事件事件){

  requestFocusInWindow();

  addkey监听器(internalKeyListener);

  addmouse侦听器(internalMouseListener);

  public void addActionListener(action listener操作侦听器){

  actionListener列表添加(操作监听器。类,动作监听器);

  public void删除操作侦听器(操作侦听器操作侦听器){

  actionListener列表删除(操作侦听器。类,动作监听器);

  public void fireActionPerformed(操作事件事件){

  事件侦听器[]侦听器列表=actionlistener列表。获取侦听器(操作侦听器。类);

  for(int i=0,n=listener list . length ipublic boolean is focusable(){

  返回真实的

  }

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: