| Summary: | FXCanvasEx does not ensure that the UI is always updated while processing events. | ||
|---|---|---|---|
| Product: | [Tools] GEF | Reporter: | Matthias Wienand <matthias.wienand> |
| Component: | GEF FX | Assignee: | gef-inbox <gef-inbox> |
| Status: | RESOLVED FIXED | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | ||
| Version: | 1.0.0 | ||
| Target Milestone: | 4.1.0 (Neon.1) M1 | ||
| Hardware: | All | ||
| OS: | All | ||
| Whiteboard: | |||
I adjusted the code so that the UI is refreshed in between event dispatching. The code is published on the R4_0_maintenance and master branches. Therefore, I resolve this ticket as fixed for 4.1.0 M1. |
Currently, when embedding a JavaFX application into an SWT application using FXCanvas, the UI is not always updated while processing events. This is especially noticeable when the event processing is slow, i.e. multiple events are queued while an event is being processed. This results in a UI freeze until the events are fully processed and the UI thread is free to update itself. The FXCanvasEx should ensure that the UI is always updated while processing events. This can be done by deferring the processing of incoming events while waiting for a UI update, as follows: Scene scene = getCanvas().getScene(); final EventDispatcher eventDispatcher = scene.getEventDispatcher(); final boolean[] updated = new boolean[] { true }; final List<Event>[] deferred = new List[] { new ArrayList<Event>() }; scene.setEventDispatcher(new EventDispatcher() { @Override public Event dispatchEvent(final Event event, final EventDispatchChain tail) { // defer event if display was not updated since the last event // was processed if (!updated[0]) { deferred[0].add(event); return event; } // schedule runnable updated[0] = false; Display.getDefault().asyncExec(new Runnable() { @Override public void run() { updated[0] = true; // dispatch deferred events if (!deferred[0].isEmpty()) { for (Event e : deferred[0]) { eventDispatcher.dispatchEvent(e, tail); } deferred[0].clear(); } // update UI while (Display.getDefault().readAndDispatch()) { ; } } }); // dispatch the most recent event Event returnedEvent = eventDispatcher.dispatchEvent(event, tail); // return dispatched event return returnedEvent; } });