2012-05-21 4 views
13

여기 간단한 Java 질문이 있습니다. JTextArea를 사용하여 작성된 텍스트 영역의 마지막 행의 처음으로 자동 텍스트 스크롤을 원합니다. 텍스트 영역의 줄당 텍스트의 양은 텍스트 영역의 너비보다 상당히 길다.마지막 줄의 시작 부분에 캐럿 위치가 설정된 텍스트 영역 (JTextArea)의 자동 텍스트 스크롤

다음은이 코드를 설정하는 코드입니다.

지금
JTextArea textArea = new JTextArea(); 
DefaultCaret caret = (DefaultCaret)textArea.getCaret(); 
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 

문제이며, 위의 코드로, 기본 동작은 캐럿이 자동 결과적으로 전체 텍스트 영역의 시작 부분이 범위를 벗어나 취득, 문서의 끝 부분에 위치한다는 것입니다 . 문서에서 마지막 줄의 시작 부분까지 자동 스크롤을 사용하는 것이 좋습니다.

여기에 두 개의 스크린 샷,

는 내가 원하는 것은 처음입니다하지만 일어나는 것은 두 번째이며, 그것은 명확하게합니다. What I get is this

답변

13

What I want is this

단순히 텍스트 영역의 텍스트를 업데이트 한 후 getLineCountgetLineStartOffset를 사용하여 올바른 위치로 캐럿을 이동합니다.

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

쿨 솔루션 : 여기

원하는 동작을 설명하는 작업 예입니다! 하지만 여기에 질문이 있습니다. ta.setCaretPosition (ta.getLineStartOffset (ta.getLineCount() - 1));)을 설정할 수있는 방법이 있습니까? 매번 업데이트하지 않고 한 번만 실행하므로 전체 응용 프로그램에 대해 유효하게 유지됩니까? –

+0

또한 DefaultCaret을 사용하더라도 caret = (DefaultCaret) ta.getCaret(); caret.setUpdatePolicy (DefaultCaret.ALWAYS_UPDATE); 귀하의 코드는 이러한 진술도없이 작동합니까? 이 관점에서 당신의 견해는 무엇입니까? –

+0

@JtheRocker는 내가 아는 것이 아닙니다. 캐럿 위치는 텍스트가 업데이트 될 때 계속 움직입니다. 따라서 이것은 매번 위치를 다시 계산해야 함을 의미합니다. 아마도 superTextArea를 확장하고 setText를 재정의 할 수 있습니다. 먼저 super.setText를 호출 한 다음 캐럿을 배치합니다. 두 번째 질문에 관해서는, 이것은 바람직한 행동과 인간 공학의 문제입니다. 귀하의 질문에 당신이 요청한 것입니다. 이제 실제로 스크롤 패널의 왼쪽 하단으로 스크롤하는 것을보고 있다면 다른 것을 찾고 있습니다. 그렇다면 다른 질문을 게시하는 것을 고려하십시오. –