2012-05-21 28 views
13

Tôi có một câu hỏi Java đơn giản tại đây. Tôi muốn tự động di chuyển văn bản đến đầu dòng cuối cùng của vùng văn bản được tạo bằng JTextArea. Số lượng văn bản trên mỗi dòng của vùng văn bản dài hơn chiều rộng của vùng văn bản.Cuộn văn bản tự động cho vùng văn bản (JTextArea) với vị trí dấu mũ được đặt ở đầu dòng cuối cùng

Đây là đoạn mã tôi đã sử dụng để thiết lập điều đó.

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

Vấn đề bây giờ là, với đoạn code trên, hành vi mặc định là dấu sót được tự động đặt ở cuối tài liệu, kết quả là, phần đầu của vùng văn bản toàn bộ được ra khỏi phạm vi . Tôi muốn cuộn tự động xảy ra ở đầu dòng cuối cùng trong tài liệu.

Để làm rõ, dưới đây là hai ảnh chụp màn hình,

Điều tôi muốn là cái đầu tiên nhưng điều đang xảy ra là thứ hai.

What I want is this What I get is this

Trả lời

13

Đơn giản chỉ cần di chuyển dấu mũ đến vị trí đúng bằng getLineCountgetLineStartOffset sau khi cập nhật nội dung của textarea.

Dưới đây là một ví dụ minh họa làm việc hành vi mong muốn của bạn:

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

mát giải pháp! Nhưng tôi có một câu hỏi ở đây. Có cách nào tôi có thể đặt ta.setCaretPosition (ta.getLineStartOffset (ta.getLineCount() - 1)); chỉ một lần thay vì cập nhật nó mỗi lần, để nó vẫn còn hợp lệ cho toàn bộ ứng dụng? –

+0

Hơn nữa, mặc dù bạn đang sử dụng DefaultCaret caret = (DefaultCaret) ta.getCaret(); caret.setUpdatePolicy (DefaultCaret.ALWAYS_UPDATE); Mã của bạn cũng sẽ hoạt động nếu không có các câu lệnh này? Quan điểm của bạn về vấn đề này là gì? –

+0

@ JtheRocker không phải là tôi biết. Vị trí dấu nháy tiếp tục di chuyển khi văn bản được cập nhật. Do đó, điều này có nghĩa là vị trí của nó cần phải được tính toán lại mọi lúc. Bạn có lẽ có thể mở rộng JTextArea và ghi đè lên setText, trước tiên gọi super.setText và sau đó định vị dấu mũ. Đối với câu hỏi thứ hai của bạn, đây là một câu hỏi về hành vi và thái độ mong muốn. Trong câu hỏi của bạn đó là những gì bạn yêu cầu. Bây giờ, nếu bạn đang tìm kiếm trong thực tế di chuyển đến góc dưới bên trái của scrollpane, sau đó bạn đang tìm kiếm cái gì khác. Nếu có, hãy cân nhắc đăng câu hỏi khác lên SO. –

Các vấn đề liên quan