Java - выделите определенный текст внутри JTextArea

Я пытаюсь реализовать функцию внутри текущей программы, которую я пишу, и я хочу научиться прокручивать вниз к определенному тексту внутри JTextArea. Например, допустим, у меня есть следующее:

JTextArea area = new JTextArea(someReallyLongString);

someReallyLongString будет представлять абзац или очень большой фрагмент текста (в котором будет видна вертикальная полоса прокрутки). И вот что я пытаюсь сделать, это прокрутить вниз до определенного текста в этой текстовой области. Например, предположим, что someReallyLongString содержит слово "the" около середины полосы прокрутки (то есть это слово не отображается), как бы прокрутить этот конкретный текст вниз?

Спасибо, любая помощь будет очень благодарна.

3 ответа

Решение

Это ОЧЕНЬ простой пример. Это в основном обходит документ, чтобы найти положение слова в документе, и гарантирует, что текст будет перемещен в видимую область.

Это также подчеркивает матч

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();
                        }

                    }
                }
            });

        }
    }
}

Это должно работать:

textArea.setCaretPosition(posOfTextToScroll);

Вы можете получить posOfTextToScroll посредством Document модель. Читайте об этом в Javadoc.

Сначала получите текст, который вы установили в текстовой области, и создайте индекс, используя карту, чтобы удерживать символ и положение, в котором вы его нашли.

Исходя из этого, предыдущий ответ предложил использовать setCaretPosition, используя значение, извлеченное из карты.

Добавьте к комментарию MadProgrammer:

scrollRectToVisible(viewRect) устарела в Java SE9 и была заменена на scrollRectToVisible2D(viewRect)

Правильный способ отображения текста без использования устаревших функций:

java.awt.geom.Rectangle2D view = area.modelToView2D(pos); // View where pos is visible
area.scrollRectToVisible(view.getBounds()); // Scroll to the rectangle provided by view
area.setCaretPosition(pos); // Sets carat position to pos
Другие вопросы по тегам