我想知道如何捕获用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捕获这些按钮,并获取它们的参数(例如名称)?
答案 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
我希望它有所帮助!