Это возможно. Я привел два примера. Первый, который распечатывается для каждого 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..
}
ОБНОВЛЕНИЕ:
Вы можете сделать это разными способами. Например, добавьте свои кнопки непосредственно в аспект. Но я предпочитаю использовать объект enum между (в данном случае ButtonManager), поэтому код не знает об аспекте. А поскольку ButtonManager является объектом enum, аспект легко получает значения из него.
Я только что протестировал его с классом кнопок Swing от Oracle, и он работает. В классе 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;
}
}
Изменен pointcut и совет только печатать названия кнопок, зарегистрированных в 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
Хорошо, я верю, что понимаю, чего вы хотите. Вы хотите слушать события мыши. Это возможно Недостатком является то, что вы должны зарегистрировать все ваши компоненты графического интерфейса, которые вы хотите прослушивать щелчки, с помощью прослушивателя мыши. Недостаточно зарегистрировать JPanel JFrame с помощью MouseListener. Поэтому, если вы зарегистрировали ActionListener только для своих кнопок, вам также нужно добавить прослушиватель мыши.
Я создал быстрое решение, которое работает для меня. Это только показывает, что это работает. Я не пытался сделать решение универсальным для множества различных объектов GUI. Но это должно быть довольно легко изменить, если у вас есть основы для работы.
В классе Swing:
private class MouseListener extends MouseInputAdapter {
public void mouseClicked(MouseEvent e) {}
}
В методе init класса Swing:
MouseListener myListener = new MouseListener();
btn1.addMouseListener(myListener);
btn2.addMouseListener(myListener);
В классе Аспект:
@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 -> mouseClicked: Test1
Надеюсь, это поможет!