2012-08-28 37 views
7

メッセージを表示するJTextAreaと、各メッセージが1行に書き込まれ、必要に応じてワードラッピングされるサービス用のGUIを作成しようとしています。JTextAreaの行数を制限する方法は?

メッセージはソケット経由で届くので、JTextAreaを更新するために使用している単なる.append(メッセージ)です。これらの行を50または100に制限する必要があります。文字数を制限する必要はありません各行。

JTextAreaの行数を制限する方法がある場合、または代替方法がある場合は、

私は本当にこの問題の支援を利用することができました。

編集

問題は、各クライアントが無限のラインを送ることができるということである、すべてのこれらの行は読みやすいように持っているので、これはJTextAreaにの行数の簡単なチェックではありません。新しい行を表示するには古い行を削除する必要があります。

+0

jtextareaの行にいくつの文字が許可されているか分かっている場合は、jtextareaの合計文字数で除算するだけです –

+0

関連:http://stackoverflow.com/questions/479182/how-to-limit- JTextAreaに-MAX-行-と-coloums – CloudyMarble

+0

それは私が、この場合に限定するために必要なだけの行または列ですので、文字の数は、一種の無関係です。 –

答えて

6

これが効率的でしょうか?

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

使用thisが行と列

行の量を(doc.getLengthを(パス)オフセット)をチェックDocumentFilterを追加し、より多くのテキストを追加防ぐ取得します。

または、ダミーの非表示のJTextAreaを作成し、そこにすべてのテキストを追加することができます。最後に許可された行を測定し、テキストをカットします。

+0

「DocumentFilter」の場合は+1、高速の場合:-) – trashgod

+0

好奇心:なぜ、textArea.getLine/Start/OfOffsetの代わりにユーティリティメソッドを使用するのですか? – kleopatra

+0

hach​​ ...私はそれを見つけたと思う:そのメソッドで扱われる行は、行間のcrであり、実際の行はラップされたビューに現れるものではありませんか?それが本当なら...なんとなく... – kleopatra

6

以下は、動作するように見える粗いDocumentFilterです。その基本的なアプローチは、挿入/追加が起きるようにすることです。実際の行の数を照会します。必要に応じて、先頭から行を削除します。

注意:テキストエリアの方法で計数線である(おそらく、@Staniからの確認を待っている)ライン-間-CRはなく、実際のラインをレイアウトされます。あなたの正確な要件に応じて、彼らはまたは

あなたをスイート(そうでない場合は、スタンのユーティリティメソッドを使用)しない場合があり、私はそれが安全

  • だ場合、完全に確認してください驚いたとしませ驚い:insertメソッドのISN」をトンにtextAreaは、フィルタメソッドに最新の値を返すことが保証されている場合(おそらく、その長さのチェックができない代わりに
  • (両方ともおそらく生産準備コードで)わからない置き換える方法を実施するのに必要な、と呼ばれますinvokeLaterでラップ)

コード:

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

私のアプローチは、ドキュメントとしてのJTextPaneのコンテンツで動作します。これは、あなたのプログラムがドキュメントの最後に何度もテキストを追加していることを前提としているので、doc.getCharacterElement(1)を呼び出すと、基本的に最初のコード行を表すリーフ要素が得られます。これを削除したいので、その要素の開始オフセットと終了オフセットを取得し、removeメソッドを呼び出して最も早いテキストを切り取ります。

これは、選択文字の数が百万円(私は以下のように行われている)よりも大きい場合、または既に追加した行の数に基づいて合計するかどうかを確認することで行うことができました。

すでに追加されている行数に基づいている場合は、JTextPaneに印刷するたびにインクリメントされるフィールドが必要になります。そのため、新しいテキスト行を印刷するたびにこのコードが1回実行され、カウントがあなたの最大値を超えています。

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

乾杯!

関連する問題