I'm looking for a quick way to find a String in a JTextPane and change the style there, so it gets highlighted. What I currently have is something like this (tpOutput is the JTextPane in question, strSearch the String to be searched.. duh):
int index = tpOutput.getText().indexOf(strSearch);
StyledDocument doc = tpOutput.getStyledDocument();
doc.setCharacterAttributes(i, strSearch.length(), doc.getStyle("exampleStyle") , false);
However, as beautiful as that would be if it worked, it counts wrong on newline characters, so if I search the text "foobar" in
foobarTTT
abcd123
abcd123
it would highlight "foobar" in the first line correctly. However, in
abcd123
abcd123
foobarTTT
it would highlight "obarTT" (and the following 2 whitespaces if they exist)
I'm probably doing the whole thing wrong, trying to get the offset easy using just the text. Anyone know the proper way to do this?
You can also use a Highlighter
, discussed in How to Use Text Fields: Another Example: TextFieldDemo.
IndexOutOfBounds
is maybe from doc.getStyle("exampleStyle")
, by using MutableAttributeSet works for me,
can you demonstrated your issue with IndexOutOfBounds
by using this SSCCE
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class TextPaneAttributes extends JFrame {
private static final long serialVersionUID = 1L;
public TextPaneAttributes() {
final JTextPane textPane = new JTextPane();
StyledDocument doc = textPane.getStyledDocument();
final MutableAttributeSet standard = new SimpleAttributeSet();
StyleConstants.setAlignment(standard, StyleConstants.ALIGN_CENTER);
doc.setParagraphAttributes(0, 0, standard, true);
MutableAttributeSet keyWord = new SimpleAttributeSet();
StyleConstants.setForeground(keyWord, Color.red);
StyleConstants.setItalic(keyWord, true);
textPane.setText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\n");
doc.setCharacterAttributes(0, 3, keyWord, false);
doc.setCharacterAttributes(19, 4, keyWord, false);
try {
doc.insertString(0, "Start of text\n", null);
doc.insertString(doc.getLength(), "End of text\n", keyWord);
} catch (Exception e) {
}
final MutableAttributeSet selWord = new SimpleAttributeSet();
StyleConstants.setForeground(selWord, Color.blue);
StyleConstants.setItalic(selWord, true);
JScrollPane scrollPane = new JScrollPane(textPane);
scrollPane.setPreferredSize(new Dimension(200, 200));
add(scrollPane);
JToggleButton toggleButton = new JToggleButton("where is 'four'");
toggleButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent actionEvent) {
//AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
//boolean selected = abstractButton.getModel().isSelected();
int index = textPane.getText().indexOf("four");
StyledDocument doc = textPane.getStyledDocument();
doc.setCharacterAttributes(index, 4, selWord, false);
}
});
add(toggleButton, BorderLayout.SOUTH);
}
public static void main(String[] args) {
Runnable doRun = new Runnable() {
@Override
public void run() {
TextPaneAttributes frame = new TextPaneAttributes();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(doRun);
}
}
my guess: maybe there's a difference in what newline characters are used in JTextPane and StyledDocument, let's say JTextPane uses \n
and StyledDocument uses \r\n
I observed the same thing and I used this code to adjustment:
private int countCarrierReturns(StringBuilder sb, int end) {
final String cr = "\r";
int lines = 0;
int init = sb.indexOf(cr, 0);
if (init == -1) {
return 0;
}
while (init < end) {
lines++;
init = sb.indexOf(cr, init + 1);
}
return lines;
}
the 'int end
' is my first char to apply style.