I am currently refactoring an application I made to be thread safe.
I have a JCheckBox
that I need to check. This JCheckBox
is referenced throughout the program in various different threads.
Can I simply call checkbox.isSelected()
or do I have to make this call using invokeLater
?
I'm finding it difficult to understand concurrency in general, but I'm getting there slowly but surely. If this is a stupid question, please tell me why so I can better my understanding.
Thank you.
No, it's not thread safe. Swing generally is not thread safe. You need to use invokeLater
. On the other hand, you can make the current thread wait until the task ininvokeLater
finishes:
private boolean isSelected(final AbstractButton button) {
if (SwingUtilities.isEventDispatchThread()) {
// a shortcut so the AWT thread won't wait for itself
return button.isSelected();
}
final AtomicBoolean isSelected = new AtomicBoolean();
final CountDownLatch latch = new CountDownLatch(1);
SwingUtilities.invokeLater(() -> {
try {
isSelected.set(button.isSelected());
} finally {
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return isSelected.get();
}