Search code examples
javaswingdeadlockfreeze

Calling modelToView() method freezes Java Swing application


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 enter image description here

When Application freezes enter image description here

If I minimize and maximize the window enter image description here


Solution

  • 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.