Swing JTextArea multithreading issue - InterruptedException

I have a simple console application that runs calculations in multiple threads (10-20 of them). Now I'm trying to create a simple graphical interface that allows me to select a file for processing and printing logs from all threads.

So, I created a Swing GUI with JTextArea for my log and a method for logging information:

public synchronized void log(String text) {
    logArea.append(text);
    logArea.append("\n");

    if (logArea.getDocument().getLength() > 50000) {
        try {
            logArea.getDocument().remove(0,5000);
        } catch (BadLocationException e) {
            log.error("Can't clean log", e);
        }
    }

    logArea.setCaretPosition(logArea.getDocument().getLength());
}

However, the method setCaretPositionsometimes causes a lock while waiting for some lock, and appendsometimes throws an InterruptedException.

Exception in thread "Thread-401" java.lang.Error: Interrupted attempt to aquire write lock
at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1334)
at javax.swing.text.AbstractDocument.insertString(AbstractDocument.java:687)
at javax.swing.text.PlainDocument.insertString(PlainDocument.java:114)
at javax.swing.JTextArea.append(JTextArea.java:470)
at lt.quarko.aquila.scripts.ui.ScriptSessionFrame.log(ScriptSessionFrame.java:215)

I'm new to Swing, so I can't figure out what I'm doing wrong here?

Thanks in advance.

+6
source share
4

Swing , .

+5

ui , EventDispatchThread. :

 public synchronized void log(String text) {
        Runnable  runnable = new Runnable() {
            public void run(){
                logArea.append(text);
                logArea.append("\n");
                if (logArea.getDocument().getLength() > 50000) {
                    try {
                        logArea.getDocument().remove(0, 5000);
                    } catch (BadLocationException e) {
                        log.error("Can't clean log", e);
                    }
                }
                logArea.setCaretPosition(logArea.getDocument().getLength());
            }
        }
        SwingUtilities.invokeLater(runnable);

    }
+3

, , interrupt . . .

append InterruptedException

, . , Document.insertString .

, EDT. JTextArea.append , . , , ( ) - setCaretPosition. , invokeLater? , , . . AbstractDocument.writeLock jdk, Error.

, , Document EDT , , . AbstractDocument, Error.

Document Error. , , , bInterrupted. , Thread.interrupt() , .

// test the flag and clear it (interrupted() method does clear it)
boolean bInterrupted = Thread.interrupted();
m_doc.insertString(m_doc.getLength(), s, null);
// restore the original interrupted state
if (bInterrupted)
  Thread.currentThread().interrupt();

setCaretPosition

. invokeLater, , :

/** <code>true</code> when gui update scheduled. This flag is to avoid
  * multiple overlapping updates, not to call
  * <code>invokeLater</code> too frequently.
 */
private volatile boolean m_bUpdScheduled;

/** Updates output window so that the last line be visible */
protected void update()
{
  if (!m_bUpdScheduled) {
    m_bUpdScheduled = true;
    EventQueue.invokeLater(new Runnable() {
        public void run() {
          m_bUpdScheduled = false;
          try {
            m_ebOut.setCaretPosition(m_doc.getLength());
          }
          catch (IllegalArgumentException iae) {
            // doc not in sync with text field - too bad
          }
        }
    });
  }
}
+2

, , setCaretPosition() , JTextArea . , EDT, .

:

  • NEVER_UPDATE. , , " ", , .
  • setCaretPosition(): , X . , , , X . , NEVER_UPDATE .
  • JTextArea JScrollPane, . invokeLater() , , - .

, JTextComponent ( ), , :

  if (autoScroll && (scrollPane != null)) {
    final JScrollBar vertical = scrollPane.getVerticalScrollBar();
    if (vertical != null) {
      appendText(doc, txt);
      java.awt.EventQueue.invokeLater(new Runnable() {
        @Override public void run() {
          vertical.setValue(vertical.getMaximum());
        }
      });
      return;
    }
  }

, , , .

0

All Articles