I'm trying to find a way to change the line spacing in a JTextArea component.
A little bit of searching always seems to reveal the same answer: "Use a JTextPane instead and then call setParagraphAttributes".
But I'm wondering whether it's possible to achieve this with just a JTextArea by, for example, messing with the font.
With the deriveFont(...)
method, it's possible to change the tracking and the kerning of the font, i.e. the horizontal spacing between characters, but I haven't been able to find a way to change the vertical spacing (maybe ascent, descent, leading). Am I missing something there?
As camickr pointed out, JTextArea
does not provide a way to change the line height directly. It simply uses the font height provided by the corresponding FontMetrics
.
But, this leaves a point of attack open using the following helper-class:
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, ...);
// }
}
Then, it becomes possible to create the JTextArea like this:
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
}
};
}
};
This is definitely not the cleanest solution and is merely meant as proof of concept. For example, one issue is that getFontMetrics(...)
is called quite often, and, in the given example, creates a new instance of the wrapper class each time. So, at the very least, a HashMap that caches the created FontMetricsWrapper
for each given font would be in order...
But, what I was really hoping for was a way to play with the Font
or maybe the associated FontRenderContext
passed into the JTextArea to modify the line height. For example, is there some way to influence font's reported ascent, descent, and leading values? Seems strange that you can change pretty much any other aspect of the font's appearance, except this one...