单击AspectJ捕获按钮

时间:2011-12-01 11:33:06

标签: button aspectj capture click

我想知道如何捕获用AspectJ单击的按钮并获取其参数(例如按钮名称)。我认为对于使用AspectJ进行更广泛的捕获,它可以使用MouseListener,因此它可以捕获其他UI元素!

示例:

在GUI示例中,我定义了2个按钮,这些按钮采取了一些操作

public JButton btn1 = new JButton("Test1");
public JButton btn2 = new JButton("Test2");

btn1.addActionListener(new ActionListener()
        {
             public void actionPerformed(ActionEvent e)
             {
                        //take some actions
                     } 
                }

btn2.addActionListener(new ActionListener()
        {
             public void actionPerformed(ActionEvent e)
             {
                        //take some actions
                     } 
            }

如何使用AspectJ捕获这些按钮,并获取它们的参数(例如名称)?

1 个答案:

答案 0 :(得分:1)

有可能。我提供了两个例子。第一个打印出来的每个JButton都有ActionListener。另一个示例仅在单击特定按钮时打印出来。

打印使用JButton点击的每个ActionListener的文字:

@Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent)")
public void buttonPointcut(ActionEvent actionEvent) {}

@Before("buttonPointcut(actionEvent)")
public void beforeButtonPointcut(ActionEvent actionEvent) {
   if (actionEvent.getSource() instanceof JButton) {
      JButton clickedButton = (JButton) actionEvent.getSource();
      System.out.println("Button name: " + clickedButton.getText());
   }
}

打印特定JButton的文本:

public static JButton j1;

@Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent) && if()")
public static boolean button1Pointcut(ActionEvent actionEvent) {
    return (actionEvent.getSource() == j1);
}

@Before("button1Pointcut(actionEvent)")
public void beforeButton1Pointcut(ActionEvent actionEvent) {
    // logic before the actionPerformed() method is executed for the j1 button..
}

<强>更新:

您可以通过多种不同方式完成此操作。例如,直接将按钮添加到方面。但我更喜欢在(在这种情况下为ButtonManager)之间使用枚举对象,因此代码不了解方面。由于ButtonManager是一个枚举对象,因此方面很容易从中检索值。

我刚刚使用Oracle的Swing按钮类进行了测试,它确实有效。在Swing类中:

b1 = new JButton("Disable middle button", leftButtonIcon);
ButtonManager.addJButton(b1);

AspectJ在操作类时非常强大,但它无法将建议编织到特定对象中,因为在编织时不会创建对象。所以你只能在运行时使用对象,这就是为什么我在上面添加了addJButton(..)方法。这使得方面可以根据已注册按钮列表检查建议按钮。

ButtonManager类:

public enum ButtonManager {

    ;

    private static Collection<JButton> buttonList = new LinkedList<JButton>();

    public static void addJButton(JButton jButton) {
        buttonList.add(jButton);
    }

    public static Collection<JButton> getButtonList() {
        return buttonList;
    }
}

修改了切入点和建议,仅打印ButtonManager中注册的按钮的名称:

@Pointcut("execution(* *.actionPerformed(*)) && args(actionEvent) && if()")
public static boolean buttonListPointcut(ActionEvent actionEvent) {
    Collection<JButton> buttonList = ButtonManager.getButtonList();
    JButton registeredButton = null;
    for (JButton jButton : buttonList) {
        if (actionEvent.getSource() == jButton) {
            registeredButton = jButton;
        }           
    }
    return registeredButton != null;
}

@Before("buttonListPointcut(actionEvent)")
public void beforeButtonListPointcut(ActionEvent actionEvent) {
    JButton clickedButton = (JButton) actionEvent.getSource();
    System.out.println("Registered button name: " + clickedButton.getText());
}

更新2

好的,我相信我明白你想要的。你想听老鼠事件。这是可能的。缺点是您必须使用鼠标监听器注册要监听点击的所有GUI组件。使用MouseListener注册JFrame的JPanel是不够的。因此,如果您只为按钮注册了ActionListener,则还必须添加鼠标侦听器。

我已经创建了一个适合我的快速解决方案。它只表明它有效。我没有尝试使用许多不同的GUI对象使解决方案通用。但是当你掌握基础知识时,这应该很容易重构。

在Swing课程中:

private class MouseListener extends MouseInputAdapter {
        public void mouseClicked(MouseEvent e) {}
}

在Swing类的init方法中:

MouseListener myListener = new MouseListener();

btn1.addMouseListener(myListener);
btn2.addMouseListener(myListener);

在Aspect类中:

@Pointcut("execution(* *.mouseClicked(*)) && args(mouseEvent)")
public void mouseEventPointcut(MouseEvent mouseEvent) {}

@Before("mouseEventPointcut(mouseEvent)")
public void beforeMouseEventPointcut(MouseEvent mouseEvent) {   
   if (mouseEvent.getSource() instanceof JButton) {
      JButton clickedButton = (JButton) mouseEvent.getSource();
      System.out.println("aspectJ --> mouseClicked: " + clickedButton.getText());
   }
} 

这会在控制台中产生以下输出:

  

aspectJ - &gt; mouseClicked:Test1

我希望它有所帮助!