I have encountered a very strange problem when trying to insert multiple Strings into a JTextPane that has a TitledBorder (this is important, the problem seems to only occur with TitledBorder specifically, other Borders or no Border at all work fine) from a Thread. The (for this problem) significant part of my test code looks like this:
JTextPane myTextPane = new JTextPane();
myTextPane.setBorder(new TitledBorder("Some title"));
StyledDocument doc = myTextPane.getStyledDocument();
SimpleAttributeSet sas = new SimpleAttributeSet();
StyleConstants.setForeground(sas, Color.BLACK);
private void insertTwoStrings()
{
new Thread(new Runnable()
{
@Override
public void run()
{
docTest.insertString(docTest.getLength(), "first string ", sas);
docTest.insertString(docTest.getLength(), "second string\n", sas);
}
}).start();
}
Now to the problem: the insertTwoStrings() method works fine sometimes, but other times it fails very badly in a way that locks up the entire application (i have to kill the process to shut the application down). So i opened the program in the debugger and replicated the problem there, when the problematic Thread got locked up i suspended it and took a closer look at the program counter position:

It seems like this synchronized(this) is the cause of my problem. Is this actually a bug or am i making some kind of mistake?
In case someone wants to replicate this, for the problem to occur you have to meet all of the following three criteria:
- inserting text into a JTextPane (i.e. into its StyledDocument) from a Thread
- invoking StyledDocument.insertString(…) multiple times within the thread, not just once
- the JTextPane must have a TitledBorder
Executing the Thread will still work sometimes, but every now and then it will fail and lock up the entire program.
As others already point out Swing is not threadsafe unless the specific method is documented to be threadsafe. Swing provides several Utility methods and classes that can pass messages to the event dispatch thread – SwingUtilities contains invokeLater and invokeAndWait, the SwingWorker threads can send “finished” work to a callback.
The above code will execute run on swings event dispatch thread, so take care to keep run() short (read fast) or your User interface will slow to a crawl.