How to determine when a button is pressed in an external Java application?

I need to integrate custom spellchecking into an existing Java application without the Automation API .

It should work as follows:

  • In external application A user opens a window in which he enters some text. This window has a button "Spell Check".
  • When the user clicks the Spell Check button, my program B should read the text from the text box and put it in the custom spelling case.

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

Update 1: I tried installing 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 that will not work.

Update 2: Replacing the system event queue also does not work.

 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() return empty arrays even if a JFrame is open during their JFrame .

Update 4: I noticed that I cannot write 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 commented out . This can cause the above problems with accessibility objects.

+6
source share
1 answer

How can i achieve this? I thought a separate JVM was launched for each Java program.

In fact, the java application A can be launched from application B. You simply call the A main () method. So you actually run B.main (), which runs the necessary code B, and then calls A.main () to run A. In this case, you can run the window (or frame) using the Window class method.

 public static Window[] getWindows() 

After that, just omit all the subcomponents of the found window, checking their classes, and when you find JButton , check the text or image of the bud to find the desired instance. Then just add your listener.

+4
source

Source: https://habr.com/ru/post/947710/


All Articles