All Swing components are implemented to be accessed from a single thread (the event dispatching thread). So there are no protections against concurrent access and concurrent changes of variables and field.
If you are lucky everything works well. But you cannot rely on it and the same code can have massive problems on the next run.
A simple example:
The paint procedure of a JLabel contains the following (simplified) code (taken from BasicLabelUI
class):
# assume your label is enabled
Icon icon = (label.isEnabled()) ? label.getIcon() : label.getDisabledIcon();
# what happens if another thread calls label.setEnabled(false) at this point?
if (icon != null) {
icon.paintIcon(c, g, paintIconR.x, paintIconR.y);
}
if (label.isEnabled()) {
paintEnabledText(label, g, clippedText, textX, textY);
}
else {
paintDisabledText(label, g, clippedText, textX, textY);
}
For example if you call setEnabled() from other threads than the EDT it would be possible that you get a label with the enabled icon but the disabled painted text.