How do I change the color of specific words in a JTextPane
just while the user is typing? Should I override JTextPane
paintComponent
method?
To set the font and color of JTextArea we can use the setFont() and setForeground() methods of the JTextArea . To create a font we must define the font name, the font style and its size. For the colors we can uses the constant color values defined by the Color class.
No. You are not supposed to override the paintComponent() method. Instead, you should use StyledDocument
. You should also delimit the words by your self.
Here is the demo, which turns "public", "protected" and "private" to red when typing, just like a simple code editor:
import javax.swing.*; import java.awt.*; import javax.swing.text.*; public class Test extends JFrame { private int findLastNonWordChar (String text, int index) { while (--index >= 0) { if (String.valueOf(text.charAt(index)).matches("\\W")) { break; } } return index; } private int findFirstNonWordChar (String text, int index) { while (index < text.length()) { if (String.valueOf(text.charAt(index)).matches("\\W")) { break; } index++; } return index; } public Test () { setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(400, 400); setLocationRelativeTo(null); final StyleContext cont = StyleContext.getDefaultStyleContext(); final AttributeSet attr = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, Color.RED); final AttributeSet attrBlack = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, Color.BLACK); DefaultStyledDocument doc = new DefaultStyledDocument() { public void insertString (int offset, String str, AttributeSet a) throws BadLocationException { super.insertString(offset, str, a); String text = getText(0, getLength()); int before = findLastNonWordChar(text, offset); if (before < 0) before = 0; int after = findFirstNonWordChar(text, offset + str.length()); int wordL = before; int wordR = before; while (wordR <= after) { if (wordR == after || String.valueOf(text.charAt(wordR)).matches("\\W")) { if (text.substring(wordL, wordR).matches("(\\W)*(private|public|protected)")) setCharacterAttributes(wordL, wordR - wordL, attr, false); else setCharacterAttributes(wordL, wordR - wordL, attrBlack, false); wordL = wordR; } wordR++; } } public void remove (int offs, int len) throws BadLocationException { super.remove(offs, len); String text = getText(0, getLength()); int before = findLastNonWordChar(text, offs); if (before < 0) before = 0; int after = findFirstNonWordChar(text, offs); if (text.substring(before, after).matches("(\\W)*(private|public|protected)")) { setCharacterAttributes(before, after - before, attr, false); } else { setCharacterAttributes(before, after - before, attrBlack, false); } } }; JTextPane txt = new JTextPane(doc); txt.setText("public class Hi {}"); add(new JScrollPane(txt)); setVisible(true); } public static void main (String args[]) { new Test(); } }
The code is not so beautiful since I typed it quickly but it works. And I hope it will give you some hint.
Overwriting paintComponent
will not help you.
This is not an easy one, but not impossible either. Something like this will help you:
DefaultStyledDocument document = new DefaultStyledDocument(); JTextPane textpane = new JTextPane(document); StyleContext context = new StyleContext(); // build a style Style style = context.addStyle("test", null); // set some style properties StyleConstants.setForeground(style, Color.BLUE); // add some data to the document document.insertString(0, "", style);
You may need to tweak this, but at least it shows you where to start.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With