serg.nechaev
serg.nechaev

Reputation: 1321

How to get number of visible lines in JTextArea with line wrap enabled?

I am wondering how it is possible to get the number of visible lines in JTextArea when line wrap is set to true?

Upvotes: 1

Views: 1183

Answers (1)

camickr
camickr

Reputation: 324118

What is your definition of "visible lines"? For example what if:

  1. half of a line is displayed. Does it count as a line or not?
  2. half of a wrapped line is displayed. Does it count as a line or not?

Anyway, I think the way to approach is to use the location of the viewport and the viewToModel() method to get the offsets off the text on the first and last line displayed in the viewport.

Then you can use the Element structure of the document to determine the line number of these offsets. Once you know the line numbers you calculate the difference between the line numbers.

Finally depending on your answers to my questions above, you adjust the line number as required.

Here is the basics to get you started:

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

public class TestTextArea {

    public static void main(String[] args) {
        new TestTextArea();
    }

    public TestTextArea() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestTextAreaPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestTextAreaPane extends JPanel {

        private JTextArea textArea;

        public TestTextAreaPane() {
            setLayout(new BorderLayout());
            textArea = new JTextArea(20, 100);
            textArea.setWrapStyleWord(true);
            textArea.setLineWrap(true);

            try
            {
                FileReader reader = new FileReader( "TestTextArea.java" );
                BufferedReader br = new BufferedReader(reader);
                textArea.read( br, null );
                br.close();
            }
            catch(Exception e2) { System.out.println(e2); }

            JScrollPane scrollPane = new JScrollPane(textArea);
            add(scrollPane);
            scrollPane.getViewport().addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {
                    if (textArea.getText().length() > 0) {
                        JViewport viewport = (JViewport) e.getSource();
                        Rectangle viewRect = viewport.getViewRect();

                        Point p = viewRect.getLocation();
                        int startIndex = textArea.viewToModel(p);

                        int lineHeight = textArea.getFontMetrics( textArea.getFont() ).getHeight();
                        p.y += viewRect.height - lineHeight;
                        int endIndex = textArea.viewToModel(p);

                        Element root = textArea.getDocument().getDefaultRootElement();
                        int startLine =  root.getElementIndex( startIndex );
                        int endLine =  root.getElementIndex( endIndex );
                        int lines = endLine - startLine + 1;
                        System.out.println(lines);
                    }
                }
            });
        }
    }
}

Upvotes: 3

Related Questions