2

我试图可靠地计算给定宽度的 JTextArea 中的行数(包括换行和换行的行数)。我正在使用此信息来设置 GUI 中其他组件的高度(例如,对于 n 行,设置组件的 n*height)。

我偶然发现了这个解决方案(转载如下),但这有一个问题。如果该行上没有太多文本,有时它会错过一行。例如,如果一个宽度为 100 的 JTextArea 有 3 行文本,而在第 3 行它只有大约 15 的文本宽度,那么它将只计算 2 行而不是 3 行。

public class MyTextArea extends JTextArea {

    //...

    public int countLines(int width) {

        AttributedString text = new AttributedString(this.getText());
        FontRenderContext frc = this.getFontMetrics(this.getFont()).getFontRenderContext();
        AttributedCharacterIterator charIt = text.getIterator();
        LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc);
        lineMeasurer.setPosition(charIt.getBeginIndex());

        int noLines = 0;
        while (lineMeasurer.getPosition() < charIt.getEndIndex()) {
            lineMeasurer.nextLayout(width);
            noLines++;
        }

        System.out.print("there are " + noLines + "lines" + System.getProperty("line.separator"));
        return noLines;
    }
}

知道可能导致此问题的原因是什么吗?在 JTextArea 中计算行是否有任何替代方法?谢谢。

4

2 回答 2

2

我正在使用这些信息来设置我的 GUI 中其他组件的高度。

相反,让每个组件采用其首选大小pack()封闭容器。如此处所示,您可以将文本区域添加到大小有限的滚动窗格中,可能是行高的方便倍数。更一般地说,您可以实现此处Scrollable概述的接口。

于 2013-06-09T01:03:06.383 回答
2

所以我想出了一个简单的解决方案,它使用 FontMetrics 来计算文本的显示宽度,通过将文本拆分为字符串标记,我可以计算会有多少行。

public int countLines(int width) {

        FontMetrics fontMetrics = this.getFontMetrics(this.getFont());
        String text = this.getText();
        String[] tokens = text.split(" ");
        String currentLine = "";
        boolean beginningOfLine = true;
        int noLines = 1;

        for (int i = 0; i < tokens.length; i++) {
            if (beginningOfLine) {
                beginningOfLine = false;
                currentLine = currentLine + tokens[i];
            } else {
                currentLine = currentLine + " " + tokens[i];
            }

            if (fontMetrics.stringWidth(currentLine) > width) {
                currentLine = "";
                beginningOfLine = true;
                noLines++;
            }
        }

        System.out.print("there are " + noLines + "lines" + System.getProperty("line.separator"));
        return noLines;
}
于 2013-06-09T02:16:56.187 回答