1

使用する自由な時間がかなりありましたが、JTextPane の一部としての StyledDocument に関する問題に遭遇しました。ドキュメントの合計サイズが値 x (私の場合は 10.000) に達したときに、テキストの最初の部分を削除したいと考えています。ただし、レイアウトが維持されていることが重要なので、最初に画像で何が起こるかを示してから、ソースを投稿します。

画像 1: 最大長にまだ達していない場合、水平スクロールバーはありません

画像 2: 最大長の 10.000 文字に達し、StyledDocument が styleddoc.getDocument().remove(0, maxsize); でトリミングされた場合。

http://i.stack.imgur.com/i10KZ.png【画像1】

http://i.stack.imgur.com/dUZ0K.png【画像2】

(大変申し訳ございませんが、こちらで初めての質問のため、スパム対策のため画像の掲載はお断りさせていただいております)

ご覧のとおり、水平スクロールバーが突然表示され、レイアウトが完全に台無しになり、削除前のようにテキストが収まらない場合、テキストがきれいに複数の行に分割されることはありません。

さて、これが私のソースです。この問題に対する天才的な解決策を見つけるのを手伝ってください。

public void publicTextPaneOutput(String sender, String receiver, int type, String message) {
    int messagesize = 0;
    StyledDocument styledDocument = (StyledDocument) publicText.getDocument();
    Style defaultStyle = styledDocument.addStyle("Default Text", null);
    Style nicknameStyle = styledDocument.addStyle("Personal Nickname", null);
    StyleConstants.setBold(nicknameStyle, true);
    StyleConstants.setForeground(nicknameStyle, Color.decode("#006400"));
    Style chatterStyle = styledDocument.addStyle("Other Nickname", null);
    StyleConstants.setBold(chatterStyle, true);
    StyleConstants.setForeground(chatterStyle, Color.blue);

    switch (type) {
        case 1: {
            messagesize += sender.length() + message.length() + 3;
            publicTextPaneOverflowProtection(styledDocument, messagesize);
            try {
                if (sender.equals(nickname)) {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), nicknameStyle);
                } else {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), chatterStyle);
                }
                styledDocument.insertString(styledDocument.getLength(), ": ", chatterStyle);
                styledDocument.insertString(styledDocument.getLength(), message, defaultStyle);
                styledDocument.insertString(styledDocument.getLength(), "\n", defaultStyle);
            } catch (BadLocationException e) {
                e.printStackTrace();
            }
            break;
        }
        case 2: {
            messagesize += sender.length() + receiver.length() + message.length() + 7;
            publicTextPaneOverflowProtection(styledDocument, messagesize);
            try {
                if (sender.equals(nickname)) {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), nicknameStyle);
                } else {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(sender).toString(), chatterStyle);
                }
                styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(" -> ").toString(), chatterStyle);
                if (receiver.equals(nickname)) {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(receiver).toString(), nicknameStyle);
                } else {
                    styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(receiver).toString(), chatterStyle);
                }
                styledDocument.insertString(styledDocument.getLength(), (new StringBuilder()).append(": ").toString(), chatterStyle);
                styledDocument.insertString(styledDocument.getLength(), message, defaultStyle);
                styledDocument.insertString(styledDocument.getLength(), "\n", defaultStyle);

            } catch (BadLocationException e) {
                e.printStackTrace();
            }
            break;
        }
    }
    scroll();
}

private void publicTextPaneOverflowProtection (StyledDocument styledDocument, int messagesize)
{
    if(styledDocument.getLength() + messagesize > 10000) {
        try {
            styledDocument.remove(0, messagesize);
        } catch (BadLocationException e) {

        }
    }

}

public void scroll() {
    StyledDocument styleddocument = (StyledDocument) publicText.getDocument();
    publicText.setCaretPosition(styleddocument.getLength());
}

// this part is coded in the class itself

private JTextPane publicText;
private JScrollPane publicTextScrollPane;

//this is coded in the constructor of the class
publicText = new JTextPane();
publicTextScrollPane = new JScrollPane();

publicText.setEditable(false);
publicTextScrollPane.setViewportView(publicText);

私のプロジェクトの特定の部分の追加コードが必要な場合は、できるだけ早く教えてください

私が望む解決策は、StyledDocument の先頭にあるこのテキストの削除を実装し、配置された \n 文字を考慮に入れる必要があります。一部が削除されたとしてもです。スタイル付きのドキュメントの代わりに単純な「ドキュメント」を使用するなど、いくつかのことを試しましたが、チャットアプレットで色と絵文字の使用を実装する予定であるため、これはオプションではありません。

これを調べてくれたすべての人に事前に感謝します!可能な限りフォローします。

敬具、 スティーブン・カスターズ

PS .: StyledDocument の一部を削除するのはなぜですか? メモリ管理。これは、最大 200 人が同時に使用できるチャット アプレットの一部であるためです。全員が 10 秒ごとに何かを言うと、1 分後には 1200 件のメッセージが表示されるため、大量のメモリを使用します。これは、たとえば 10 時間続きます: 推定最大負荷として 720.000 メッセージ。(最悪のシナリオ(または最良のシナリオ、視点によって異なります))

4

1 に答える 1

1

あなたの質問にはさまざまな部分がありますが、1 つの部分は簡単に修正できる場合があります。あなたの主な関心事は、ドキュメントから行を削除する方法のようです。この側面を処理する DocumentListener が実装されています。LimitLinesDocumentListenerを確認してください。そのページはクラスのソースにリンクしており、ドキュメントから行を削除する方法の例も含まれています。

于 2013-09-26T18:00:34.390 に答える