I am creating a Transliterating tool in Java. It's almost complete. But, when I type so fast the GUI freezes.
So, I debugged the application to pinpoint the command where it is happening.
The call to method JTextField.modelToView(pos)
causes this, which further calls TextUI.modelToView(JTextComponent c, int pos)
.
It appears, this method first acquires lock on text component's document by calling AbstractDocument::readLock()
method, whose source code is:
public synchronized final void readLock() {
try {
while (currWriter != null) {
if (currWriter == Thread.currentThread()) {
// writer has full read access.... may try to acquire
// lock in notification
return;
}
wait();
}
numReaders += 1;
} catch (InterruptedException e) {
throw new Error("Interrupted attempt to aquire read lock");
}
}
Which calls wait()
if current thread is not the writer thread.
But, I am only mutating document when space key is pressed, which I believe happens in EDT. And, Swing
would also be mutating it in EDT. Also, I am calling JTextField.modelToView(pos)
when DocumentListener.insertUpdate(DocumentEvent)
is invoked.
Then, what is the reason, the application freezes!
Here are the screenshots:
The application screenshot
When Application freezes
If I minimize and maximize the window
I am calling JTextField.modelToView(pos) when DocumentListener.insertUpdate(DocumentEvent) is invoked.
The Document has not been updated completely when the DocumentEvent is fired. Wrap your code in the DocumentListener in a SwingUtilities.invokeLater(...)
. This should cause your event code to be executed after the Document has finished updating itself.