Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Scroll to specific text inside JTextArea

I'm trying to implement a feature inside the current program that I'm writing and I wanna learn how to scroll down to specific text inside a JTextArea. For example, lets say I have the following:

JTextArea area = new JTextArea(someReallyLongString);

someReallyLongString would represent a paragraph, or a very large piece of text (in which the vertical scrollbar would be visible). And so what I am trying to do is scroll down to specific text within that text area. For example, lets say someReallyLongString contained the word "the" near the middle of the scrollbar (meaning this word is not visible), how would I scroll down to that specific text?

Thanks, any help would be greatly appreciating.

like image 626
Josh M Avatar asked Nov 18 '12 05:11

Josh M


3 Answers

This is a VERY basic example. This basically walks the document to find the position of the word within the document and ensures that the text is moved to the viewable area.

It also highlights the match

enter image description here

public class MoveToText {

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

    public MoveToText() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new FindTextPane());
                frame.setSize(400, 400);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class FindTextPane extends JPanel {

        private JTextField findField;
        private JButton findButton;
        private JTextArea textArea;
        private int pos = 0;

        public FindTextPane() {
            setLayout(new BorderLayout());
            findButton = new JButton("Next");
            findField = new JTextField("Java", 10);
            textArea = new JTextArea();
            textArea.setWrapStyleWord(true);
            textArea.setLineWrap(true);

            Reader reader = null;
            try {
                reader = new FileReader(new File("Java.txt"));
                textArea.read(reader, null);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    reader.close();
                } catch (Exception e) {
                }
            }

            JPanel header = new JPanel(new GridBagLayout());

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.anchor = GridBagConstraints.WEST;
            header.add(findField, gbc);
            gbc.gridx++;
            header.add(findButton, gbc);

            add(header, BorderLayout.NORTH);
            add(new JScrollPane(textArea));

            findButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    // Get the text to find...convert it to lower case for eaiser comparision
                    String find = findField.getText().toLowerCase();
                    // Focus the text area, otherwise the highlighting won't show up
                    textArea.requestFocusInWindow();
                    // Make sure we have a valid search term
                    if (find != null && find.length() > 0) {
                        Document document = textArea.getDocument();
                        int findLength = find.length();
                        try {
                            boolean found = false;
                            // Rest the search position if we're at the end of the document
                            if (pos + findLength > document.getLength()) {
                                pos = 0;
                            }
                            // While we haven't reached the end...
                            // "<=" Correction
                            while (pos + findLength <= document.getLength()) {
                                // Extract the text from teh docuemnt
                                String match = document.getText(pos, findLength).toLowerCase();
                                // Check to see if it matches or request
                                if (match.equals(find)) {
                                    found = true;
                                    break;
                                }
                                pos++;
                            }

                            // Did we find something...
                            if (found) {
                                // Get the rectangle of the where the text would be visible...
                                Rectangle viewRect = textArea.modelToView(pos);
                                // Scroll to make the rectangle visible
                                textArea.scrollRectToVisible(viewRect);
                                // Highlight the text
                                textArea.setCaretPosition(pos + findLength);
                                textArea.moveCaretPosition(pos);
                                // Move the search position beyond the current match
                                pos += findLength;
                            }

                        } catch (Exception exp) {
                            exp.printStackTrace();
                        }

                    }
                }
            });

        }
    }
}
like image 174
MadProgrammer Avatar answered Sep 20 '22 21:09

MadProgrammer


This should work:

textArea.setCaretPosition(posOfTextToScroll);

You can get the posOfTextToScroll by the Document model. Read about it, in the Javadoc.

like image 25
Mordechai Avatar answered Sep 20 '22 21:09

Mordechai


First get the text you set in the text area and build an index using a map to hold the character and the position you find it on.

Based on this the previous answer suggested used the setCaretPosition using the value retrieved from the map.

like image 32
dinukadev Avatar answered Sep 19 '22 21:09

dinukadev