public void connectChildren(final List<? extends DataItem> children, final DataFolder parent) { final ArrayList<AddTypeTagsCallable> callables = new ArrayList<>(); final ArrayList<DataItemCreatedEvent> events = new ArrayList<>(); // edit databeans in EDT ThreadUtils.runInEDT( new Runnable() { @Override public void run() { for (DataItem child : children) { // was it already connected? boolean wasConnected = child.getParent() != null; if (!wasConnected) { // prepare event, but don't send it yet events.add(new DataItemCreatedEvent(child)); } // connect to this child.setParent(parent); // add parent.children.add(child); // prepare type tagging callables if (child instanceof DataBean) { callables.add(new AddTypeTagsCallable((DataBean) child)); } } } }); // run type tagging in parallel in background threads try { // run callables and wait until all have finished List<Future<Object>> futures = executor.invokeAll(callables); for (Future<Object> future : futures) { // check callable for exception, and throw if found future.get(); } // dispatch events in EDT ThreadUtils.runInEDT( new Runnable() { @Override public void run() { for (DataItemCreatedEvent event : events) { dispatchEvent(event); } } }); } catch (InterruptedException | ExecutionException e) { Session.getSession().getApplication().reportExceptionThreadSafely(e); } }
public void notifyTaskStateChangeListener(State oldState, State newState) { /* * Notify listener * * Use invokeAndWait instead of invokeLater. In CLI, we must know when * the task is completed and the next operation (usually session * saving) can be started. */ TaskStateChangeNotifier changeNotifier = new TaskStateChangeNotifier(oldState, newState); ThreadUtils.runInEDT(changeNotifier); }