2012-05-21 38 views
13

Burada basit bir Java sorusu var. Otomatik metin kaydırmayı JTextArea kullanılarak oluşturulan bir metin alanının son satırının başına kaydırmak istiyorum. Metin alanının satır başına düşen metin miktarı, metin alanının genişliğinden oldukça uzundur.Metin alanı için otomatik metin kaydırma (JTextArea) ile son satırın başlangıcına ayarlanmış düzeltme konumu

Bunu kurmak için kullandığım kod parçacığı İşte.

şimdi
JTextArea textArea = new JTextArea(); 
DefaultCaret caret = (DefaultCaret)textArea.getCaret(); 
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 

sorun deyişle, yukarıdaki kod ile, varsayılan davranış şapka oto sonucunda, tüm metin alanının başlangıç ​​kısmı kapsamı dışında alır, belgenin sonuna yerleştirilmiş olmasıdır . Otomatik kaydırmayı belgede son satırın başına gelmesini tercih ederim.

Burada iki ekran görüntüleri,

İstediğim ilki ama ne oluyor ikinci biridir vardır, bu açıklığa kavuşturmak için. What I get is this

cevap

13

What I want is this

Basitçe textarea metnini güncelledikten sonra getLineCount ve getLineStartOffset kullanarak doğru konuma işaretini taşımak.

import java.util.List; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DefaultCaret; 

public class Test { 

    private JFrame frame; 
    private JTextArea ta; 

    protected void initUI() { 
     frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     ta = new JTextArea(); 
     DefaultCaret caret = (DefaultCaret) ta.getCaret(); 
     caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 
     frame.add(new JScrollPane(ta)); 
     frame.setSize(400, 200); 
     frame.setVisible(true); 
     new UpdateText().execute(); 
    } 

    class UpdateText extends SwingWorker<String, String> { 

     @Override 
     public String doInBackground() { 
      for (int i = 0; i < 1000; i++) { 
       publish("Hello-" + i); 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
      return null; 
     } 

     @Override 
     public void process(List<String> chunks) { 
      for (String s : chunks) { 
       if (ta.getDocument().getLength() > 0) { 
        ta.append("\n"); 
       } 
       ta.append(s); 
      } 
      try { 
       ta.setCaretPosition(ta.getLineStartOffset(ta.getLineCount() - 1)); 
      } catch (BadLocationException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     @Override 
     public void done() { 

     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new Test().initUI(); 
      } 
     }); 
    } 

} 
+0

Serin çözüm: İşte

İstediğiniz davranışı gösteren bir çalışma örneğidir! Ama burada bir sorum var. Ta.setCaretPosition (ta.getLineStartOffset (ta.getLineCount() - 1)) 'i ayarlayabileceğim herhangi bir yol var mı? Her seferinde güncellemek yerine sadece bir kez, tüm uygulama için geçerli kalması için mi? –

+0

Ayrıca, DefaultCaret caret = (DefaultCaret) ta.getCaret() 'ı kullanırken, caret.setUpdatePolicy (DefaultCaret.ALWAYS_UPDATE); Kodunuz da bu ifadeler olmadan işe yarayacak mı? Bu konuda görüşünüz nedir? –

+0

@JtheRocker bildiğimi değil. Metin güncellendiğinde düzeltme işareti konumu devam ediyor. Bu nedenle, bu konumun her zaman yeniden hesaplanması gerektiği anlamına gelir. JTextArea'yı genişletebilir ve setText'i geçersiz kılabilirsiniz, önce super.setText öğesini arayarak ve sonra da kartelayı konumlandırabilirsiniz. İkinci sorunuz için, bu istenen davranış ve ergonomi sorunudur. Sorduğun soruda istediğin buydu. Şimdi, aslında kaydırma bölmesinin sol alt köşesine ilerliyorsanız, başka bir şey arıyorsunuz demektir. Eğer öyleyse, SO üzerine başka bir soru göndermeyi düşünün. –

İlgili konular