@Override
 public synchronized void write(byte[] ba, int str, int len) {
   try {
     curLength += len;
     if (bytesEndWith(ba, str, len, LINE_SEP)) {
       lineLengths.addLast(new Integer(curLength));
       curLength = 0;
       if (lineLengths.size() > maxLines) {
         textArea.replaceRange(null, 0, lineLengths.removeFirst().intValue());
       }
     }
     for (int xa = 0; xa < 10; xa++) {
       try {
         textArea.append(new String(ba, str, len));
         break;
       } catch (
           Throwable
               thr) { // sometimes throws a java.lang.Error: Interrupted attempt to aquire write
                      // lock
         if (xa == 9) {
           thr.printStackTrace();
         }
       }
     }
     textArea.setCaretPosition(textArea.getText().length());
   } catch (Throwable thr) {
     CharArrayWriter caw = new CharArrayWriter();
     thr.printStackTrace(new PrintWriter(caw, true));
     textArea.append(System.getProperty("line.separator", "\n"));
     textArea.append(caw.toString());
   }
 }
 // MUST BE THE ONLY METHOD THAT TOUCHES textArea!
 public synchronized void run() {
   if (clear) {
     textArea.setText("");
   }
   for (String val : values) {
     curLength += val.length();
     if (val.endsWith(EOL1) || val.endsWith(EOL2)) {
       if (lengths.size() >= maxLines) {
         textArea.replaceRange("", 0, lengths.removeFirst());
       }
       lengths.addLast(curLength);
       curLength = 0;
     }
     textArea.append(val);
   }
   values.clear();
   clear = false;
   queue = true;
 }