2

JTextArea コンポーネントの行間隔を変更する方法を見つけようとしています。

少し検索すると、「代わりに JTextPane を使用してから setParagraphAttributes を呼び出す」という同じ答えが常に明らかになるようです。

しかし、たとえばフォントをいじることによって、JTextAreaだけでこれを達成できるかどうか疑問に思っています。

このderiveFont(...)方法では、フォントのトラッキングとカーニング、つまり文字間の水平方向の間隔を変更することができますが、垂直方向の間隔 (おそらくアセント、ディセント、リーディング) を変更する方法を見つけることができませんでした。私はそこに何か欠けていますか?

4

2 に答える 2

6

camickr が指摘しJTextAreaたように、行の高さを直接変更する方法はありません。対応する によって提供されるフォントの高さを使用するだけですFontMetrics

ただし、これにより、次のヘルパー クラスを使用した攻撃の可能性が残されます。

public class FontMetricsWrapper extends FontMetrics {

    private final FontMetrics target;

    public FontMetricsWrapper(FontMetrics target) {
        super(target.getFont());
        this.target = target;
    }

    @Override
    public int bytesWidth(byte[] data, int off, int len) {
        return target.bytesWidth(data, off, len);
    }

    @Override
    public int charWidth(char ch) {
        return target.charWidth(ch);
    }

    @Override
    public int charWidth(int codePoint) {
        return target.charWidth(codePoint);
    }

    // ... tons more @Override's, all of the same form:
    //
    // @Override
    // public baz foo(bar, ...) {
    //     return target.foo(bar, ...);
    // }

}

次に、次のように JTextArea を作成することが可能になります。

JTextArea myTextArea = new JTextArea("Some text") {
    @Override
    public FontMetrics getFontMetrics(Font font) {
        return new FontMetricsWrapper(super.getFontMetrics(font)) {
            @Override
            public int getHeight() {
                return 10;  // Gives line height in pixels
            }
        };
    }
};

これは間違いなく最もクリーンなソリューションではなく、単に概念実証を目的としています。たとえば、getFontMetrics(...)非常に頻繁に呼び出される問題の 1 つは、この例では毎回ラッパー クラスの新しいインスタンスを作成することです。したがって、少なくとも、FontMetricsWrapper特定のフォントごとに作成されたものをキャッシュする HashMap が適切です...

しかし、私が本当に望んでいたのは、行の高さを変更するために JTextArea に渡された、Fontまたは関連するを操作する方法でした。FontRenderContextたとえば、報告されたフォントのアセント、ディセント、リーディング値に影響を与える方法はありますか? これを除いて、フォントの外観の他のほとんどの側面を変更できるのは奇妙に思えます...

于 2013-07-20T17:12:52.473 に答える
2

軽量コーディングの何が問題になっていますか?

ジョブには最も単純なコンポーネントを使用する必要があります。ただし、単純なコンポーネントが要件をサポートしていない場合は、通常、要件がより複雑であり、機能を実装するにはより複雑なコンポーネントが必要なためです。クラスのプロパティを設定するのがこれほど簡単なことはめったにありません。

時々、何か新しいことを学び、何が可能かを理解することに単純に興味があります。

Swing テキスト コンポーネントは、 を使用しViewてテキストを描画します。テキストのフォーマットと配置は、ビューの責任です。したがって、各ビューは、次の行をいつ折り返すか、どこに配置するかを決定します。

JTextArea の場合、Plainview または WrappedPlanView のいずれかを使用します。Plainview の場合、描画コードは次のとおりです。

drawLine(line, g, x, y);
y += fontHeight;

ここで、fontHeight は FontMetrics.getHeight() メソッドを使用して決定されます。

したがって、値は基本的にビューでハードコードされています。テキスト領域にカスタム ビューをいつでも提供できますが、ビューをオーバーライドするのは一般的に簡単な作業ではありません。

于 2013-07-20T16:33:04.237 に答える