在JTextArea(而不是JTextPane)中更改行间距

时间:2013-07-20 13:15:26

标签: java swing fonts jtextarea css

我试图找到一种方法来改变JTextArea组件中的行间距。

一点点搜索似乎总是显示相同的答案:"改为使用JTextPane,然后调用setParagraphAttributes"。

但是我想知道是否可以通过JTextArea实现这一点,例如,弄乱字体。

使用deriveFont(...)方法,可以更改字体的跟踪和字距,即字符之间的水平间距,但我还没有找到办法改变垂直间距(可能是上升,下降,领先)。我错过了什么吗?

2 个答案:

答案 0 :(得分:4)

正如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(...)经常被调用,并且在给定的示例中,每次都会创建一个包装类的新实例。因此,至少,为每个给定字体缓存创建的FontMetricsWrapper的HashMap将按顺序排列......

但是,我真正希望的是使用Font或者传递到JTextArea的相关FontRenderContext来修改行高的方法。例如,有没有办法影响字体报告的上升,下降和领先值?看起来奇怪的是你可以改变字体外观的任何其他方面,除了这个......

答案 1 :(得分:1)

  

轻量编码有什么问题?

没什么,你应该使用最简单的组件来完成工作。但是,如果简单组件不支持需求,通常是因为需求更复杂,并且您需要更复杂的组件来实现功能。设置一个类的属性很少会这么简单。

  

有时我只是对学习新东西并弄清楚什么是可能的感兴趣。

Swing文本组件使用View绘制文本。视图的格式和位置是视图的责任。因此,每个视图确定何时换行以及将下一行放在何处。

对于JTextArea,它使用Plainview或WrappedPlanView。对于Plainview,绘画代码是:

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

其中fontHeight是使用FontMetrics.getHeight()方法确定的。

因此该值基本上是在视图中进行硬编码的。您可以随时为文本区域提供自定义视图,但覆盖视图通常不是一件容易的事。