Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change the color of specific words in a JTextPane?

How do I change the color of specific words in a JTextPane just while the user is typing? Should I override JTextPane paintComponent method?

like image 843
Soheil Avatar asked Jan 18 '13 14:01

Soheil


People also ask

How do I change textarea text color in Java?

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.


2 Answers

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:

enter image description here

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.

like image 71
shuangwhywhy Avatar answered Sep 25 '22 17:09

shuangwhywhy


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.

like image 41
Dan D. Avatar answered Sep 25 '22 17:09

Dan D.