Swing: How to create Events and dispatch them to a component?

17,170

Solution 1

The obvious thing to do is get the EventQueue and post events to it. That would just add the event to the queue which will get dispatched in its turn on the EDT.

java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(event);

Someone claimed yesterday the Opera and Safari do their own thing and don't give the required permission to untrusted code.

A direct way to do it is to call Component.dispatchEvent.

Solution 2

If you're looking for standard GUI events, then you want java.awt.Robot

If you're looking to define your own events, you're going to have to subclass the GUI classes that need to receive those events (or better, create an external controller for them), define an event class, and dispatch the events. You can use java.beans.EventHandler to dispatch, create your own handler class (I've found that more useful on occasions), or inject your events (depending on how they inherit) into the system event queue (can't find the class to do that ... I thought it was Toolkit).

However, I would do none of these. What you describe (a macro recorder) should be implemented using a controller that generates/is fed a series of application-specific action messages (look at the Command pattern).

Solution 3

I believe that you have to construct an instance of the event and then call

java.awt.EventQueue.dispatchEvent(event)

Set the source of the event to the desired component.

Share:
17,170
Ayman
Author by

Ayman

Creator of JSyntaxPane. Working as Consultant and coding for fun.

Updated on June 19, 2022

Comments

  • Ayman
    Ayman almost 2 years

    I need to send some events to a component in Swing, so it is handled just like any user generated, standard Swing events.

    Basically, something like a macro recorder, and then executor for JEditorPane. But I need more control over the generated events.

    SO, assume I have an editor, I want to:

    1. capture all events sent to it, and at that point, i can store them in list, on disk, or whatver..
    2. Be able to later play those events
    3. Ideal situation, is to allow user to edit a commands which contains things like:
      "type key A, select line, delete-selection, cursor-up, line-start..."
  • Brett
    Brett about 15 years
    EventQueue.dispatchEvent is a protected instance method. You'd have to get the current event queue and push a subclass to use that method.
  • palantus
    palantus about 15 years
    How about postEvent() instead?
  • kdgregory
    kdgregory about 15 years
    Without knowing exactly what you want to do, it's hard to give concrete advice. However, consider that a JEditorPane uses a javax.swing.text.Document to manage its contents, and you can attach a DocumentListener to receive all changes to this document. If you save that listener's events in a List, then you can replay that list at any time and apply the changes -- or undo them.
  • Ayman
    Ayman about 15 years
    For now at least, I'd like a simple yet programmable way of recording and replaying macros on an Editor. The problem with attaching to the Document is that Caret movement will not be sent to the Document. So I'll need to hookup to the events received / processed by the GUI Component. Actions seem like a great fit, bu I need a way of hooking up to see the actions sent (to record) and then a way of injecting the recorded / processed Actions back to the component. MAny thanks.
  • Dan
    Dan over 13 years
    I've been tracing code that uses 'Component.dispatchEvent' and if I'm not mistaking, this will actually invoke the listener on the current thread? Isn't the 'postEvent' method better since it will invoke the handler on the EventQueue thread?
  • Brett
    Brett over 13 years
    You should be doing pretty much everything with components on the EDT. (AWT claims to be all thread-safe, but isn't.) And of course, as I mentioned, there is the permissions thing.