Sono diventato molto affezionato a Google Gauva's EventBus, tanto che desidero includerlo in una delle mie API Swing GridBagBuilder. L'obiettivo è prendere un componente Swing e fare qualcosa con esso in un evento arbitrario e iscriverlo a un EventBus. Il problema è che penso che le operazioni di riflessione effettuate da EventBus non piacciano ai miei generici per qualsiasi tipo di evento arbitrario.Passare un evento generico a Guava EventBus?
In sostanza, il metodo accetta un BiConsumer in cui C è un componente Swing ed E è un tipo di evento arbitrario da sottoscrivere a EventBus.
public <E> void subscribe(EventBus eventBus, BiConsumer<C,E> consumer) {
eventBus.register(new Object() {
@Subscribe
public void processEvent(E event) {
try {
consumer.accept(comp, event);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
Il bus evento sembra funzionare, ma continuo a ricevere bizzarre ClassCastException
errori. C'è un modo per far funzionare questo? O è quello che sto cercando di ottenere una causa persa?
AGGIORNAMENTO: qui è un SSCCE. Si interrompe quando ci sono più tipi di eventi e da qualche parte i meccanismi generici e di riflessione interna vengono incasinati e non è in grado di distinguere un tipo di evento da un altro.
import java.awt.Component;
import java.util.function.BiConsumer;
import javax.swing.JButton;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
public class EventBusTest<C extends Component> {
private final C comp;
public static void main(String[] args) {
final EventBus eventBus = new EventBus();
EventBusTest<JButton> test = new EventBusTest<>(new JButton("Hello"));
test.subscribe(eventBus, (JButton c, SomeEvent e) -> System.out.println("Hello"));
test.subscribe(eventBus, (JButton c, SomeOtherEvent e) -> System.out.println("World"));
eventBus.post(new SomeEvent());
}
private EventBusTest(C comp) {
this.comp = comp;
}
public<E> void subscribe(EventBus eventBus, BiConsumer<C,E> consumer) {
eventBus.register(new Object() {
@Subscribe
public void processEvent(E event) {
try {
consumer.accept(comp, event);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private static final class SomeEvent {}
private static final class SomeOtherEvent {}
}
E qui è la stampa console ...
java.lang.ClassCastException: com.swa.rm.pricing.EventBusTest$SomeEvent cannot be cast to com.swa.rm.pricing.EventBusTest$SomeOtherEvent
at com.swa.rm.pricing.EventBusTest$$Lambda$14/28594521.accept(Unknown Source)
at com.swa.rm.pricing.EventBusTest$1.processEvent(EventBusTest.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.google.common.eventbus.EventSubscriber.handleEvent(EventSubscriber.java:74)
at com.google.common.eventbus.SynchronizedEventSubscriber.handleEvent(SynchronizedEventSubscriber.java:47)
at com.google.common.eventbus.EventBus.dispatch(EventBus.java:322)
at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:304)
at com.google.common.eventbus.EventBus.post(EventBus.java:275)
at com.swa.rm.pricing.EventBusTest.main(EventBusTest.java:21)
Hello
Mostrare un esempio completo e riproducibile che mostri un 'ClassCastException' e pubblichi la traccia dello stack completo. –
Dang, il SSCCE che ho costruito funziona. Perché...? – tmn
Ok, è stato rotto! Si interrompe quando ci sono più tipi di eventi. Aggiornamento sopra ... – tmn