2012-08-28 70 views
7

Tôi đang cố gắng tạo một GUI cho một dịch vụ, trong đó có một JTextArea để xem các tin nhắn trong, mỗi tin nhắn được viết trên một dòng duy nhất, và wordwrapped nếu cần thiết.Làm thế nào để hạn chế số dòng trong JTextArea?

Thư đến qua ổ cắm, vì vậy nó chỉ đơn thuần là một .append (thư) mà tôi đang sử dụng để cập nhật JTextArea, tôi cần giới hạn các dòng này thành 50 hoặc 100 và tôi không cần giới hạn số lượng ký tự mỗi dòng.

Nếu có phương pháp giới hạn số dòng trong JTextArea hoặc nếu có phương pháp thay thế để thực hiện?

Tôi thực sự có thể sử dụng sự trợ giúp trong vấn đề này.

Sửa

Vấn đề là mỗi khách hàng có thể gửi các dòng vô hạn, tất cả những dòng này phải có thể đọc được, vì vậy đây không phải là một kiểm tra đơn giản về số lượng các dòng trong JTextArea. Tôi cần phải xóa các dòng cũ hơn để xem các dòng mới hơn.

+0

nếu bạn biết có bao nhiêu ký tự được phép trong một dòng của jtextarea, chỉ cần chia số đó cho tổng số ký tự trong jtextarea –

+0

Liên quan: http://stackoverflow.com/questions/479182/how-to-limit- jtextarea-max-rows-and-coloums – CloudyMarble

+0

nó chỉ là các dòng hoặc hàng mà tôi cần giới hạn trong trường hợp này, vì vậy số lượng ký tự là loại không liên quan. –

Trả lời

6

Điều này có hiệu quả hơn không?

final int SCROLL_BUFFER_SIZE = 100; 
public void trunkTextArea(JTextArea txtWin) 
{ 
    int numLinesToTrunk = txtWin.getLineCount() - SCROLL_BUFFER_SIZE; 
    if(numLinesToTrunk > 0) 
    { 
     try 
     { 
      int posOfLastLineToTrunk = txtWin.getLineEndOffset(numLinesToTrunk - 1); 
      txtWin.replaceRange("",0,posOfLastLineToTrunk); 
     } 
     catch (BadLocationException ex) { 
      ex.printStackTrace(); 
     } 
    } 
} 
6

Sử dụng this để có được hàng và cột

Thêm một DocumentFilter mà kiểm tra số lượng hàng (vượt qua doc.getLength() bù đắp) và ngăn chặn thêm nhiều văn bản hơn.

Hoặc bạn có thể tạo JTextArea ẩn hình giả và thêm tất cả văn bản vào đó. Sau đó đo dòng cho phép cuối cùng và cắt văn bản.

+0

+1 cho 'DocumentFilter' và nhanh hơn. :-) – trashgod

+0

tò mò: tại sao lại sử dụng phương thức tiện ích thay vì textArea.getLine/Start/OfOffset? – kleopatra

+0

hach ​​... nghĩ rằng tôi đã tìm thấy nó: các dòng được xử lý trong các phương thức đó là các dòng-giữa-cr, không phải là các dòng thực tế khi chúng xuất hiện trong khung nhìn được bọc không? Nếu đó là sự thật ... cái gì-a-crap ... – kleopatra

6

Dưới đây là một DocumentFilter thô có vẻ hoạt động. Cách tiếp cận cơ bản của nó là để cho phép chèn/nối thêm xảy ra, truy vấn số lượng các dòng sau khi thực tế, nếu nhiều hơn, tối đa, loại bỏ các dòng từ đầu khi thích hợp.

Hãy coi chừng: các dòng được tính bằng các phương thức textArea (có thể nhất là, chờ xác nhận từ @Stani) dòng-giữa-cr, không phải các dòng thực tế như được bố cục. Tùy thuộc vào yêu cầu chính xác của bạn, họ có thể hoặc có thể không phù hợp với bạn (nếu không, sử dụng phương pháp hữu ích của Stan)

Tôi rất ngạc nhiên và không hoàn toàn chắc chắn nếu nó an toàn

  • ngạc nhiên: phương pháp chèn isn' được gọi là, cần thiết để thực hiện phương pháp thay thế (trong mã sản phẩm sẵn sàng có thể cả hai)
  • không chắc chắn textArea có được trả về giá trị cập nhật trong phương pháp lọc hay không. gói trong một invokeLater)

Một số mã:

public class MyDocumentFilter extends DocumentFilter { 

    private JTextArea area; 
    private int max; 

    public MyDocumentFilter(JTextArea area, int max) { 
     this.area = area; 
     this.max = max; 
    } 

    @Override 
    public void replace(FilterBypass fb, int offset, int length, 
      String text, AttributeSet attrs) throws BadLocationException { 
     super.replace(fb, offset, length, text, attrs); 
     int lines = area.getLineCount(); 
     if (lines > max) { 
      int linesToRemove = lines - max -1; 
      int lengthToRemove = area.getLineStartOffset(linesToRemove); 
      remove(fb, 0, lengthToRemove); 
     } 
    } 
} 

// usage 
JTextArea area = new JTextArea(10, 10); 
((AbstractDocument) area.getDocument()).setDocumentFilter(new MyDocumentFilter(area, 3)); 
1

Cách tiếp cận của tôi hoạt động với nội dung của JTextPane dưới dạng tài liệu. Nó giả định rằng chương trình của bạn đã được thêm văn bản vào cuối tài liệu hơn và hơn, để khi bạn gọi doc.getCharacterElement (1), bạn sẽ nhận được về cơ bản một phần tử lá đại diện cho dòng mã sớm nhất. Đây là những gì chúng tôi muốn xóa, vì vậy sau đó chúng tôi nhận được sự bắt đầu và kết thúc offsets của yếu tố đó, và gọi phương pháp loại bỏ để cắt văn bản đầu tiên.

Điều này có thể được thực hiện có chọn lọc bằng cách kiểm tra xem tổng số ký tự có lớn hơn một triệu (như tôi đã làm bên dưới) hay dựa trên số dòng bạn đã thêm.

Nếu bạn muốn dựa trên số dòng đã thêm, bạn sẽ cần trường được tăng mỗi lần bạn in với JTextPane, để mã này chạy mỗi khi bạn in dòng văn bản mới và số vượt quá giá trị tối đa của bạn.

 JTextPane pane = ... 
     StyledDocument doc = pane.getStyledDocument(); 
     int size = doc.getLength(); 
     if (size > 1000000) { 
      out.println("Size: " + size); 
      out.println(":" + 1); 
      int i = 0; 
      Element e = doc.getCharacterElement(i + 1); 
      int start = e.getStartOffset(); 
      int end = e.getEndOffset(); 

      try { 
       doc.remove(start, end); 
      } catch (BadLocationException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 
     } 

Chúc mừng!

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