Z innego wątku powinieneś użyć java.awt.EventQueue.invokeLater
, aby dostać się do EDT, a następnie wszystko działa.
Więc:
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
Document doc = text.getDocument();
int origLen = doc.getLength()
try {
doc.insertString(origLen, msg, null);
} catch (BadLocationException exc) {
// Odd APIs forces us to deal with this nonsense.
IndexOutOfBoundsException wrapExc = new IndexOutOfBoundsException();
wrapExc.initCause(exc);
throw wrapExc;
}
// IIRC, Position is a bit odd and
if (origLen == 0) {
text.setCaretPosition(doc.getLength());
}
}});
Gdyby ktoś odczytać docs API dla JTextArea.append
twierdzi, że jest bezpieczny wątku. JDK7 usuwa to mało prawdopodobne żądanie (przypomnienie: wątki są trudne). Z reguły w Swingu zawsze zmierzam prosto do modelu/Document
.
Wierzę, że jeśli karetka jest na końcu, należy ją przesunąć po dodaniu. Jedynym wyjątkiem jest brak tekstu z powodu dziwnego API. Jeśli został przeniesiony, prawdopodobnie nie chcemy go aktualizować po dodaniu.
Uwaga: jeśli robi to wiele wątków, niekoniecznie wiadomo, które zostaną przesłane jako pierwsze.
+1 dla pamiętając, aby przesunąć kursor – kdgregory
Kopiowanie całego obszaru tekstowego do String tylko po to, by uzyskać jego długość? To nie będzie bezpieczne dla wątków. –
Tak, obowiązują standardowe procedury gwintowania Swing. (Nie zdawałem sobie sprawy, że getText() wymaga kopiowania rzeczy, zmienię to na getDocument().) –