2012-03-01 8 views
11

Cuando usted tiene un bus de eventos asíncronos hilo de eventos y eventos de fuego, digamos dentro del modelo que quedar atrapado en la interfaz de usuario que tiene probablemente el siguiente problema:mejor manera de combinar EventBus guayaba y AWT manejo

El domicilio el controlador se ejecuta en un hilo de trabajo, pero todos los cambios de desplazamiento de UI deben ejecutarse dentro del hilo de evento AWT. Esto significa que debe envolver todo su manipulador clode en EventQueue.invokeLater(...).

Parece un código de placa de caldera. Me pregunto si existe una solución más inteligente para ese problema.

¿Qué tal una extensión del bus de eventos guava que marca a un controlador para la ejecución dentro de un hilo especial? Esto se puede marcar con una anotación, p. @ExecuteWithinEDT:

class EventBusChangeRecorder { 
    @Subscribe @ExecuteWithinEDT void recordCustomerChange(ChangeEvent e) { 
    recordChange(e.getChange()); 
    } 
} 

Respuesta

1

Se puede crear un EventBus que despacha sólo en el hilo AWT:

EventBus mybus = new AsyncEventBus("awt", 
    new Executor() { 
     public void execute (Runnable cmd) { 
      if (EventQueue.isDispatchThread()) { 
       cmd.run(); 
      } else { 
       EventQueue.invokeLater(cmd); 
      } 
     } 
    }); 
+0

Hola, lo mismo que con mi otro comentario a la publicación anterior: todos los eventos ahora se envían en AWT. Lo que quería es una forma para que cada suscriptor individual pudiera decidir enviar en AWT o no. De lo contrario, un bus de evento asincrónico no tendría sentido en una aplicación del mundo real – langm

9

Los controladores registrados con un bus de eventos asíncrono se ejecutan en cualquier hilo de las previstas Executor elige a ejecutarlos en , no necesariamente un hilo de trabajo.

Lo que he hecho es crear una implementación de Executor que ejecuta cosas en el hilo de la cola de eventos. Es muy sencillo:

public class EventQueueExecutor implements Executor { 
    @Override public void execute(Runnable command) { 
    EventQueue.invokeLater(command); 
    } 
} 

continuación, puede simplemente crear su EventBus con eso:

EventBus eventBus = new AsyncEventBus(new EventQueueExecutor()); 

A continuación, todos los manipuladores se ejecutarán en el hilo de cola de eventos.

Editar:

Un ejemplo de eventos de reenvío:

public class EventForwarder { 
    private final EventBus uiEventBus; 

    public EventForwarder(EventBus uiEventBus) { 
    this.uiEventBus = uiEventBus; 
    } 

    // forward all events 
    @Subscribe 
    public void forwardEvent(Object event) { 
    uiEventBus.post(event); 
    } 

    // or if you only want a specific type of event forwarded 
    @Subscribe 
    public void forwardEvent(UiEvent event) { 
    uiEventBus.post(event); 
    } 
} 

Solo necesita suscribir que a su autobús evento principal y publicar todos los eventos al bus evento principal, pero se suscriben todos los componentes de interfaz de usuario a la UI evento de autobús.

+2

Su solución es agradable, pero da otro problema: ahora TODOS los eventos se envían dentro de AWT. En una aplicación del mundo real, es probable que desee que se envíen algunos suscriptores dentro de AWT (la parte de la GUI), mientras que otros subscriptores (del modelo u otro módulo) NO deben distribuirse dentro de AWT. De lo contrario, el autobús de eventos asincrónico no tendría mucho sentido. – langm

+0

@langm: ​​Una opción es tener múltiples 'EventBus'es ... uno que llama a los manejadores en la cola de eventos y otro que no. Los manipuladores que desean que se les llame en la cola de eventos se suscriben a ese bus de eventos. Luego puede tener un controlador o controladores que se suscriban al Omnibus de eventos OTHER y manejen ciertos tipos de eventos al publicarlos en el bus de cola de eventos. – ColinD

+0

que probablemente sea una solución. pero significaría que tendría que suscribirme dos veces: una vez que la interfaz de usuario, una vez el bus UI en el otro bus ... una buena característica sería una función de reenvío para simplemente reenviar todos los eventos globalmente a otro bus. ¿Esto tiene sentido? – langm

Cuestiones relacionadas