简体   繁体   中英

How to detect when a button has been pressed in an external Java application?

I need to integrate a custom spell-checker into an existing Java application without an Automation API .

It should work like this:

  1. In the external application A , the user opens a window, where he/she enters some text. In that window there is a button "Spellchecker".
  2. When the user presses the "Spellchecker" button, my program B should read the text from A's text field and put it into the custom spellchecker.

How can I detect that some button has been pressed in an external Java application?

Update 1: I tried to install my own AWT event listener to detect events in other applications.

    Toolkit.getDefaultToolkit().addAWTEventListener(new MyAWTEventListener(), AWTEvent.MOUSE_MOTION_EVENT_MASK);

    while (true)
    {
        Thread.sleep(1);
    }

But it doesn't work.

Update 2: Replacing the system event queue doesn't work, either.

private void queuePushingExperiment() throws InterruptedException,
        InvocationTargetException {
    EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue();

    queue.push(new MyEventQueue());

    EventQueue.invokeAndWait(new Runnable() {

        @Override
        public void run() {
            System.out.println("run");
        }
    });
}

public class MyEventQueue extends EventQueue {

    @Override
    public SecondaryLoop createSecondaryLoop() {
        System.out.println("createSecondaryLoop");
        return super.createSecondaryLoop();
    }

    @Override
    protected void dispatchEvent(AWTEvent event) {
        System.out.println("dispatchEvent");
        super.dispatchEvent(event);
    }

    @Override
    public AWTEvent getNextEvent() throws InterruptedException {
        System.out.println("getNextEvent");
        return super.getNextEvent();
    }

    @Override
    public AWTEvent peekEvent() {
        System.out.println("peekEvent");
        return super.peekEvent();
    }

    @Override
    public AWTEvent peekEvent(int id) {
        System.out.println("peekEvent");
        return super.peekEvent(id);
    }

    @Override
    protected void pop() throws EmptyStackException {
        System.out.println("pop");
        super.pop();
    }

    @Override
    public void postEvent(AWTEvent theEvent) {
        System.out.println("postEvent");
        super.postEvent(theEvent);
    }

    @Override
    public void push(EventQueue newEventQueue) {
        System.out.println("push");
        super.push(newEventQueue);
    }

}

Update 3: java.awt.Window.getOwnerlessWindows() and EventQueueMonitor.getTopLevelWindows() both return empty arrays even though there is a JFrame open at time of their invokation.

Update 4: I noticed that I can't write to the file C:\\Program Files\\Java\\jdk1.7.0_25\\jre\\lib\\accessibility.properties and currently the line assistive_technologies=com.sun.java.accessibility.AccessBridge is commented out. That may cause the aforementioned problems with the accessibility objects.

How can I achieve this? I thought that for every Java program a separate JVM is launched.

Actually java app A could be run from app B. You just call the A's main() method. So in fact you start B.main() which runs necessary B code and then calls A.main() to run A. In this case you can get started window (or frame) using Window class method.

public static Window[] getWindows()

After that just go down all the subcomponents of the found Window checking their classes and when you find JButton check the buton's text or image to find necessary instance. Then just add your listener there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM