问题
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?
回答1:
You can also use a Highlighter
, discussed in How to Use Text Fields: Another Example: TextFieldDemo.
回答2:
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);
}
}
回答3:
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
回答4:
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.
来源:https://stackoverflow.com/questions/8159552/find-the-offset-to-a-string-in-a-jtextpane