Не используйте тему. Вы используете поток только для трудоемких задач. Поиск текстовой строки не является трудоемкой задачей. Кроме того, необходимо обновить обновления компонентов Swing на EDT. Таким образом, вы хотите, чтобы выделение было сделано на EDT.
Не используйте grabFocus (). Вы уже использовали requestFocusInWindow (), который является правильным методом для использования.
Используйте метод String.indexOf(…)
(как предложено @ControlAltDel). Тогда нет необходимости в циклическом коде. Вы просто ищете текст с текущей позиции каретки, и вы либо находите слово, либо нет.
Для чего бы это ни стоило, у меня есть старый код, который делает это:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class TextComponentFindNext extends JFrame implements ActionListener
{
JTextComponent textComponent;
JTextField textField;
public TextComponentFindNext()
throws Exception
{
textComponent = new JTextPane();
JScrollPane scrollPane = new JScrollPane( textComponent );
scrollPane.setPreferredSize( new Dimension(500, 400) );
getContentPane().add(scrollPane, BorderLayout.NORTH);
textField = new JTextField(10);
textField.setText("im");
textField.addActionListener( this );
getContentPane().add(textField, BorderLayout.WEST);
JButton button = new JButton("Find Next");
button.addActionListener( this );
getContentPane().add(button, BorderLayout.EAST);
FileReader reader = new FileReader( "TextComponentFindNext.java" );
BufferedReader br = new BufferedReader(reader);
textComponent.read(br, null);
br.close();
}
public void actionPerformed(ActionEvent e)
{
String searchString = "";
// this works
try
{
Document doc = textComponent.getDocument();
searchString = doc.getText(0, doc.getLength());
}
catch(BadLocationException ble) {}
// this doesn't work
// searchString = textComponent.getText();
int offset = textComponent.getCaretPosition();
String searchText = textField.getText();
int start = searchString.indexOf(searchText, offset);
if (start != -1)
{
textComponent.select(start, start + searchText.length());
textComponent.requestFocusInWindow();
}
}
public static void main(String[] args)
throws Exception
{
JFrame frame = new TextComponentFindNext();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
Нет необходимости в логике прокрутки c, это будет прокручиваться автоматически при выделении текста.
Если вы хотите поиграться с прокруткой, вы можете «центрировать» строку, содержащую текст. Проверьте Утилиты текста , чтобы узнать о некоторых вспомогательных методах, которые позволяют вам это делать.
Обратите внимание, что лучше получать текст из документа, а не из компонентов. Текст из документа содержит только строку "\ n" для конца строки. Это означает, что он будет работать как для JTextArea, так и для JTextPane. См. Текст и новые строки для получения дополнительной информации.