5

アプリケーションにテキスト フィールドがあります。テキスト フィールドであるにもかかわらず、ユーザーは大量のテキストを貼り付けることがあります。さらに、問題の他の関数も大量に設定されます。

テキストが多すぎて、JVM が fontmanager.dll でアクセス違反を起こすことがあります。オラクルは問題自体の修正に関心を持っていないようですので、少なくとも回避したいと思います。

ユーザーが入力するテキストの量を制限することは明らかに受け入れられません (そうでなければ、これが最も明白な解決策です) が、設定を許可してからテキスト フィールドを無効にすることは受け入れられます。テキストがモデルにバインドされると、テキスト全体が再び含まれる必要があります。

これは本質的にビューのバグであるため、モデルで回避してそこに追加のプロパティを追加するのではなく、ビューで修正する必要があると考えました。

私の最初の試みは次のようなものでした:

public class LimitedTextField extends JTextField {
    static final int LIMIT = 10000;
    private String fullString;

    @Override
    public void setText(String text) {
        if (text != null && text.length() > LIMIT) {
            fullString = text;
            setEnabled(false);
        } else {
            fullString = null;
            super.setText(text);
            setEnabled(true);
        }
    }

    @Override
    public String getText() {
        if (fullString != null) {
            return fullString;
        } else {
            return super.getText();
        }
    }
}

これは単純な単体テストに合格しますが、BeansBinding の追加テストを作成したところ、BeansBinding はテキスト プロパティにバインドされず、ドキュメントにバインドされ、テキスト プロパティをシミュレートするため、機能しないことがわかりました。したがって、実際には getText() はそのテストで常に空の文字列を返します。

私は今、私が望むことを行う Document 実装を作成しようとしていますが、ドキュメントレベルでこの種のトリックを行うのは確かに簡単ではありません. 私はそれが持っているすべてのメソッドを見ることができますが、getText() を呼び出すときにそのテキストを使用できないようにせずにテキストを制限する良い方法を見つけることができません。

4

3 に答える 3

1

JTextField を使用する代わりに、1 行の JTextArea を使用できます。次に、ドキュメントに改行文字を挿入できます。次に、テキストがペイントされると、1 行だけが表示されます。

改行文字を削除するには、おそらく getText() メソッドもオーバーライドする必要があります。参考になるかどうかはわかりませんが、別の方向に考えさせられるかもしれません。

于 2010-08-05T14:52:17.987 に答える
1

Limited Length Document は非常に簡単に実行できます。もちろん、いくつかのアプローチがあります。これが最も単純なものです (私たちの環境で本番環境で動作します)。

package com.twist.ui.text.document;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class LimitedLengthDocument extends PlainDocument {
    private static final long serialVersionUID = 1L;

    private int limit;

    public LimitedLengthDocument(int limit) {
        super();
        this.limit = limit;
    }

    public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
        if (str == null)
            return;

        // insert the string as usual.
        super.insertString(offset, str, attr);

        // If user tries to paste in a String that will not fit into the textfield, this approach will 
        // insert the text and remove the extra characters from the right.      

        // if resultant doc length is greater than the allowable size, truncate the document.
        if( getLength() > limit  )
            super.remove(limit, getLength() - limit);
    }
}
于 2010-08-05T19:49:26.160 に答える
1

これは間違いなく難しいものです。あまり多くのテキストをレンダリングしようとしない以外は、最小限の影響でフィールドの描画に影響を与えたいと考えています。私が持っている唯一の提案は、独自の描画戦略の作成を検討することです ( http://forums.sun.com/thread.jspa?threadID=481290を参照)。テキストが描画される場所には、文字のサブセットを描画するだけです。 . テキスト コンポーネントを描画するために新しい UIDelegate を構築しようとすることも考えられますが、それもかなり難しいかもしれません。このペイントの概要は、カスタム ペイントに関してガイドするのに役立つ場合があります。この記事は、すべてのテキスト フィールドまたは修正しようとしているテキスト フィールドだけにカスタム UI デリゲートを適用する方法について説明します。

于 2010-08-05T08:02:22.927 に答える