Как подсчитать количество строк в JTextArea, включая те, что вызваны переносом?

У меня есть JTextArea, для которой я установил word-wrap и wrap-style-word в значение true. Я хочу «упаковать» JTextArea до минимально возможной высоты при заданной ширине.

Для этого я планирую вычислить высоту шрифта, используя ...

  Font font = jTextArea.getFont();
  FontMetrics fontMetrics = jTextArea.getFontMetrics(font);
  int lineHeight = fontMetrics.getAscent() + fontMetrics.getDescent();

... и затем умножить это на количество строк, используемых в JTextArea. Проблема в том, что JTextArea.getLineCount () подсчитывает количество строк, возвращаемых без учета обернутых строк.

Как мне подсчитать количество строк, используемых в JTextArea, включая те, которые вызваны переносом слов?

Вот демонстрационный код, который упрощает решение этой проблемы. У меня есть слушатель, который выводит количество строк каждый раз при изменении размера окна. На данный момент он всегда печатает 1, но я хочу компенсировать перенос слов и распечатать, сколько строк фактически используется.

РЕДАКТИРОВАТЬ: Я включил решение проблемы в приведенный ниже код. Статический метод countLines дает решение.

package components;                                                                           

import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.text.*;
import javax.swing.*;

public class JTextAreaLineCountDemo extends JPanel {                                          
  JTextArea textArea;                                                                         

  public JTextAreaLineCountDemo() {                                                           
    super(new GridBagLayout());                                                               

    String inputStr = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmo";
    textArea = new JTextArea(inputStr);                                                       
    textArea.setEditable(false);                                                              
    textArea.setLineWrap(true);                                                               
    textArea.setWrapStyleWord(true);                                                          

    // Add Components to this panel.                                                          
    GridBagConstraints c = new GridBagConstraints();                                          
    c.gridwidth = GridBagConstraints.REMAINDER;                                               

    c.fill = GridBagConstraints.BOTH;                                                         
    c.weightx = 1.0;                                                                          
    c.weighty = 1.0;                                                                          
    add(textArea, c);                                                                         

    addComponentListener(new ComponentAdapter() {                                             
      @Override                                                                               
      public void componentResized(ComponentEvent ce) {                 
        System.out.println("Line count: " + countLines(textArea));                         
      }                                                                                       
    });                                                                                       
  }                                                                                           

  private static int countLines(JTextArea textArea) {
    AttributedString text = new AttributedString(textArea.getText());
    FontRenderContext frc = textArea.getFontMetrics(textArea.getFont())
        .getFontRenderContext();
    AttributedCharacterIterator charIt = text.getIterator();
    LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc);
    float formatWidth = (float) textArea.getSize().width;
    lineMeasurer.setPosition(charIt.getBeginIndex());

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

    return noLines;
  }

  private static void createAndShowGUI() {                                                    
    JFrame frame = new JFrame("JTextAreaLineCountDemo");                                      
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                                     

    frame.add(new JTextAreaLineCountDemo());                                                  

    frame.pack();                                                                             
    frame.setVisible(true);                                                                   
  }                                                                                           

  public static void main(String[] args) {                                                    
    javax.swing.SwingUtilities.invokeLater(new Runnable() {                                   
      public void run() {                                                                     
        createAndShowGUI();                                                                   
      }                                                                                       
    });                                                                                       
  }                                                                                           
}                                                                                             
10
задан Rodrigo 19 January 2013 в 00:57
поделиться