2009-06-11 2 views
5

Каков общий подход с Java-качанием для обновления текстового поля с текстами строк (скажем, из потока), а затем поток текстового каретки на дно текстовой области, поскольку текст добавляется. Также обновите полосу прокрутки так, чтобы она была внизу.Java Swing: подход для динамически добавляемого текста в текстовой области, обновление полосы прокрутки

Я думал, что у меня будет stringbuffer и добавьте текст к этому, а затем установите строку в текстовом поле и поместите полосу прокрутки внизу.

ответ

13

Чтобы добавить текст, используйте append(), затем setCaretPosition(), чтобы убедиться, что вы прокручиваете его.

myTextPane.append(textFromSomewhere); 
myTextPane.setCaretPosition(myTextPane.getDocument().getLength()); 
+0

+1 для запоминания, чтобы переместить курсор – kdgregory

+0

Копирование всей текстовой области в строку только для того, чтобы получить длину? Это не будет потокобезопасным. –

+0

Да, применяются стандартные процедуры намотки. (Я не понимал, что getText() задействовал копирование вещей, я изменил это на getDocument().) –

7

Метод append() не делает то, что вы хотите?

И хотя вы не спрашивали: когда вы генерируете что-то в фоновом потоке, обязательно используйте SwingUtilities.invokeLater() для обновления ваших компонентов.

1

При обновлении из нити, не забудьте использовать SwingWorker или какой-либо другой AWT поточно-подход.

3

С другой стороны, вы должны использовать java.awt.EventQueue.invokeLater, чтобы попасть на EDT, а затем все работает.

Итак:

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()); 
    } 
}}); 

Если кто-нибудь читать API документацию для JTextArea.append он утверждает, что потокобезопасна. JDK7 удаляет это маловероятное утверждение (напоминание: многопоточность). Как правило, в Swing я всегда стремлюсь всегда к модели/Document.

Я считаю, что если карет в конце, он должен быть перемещен после добавления. Единственное исключение - отсутствие текста из-за странного API. Если он был перемещен, мы, вероятно, не захотим его обновлять после добавления.

Примечание: Если это связано с несколькими потоками, вы не обязательно знаете, что будет там первым.

1

Вы можете обновить скроллбар без чтения doc.length с:

scrollbar.setValue(scrollbar.getMaximum()); 

Update (завернутые в Invoke позже, код от Тома Hawtin)

java.awt.EventQueue.invokeLater(new Runnable() { public void run() { 
    try { 
     textArea.append(msg); 
    } catch (BadLocationException exc) { 
     // Odd APIs forces us to deal with this nonsense. 
     IndexOutOfBoundsException wrapExc = new IndexOutOfBoundsException(); 
     wrapExc.initCause(exc); 
     throw wrapExc; 
    } 
    JScrollBar bar = scrollPane.getVerticalScrollBar(); 
    bar.setValue(bar.getMaximum()); 
}}); 
+0

и завернутый в invokeLater, пожалуйста, уточните свой ответ. – mKorbel

+0

Я не вхожу в эту тему, но надеюсь, что это то, чего вы хотели. – fachexot

Смежные вопросы