为了做到这一点,我计划使用…来计算字体的高度
Font font = jTextArea.getFont(); FontMetrics fontMetrics = jTextArea.getFontMetrics(font); int lineHeight = fontMetrics.getAscent() + fontMetrics.getDescent();
…然后将其乘以JTextArea中使用的行数.问题是JTextArea.getLineCount()计算忽略包装线的行返回数.
如何计算JTextArea中使用的行数,包括由word wrap引起的行数?
这里有一些演示代码让这个问题变得更容易.我有一个监听器,每次窗口调整大小时打印出行数.目前,它总是打印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(); } }); } }
解决方法
LineBreakMeasurer
类.
The LineBreakMeasurer class allows styled text to be broken into lines (or segments) that fit within a particular visual advance. This is useful for clients who wish to display a paragraph of text that fits within a specific width,called the wrapping width.LineBreakMeasurer implements the most commonly used line-breaking policy: Every word that fits within the wrapping width is placed on the line. If the first word does not fit,then all of the characters that fit within the wrapping width are placed on the line. At least one character is placed on each line.