I've been using the following approach to create components and return values from Swing to/from outside the EDT. For instance, the following method could be an extension to JFrame, to create a JPanel and add it to the parent JFrame:
public JPanel threadSafeAddPanel() {
final JPanel[] jPanel = new JPanel[1];
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
jPanel[0] = new JPanel();
add(jPanel[0]);
}
});
} catch (InterruptedException ex) {
} catch (InvocationTargetException ex) {
}
return jPanel[0];
}
The local 1-length array is used to transfer the "result" from inside the Runnable, which is invoked in the EDT. Well, it looks "a bit" hacky, and so my questions:
Although that method may make sense in some situations, it will be useless most of the time.
The reason is that the creation of most (if not all) of your components will always occur from the EDT, as a result of a user action (menu item or button clicked) which are always executed from the EDT.
In cases where you have big work to perform before creating your panel and you don't want to block the EDT, then you should, as suggested by someone else, use SwingWorker or a Swing framework that offer support for long tasks (generally based on SwingWorker internally anyway, but not necessarily).
Regarding your question 2, unfortunately you don't have many ways to do that:
Here is, simplified, the ItemHolder class:
public class ItemHolder<T> {
public void set(T item) {...}
public T get() {...}
private T item;
}
Runnable before fetching the resultSwingWorkerIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With