如何计算JTextArea中的行数,包括由包装引起的行数?

pes*_*kal 10 java textarea awt jtextarea

我有一个JTextArea,我已将word-wrap和wrap-style-word设置为true.我希望将JTextArea"打包"到给定指定宽度的最小可能高度.

为此,我正在计划使用...计算字体的高度

  Font font = jTextArea.getFont();
  FontMetrics fontMetrics = jTextArea.getFontMetrics(font);
  int lineHeight = fontMetrics.getAscent() + fontMetrics.getDescent();
Run Code Online (Sandbox Code Playgroud)

...然后将其乘以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();                                                                   
      }                                                                                       
    });                                                                                       
  }                                                                                           
}                                                                                             
Run Code Online (Sandbox Code Playgroud)

sgo*_*les 5

你可以使用LineBreakMeasurerClass.

LineBreakMeasurer类允许将样式文本分解为适合特定视觉前进的线条(或线段).这对于希望显示适合特定宽度的文本段的客户端非常有用,称为包装宽度.LineBreakMeasurer实现了最常用的换行策略:适合包装宽度的每个单词都放在行上.如果第一个单词不适合,那么适合包装宽度的所有字符都放在该行上.每行至少放置一个字符.