Want javax.swing hook that tells me WHICH component in the hierarchy is executing an action

ぐ巨炮叔叔 提交于 2019-12-04 17:59:48

Put in a custom event dispatcher: http://tips4java.wordpress.com/2009/09/06/global-event-dispatching/

Also look up AWTEvent.getID(), MouseEvent, KeyEvent in the API docs.

This is how the software I work on monitors mouse and keyboard to see if the user is busy working, and locks the window if they're not.

Using AspectJ to weave a logging aspect into your code base can be done. Below is an example of advice on a joinpoint within execution of any objects with the method actionPerformed(ActionEvent) you have in your code base. Similar constructions can be used to advise other Listeners.

Below is the aspect to advise button presses and other components having ActionListeners. It simply outputs the class name of the source of the action and the signature of the actionPerformed method.

import java.awt.event.ActionEvent;

import org.aspectj.lang.Signature;

public aspect Logger {
  before(ActionEvent e) : execution(* *.actionPerformed(ActionEvent)) && args(e) {
    Signature sig = thisJoinPoint.getSignature();
    System.out.println(e.getSource().getClass() + " lead to " + sig);
  }
}

A test class which produces two buttons of different classes (in file StackTraceExample.java):

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

class MyButton extends JButton {
  public MyButton(String string) {
    super(string);
  }
}

class MyOtherButton extends JButton {
  public MyOtherButton(String string) {
    super(string);
  }
}

class ButtonStackDisplay implements ActionListener {
  private final JTextArea stackTraceText;

  ButtonStackDisplay(JTextArea textArea) {
    this.stackTraceText = textArea;
  }

  public void actionPerformed(ActionEvent e) {
    String endl = System.getProperty("line.separator");
    StringBuilder b = new StringBuilder();

    // you can see the source of the event 
    b.append(e.getSource()).append(endl).append(endl);

    // the stack trace shows that events don't propagate through the components
    // originating them, but instead processed in a different thread
    for (StackTraceElement se : new Throwable().getStackTrace()) {
      b.append(se.toString());
      b.append(endl);
    }
    stackTraceText.setText(b.toString());
  }
}

public class StackTraceExample {
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        f.setLayout(new BorderLayout());
        JPanel top = new JPanel();
        JButton button = new MyButton("Stack Trace");
        top.setLayout(new GridLayout(2, 1));
        top.add(button);
        JButton otherButton = new MyOtherButton("Stack Trace");
        top.add(otherButton);
        f.getContentPane().add(top, BorderLayout.NORTH);
        JTextArea stackTraceText = new JTextArea();
        f.add(stackTraceText, BorderLayout.CENTER);
        ButtonStackDisplay bsd = new ButtonStackDisplay(stackTraceText);
        button.addActionListener(bsd);
        otherButton.addActionListener(bsd);
        f.setSize(400, 400);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        f.toFront();
      }
    });
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!