Кнопка захвата AspectJ нажата - PullRequest
1 голос
/ 01 декабря 2011

Я хочу знать, как захватить нажатую кнопку с AspectJ и получить ее параметр (например, имя кнопки).Я думаю, что для более обобщенного захвата с AspectJ следует использовать MouseListener, чтобы он мог захватывать другие элементы пользовательского интерфейса в целом!

Пример:

В примере с графическим интерфейсомопределили 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 Ответ

1 голос
/ 01 декабря 2011

Это возможно. Я привел два примера. Первый, который распечатывается для каждого 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

Надеюсь, это поможет!

...