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

6

28

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

Ecumenism answered 18/1, 2013 at 14:24 Comment(1)
This answer regarding How to colour specific word in JTextPane, might can help you too.Railroader
T
15

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.

Tattered answered 18/1, 2013 at 14:41 Comment(1)
now let me ask other small question here, is it possible to make a JTextPane with only 1 row? just like a JTextFieldEcumenism
L
38

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.

Luncheonette answered 18/1, 2013 at 16:18 Comment(7)
Is there any other way to do same thing without looping?Loblolly
@SachinKumar, Do you mean the loops in findLastNonWordChar and findFirstNonWordChar? Yes, you can find the first non word character without looping, see the answer here, but there is no direct way to find the 'last index of' a non-word character. You can try using split() method.Luncheonette
I am trying same thing using DocumentListener(), but i got an exception "Attempt to mutate in notification". How can i accomplish this using DocumentListener().Loblolly
@SachinKumar, listener is not the same thing here. All the methods in DocumentListener are triggered after updating is happen.Luncheonette
@Luncheonette do you know whether there is a possibility to have colored text in JTextPane ?Esurient
@MrPhi, Yes, but you can only set the same color (the same style, including font size, font family, bold, italic, etc.) to all of the characters in JTextPane.Luncheonette
very useful and interestingDaliladalis
T
15

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.

Tattered answered 18/1, 2013 at 14:41 Comment(1)
now let me ask other small question here, is it possible to make a JTextPane with only 1 row? just like a JTextFieldEcumenism
I
8

Another solution is to use a DocumentFilter.

Here is an example:

Create a class that extends DocumentFilter:

private final class CustomDocumentFilter extends DocumentFilter
{
        private final StyledDocument styledDocument = yourTextPane.getStyledDocument();

        private final StyleContext styleContext = StyleContext.getDefaultStyleContext();
        private final AttributeSet greenAttributeSet = styleContext.addAttribute(styleContext.getEmptySet(), StyleConstants.Foreground, Color.GREEN);
        private final AttributeSet blackAttributeSet = styleContext.addAttribute(styleContext.getEmptySet(), StyleConstants.Foreground, Color.BLACK);

    // Use a regular expression to find the words you are looking for
    Pattern pattern = buildPattern();

    @Override
    public void insertString(FilterBypass fb, int offset, String text, AttributeSet attributeSet) throws BadLocationException {
        super.insertString(fb, offset, text, attributeSet);

        handleTextChanged();
    }

    @Override
    public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
        super.remove(fb, offset, length);

        handleTextChanged();
    }

    @Override
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attributeSet) throws BadLocationException {
        super.replace(fb, offset, length, text, attributeSet);

        handleTextChanged();
    }

    /**
     * Runs your updates later, not during the event notification.
     */
    private void handleTextChanged()
    {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                updateTextStyles();
            }
        });
    }

    /**
     * Build the regular expression that looks for the whole word of each word that you wish to find.  The "\\b" is the beginning or end of a word boundary.  The "|" is a regex "or" operator.
     * @return
     */
    private Pattern buildPattern()
    {
        StringBuilder sb = new StringBuilder();
        for (String token : ALL_WORDS_THAT_YOU_WANT_TO_FIND) {
            sb.append("\\b"); // Start of word boundary
            sb.append(token);
            sb.append("\\b|"); // End of word boundary and an or for the next word
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1); // Remove the trailing "|"
        }

        Pattern p = Pattern.compile(sb.toString());

        return p;
    }


    private void updateTextStyles()
    {
        // Clear existing styles
        styledDocument.setCharacterAttributes(0, yourTextPane.getText().length(), blackAttributeSet, true);

        // Look for tokens and highlight them
        Matcher matcher = pattern.matcher(yourTextPane.getText());
        while (matcher.find()) {
            // Change the color of recognized tokens
            styledDocument.setCharacterAttributes(matcher.start(), matcher.end() - matcher.start(), greenAttributeSet, false);
        }
    }
}

All you need to do then is apply the DocumentFilter that you created to your JTextPane as follows:

((AbstractDocument) yourTextPane.getDocument()).setDocumentFilter(new CustomDocumentFilter());
Insouciant answered 27/2, 2015 at 20:30 Comment(2)
This answer deserves more likes! It works perfectly for me, whereas the other answers are more confusing to use.Limbo
Since the DocumentFilter doesn’t actually do any filtering, it probably makes more sense to use a DocumentListener instead.Irade
S
5

You can extend DefaultStyledDocument like I did here for an SQL editor I am building with keyword text coloring ...

    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.DefaultStyledDocument;
    import javax.swing.text.Style;

    public class KeywordStyledDocument extends DefaultStyledDocument  {
        private static final long serialVersionUID = 1L;
        private Style _defaultStyle;
        private Style _cwStyle;

        public KeywordStyledDocument(Style defaultStyle, Style cwStyle) {
            _defaultStyle =  defaultStyle;
            _cwStyle = cwStyle;
        }

         public void insertString (int offset, String str, AttributeSet a) throws BadLocationException {
             super.insertString(offset, str, a);
             refreshDocument();
         }

         public void remove (int offs, int len) throws BadLocationException {
             super.remove(offs, len);
             refreshDocument();
         }

         private synchronized void refreshDocument() throws BadLocationException {
             String text = getText(0, getLength());
             final List<HiliteWord> list = processWords(text);

             setCharacterAttributes(0, text.length(), _defaultStyle, true);   
             for(HiliteWord word : list) {
                 int p0 = word._position;
                 setCharacterAttributes(p0, word._word.length(), _cwStyle, true);
             }
         }       

         private static  List<HiliteWord> processWords(String content) {
             content += " ";
             List<HiliteWord> hiliteWords = new ArrayList<HiliteWord>();
             int lastWhitespacePosition = 0;
             String word = "";
             char[] data = content.toCharArray();

             for(int index=0; index < data.length; index++) {
                 char ch = data[index];
                 if(!(Character.isLetter(ch) || Character.isDigit(ch) || ch == '_')) {
                     lastWhitespacePosition = index;
                     if(word.length() > 0) {
                         if(isReservedWord(word)) {
                             hiliteWords.add(new HiliteWord(word,(lastWhitespacePosition - word.length())));
                         }
                         word="";
                     }
                 }
                 else {
                     word += ch;
                 }
            }
            return hiliteWords;
         }

         private static final boolean isReservedWord(String word) {
             return(word.toUpperCase().trim().equals("CROSS") || 
                            word.toUpperCase().trim().equals("CURRENT_DATE") ||
                            word.toUpperCase().trim().equals("CURRENT_TIME") ||
                            word.toUpperCase().trim().equals("CURRENT_TIMESTAMP") ||
                            word.toUpperCase().trim().equals("DISTINCT") ||
                            word.toUpperCase().trim().equals("EXCEPT") ||
                            word.toUpperCase().trim().equals("EXISTS") ||
                            word.toUpperCase().trim().equals("FALSE") ||
                            word.toUpperCase().trim().equals("FETCH") ||
                            word.toUpperCase().trim().equals("FOR") ||
                            word.toUpperCase().trim().equals("FROM") ||
                            word.toUpperCase().trim().equals("FULL") ||
                            word.toUpperCase().trim().equals("GROUP") ||
                            word.toUpperCase().trim().equals("HAVING") ||
                            word.toUpperCase().trim().equals("INNER") ||
                            word.toUpperCase().trim().equals("INTERSECT") ||
                            word.toUpperCase().trim().equals("IS") ||
                            word.toUpperCase().trim().equals("JOIN") ||
                            word.toUpperCase().trim().equals("LIKE") ||
                            word.toUpperCase().trim().equals("LIMIT") ||
                            word.toUpperCase().trim().equals("MINUS") ||
                            word.toUpperCase().trim().equals("NATURAL") ||
                            word.toUpperCase().trim().equals("NOT") ||
                            word.toUpperCase().trim().equals("NULL") ||
                            word.toUpperCase().trim().equals("OFFSET") ||
                            word.toUpperCase().trim().equals("ON") ||
                            word.toUpperCase().trim().equals("ORDER") ||
                            word.toUpperCase().trim().equals("PRIMARY") ||
                            word.toUpperCase().trim().equals("ROWNUM") ||
                            word.toUpperCase().trim().equals("SELECT") ||
                            word.toUpperCase().trim().equals("SYSDATE") ||
                            word.toUpperCase().trim().equals("SYSTIME") ||
                            word.toUpperCase().trim().equals("SYSTIMESTAMP") ||
                            word.toUpperCase().trim().equals("TODAY") ||
                            word.toUpperCase().trim().equals("TRUE") ||
                            word.toUpperCase().trim().equals("UNION") ||
                            word.toUpperCase().trim().equals("UNIQUE") ||
                            word.toUpperCase().trim().equals("WHERE"));
        }
    }

Simply add it to your class like so:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Font;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTextPane;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Style;
    import javax.swing.text.StyleConstants;
    import javax.swing.text.StyleContext;

    public class SQLEditor extends JFrame {
        private static final long serialVersionUID = 1L;

        public SQLEditor() {
            StyleContext styleContext = new StyleContext();
            Style defaultStyle = styleContext.getStyle(StyleContext.DEFAULT_STYLE);
            Style cwStyle = styleContext.addStyle("ConstantWidth", null);
            StyleConstants.setForeground(cwStyle, Color.BLUE);
            StyleConstants.setBold(cwStyle, true);

            final JTextPane pane = new JTextPane(new KeywordStyledDocument(defaultStyle, cwStyle));
            pane.setFont(new Font("Courier New", Font.PLAIN, 12));

            JScrollPane scrollPane = new JScrollPane(pane);
            getContentPane().add(scrollPane, BorderLayout.CENTER);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(375, 400);      
        }

        public static void main(String[] args) throws BadLocationException {
            SQLEditor app = new SQLEditor();
            app.setVisible(true);
        }
    }

Here's the missing HiliteWord class ...

public class HiliteWord {

    int _position;  
    String _word;

    public HiliteWord(String word, int position) {
        _position = position;   
        _word = word;
    }
}
Super answered 4/5, 2015 at 21:43 Comment(4)
Where is the class HiliteWord?Justle
@Constantin...Please provide code for HiliteWord classCoastland
I tried but it was rejected by 3 of 4 reviewers, sorrySuper
Given that word.toUpperCase().trim() is not a cheap operation, copying and converting the string contents two times in the worst case, it is not a good idea to do it up to 70 times in row. Considering that word should not contain white-space, trim() is obsolete and equalsIgnoreCase can perform the desired operation directly without the creation of new strings.Aesthesia
L
0

@Constantin

Dear Constantin, I used Your fine Solution for my little Project and after only a few Adjustments your solution worked well for me.

If you allow, my Changes were:

My Use of your Class KeywordStyledDocument in my own JFrame:

StyleContext styleContext = new StyleContext();
Style defaultStyle = styleContext.getStyle(StyleContext.DEFAULT_STYLE);

This line I Have changed: MutableAttributeSet cwStyle = Functions.style(true, false, Color.RED);

private JTextPane jTextPaneNumbers = new JTextPane(new KeywordStyledDocument(defaultStyle, cwStyle));

I outsourced the supply of the cwStyle Instance in a static Function called style:

public static MutableAttributeSet style(boolean boldness, boolean italic, Color color) {
    
    MutableAttributeSet s = new SimpleAttributeSet();
    
    StyleConstants.setLineSpacing(s, -0.2f);
    StyleConstants.setBold(s, boldness);
    StyleConstants.setItalic(s, italic);
    StyleConstants.setForeground(s, color);
    
    return s;
}

Furthermore as you see above the cwStyle Class is not longer an Instance of StyleConstants but an Inctance of MutableAttributeSet. Therefore naturally I had to change the Constructor of your KeywordStyledDocumentClass as well:

public KeywordStyledDocument(Style defaultStyle, MutableAttributeSet cwStyle) {
    _defaultStyle =  defaultStyle;
    _cwStyle = cwStyle;
}

After this litle changes and adding my own "words" in your isReservedWord Function and add my Characters ' and * to your processWord Function:

 ...word.toUpperCase().trim().equals("UNION") ||
                    word.toUpperCase().trim().equals("UNIQUE") ||
                    word.toUpperCase().trim().equals("WHERE") ||
                    word.trim().equals("''''''") ||
                    word.trim().equals("******") 
                    );
 if(!(Character.isLetter(ch) || Character.isDigit(ch) || ch == '_' || ch == '\'' || ch == '*')) {

I became my whished Result:

enter image description here

Thank you very much for showing your Code here.

Lamelliform answered 21/3, 2021 at 13:13 Comment(0)
D
0

enter image description here

With the use of the ideas from code of the user shuangwhywhy, I have modified his code and made some improvements that I believe will be beneficial for many people that would like to be able to dynamically highlight keywords in a JTextPane.

In my code I extended JTextPane and created a component called JSyntaxTextPane.

It allows the developer to state a list of words that need to be coloured/highlighted, and then once those words are found within the text of this component they will be coloured accordingly.

Main Methods:

initializeSyntaxHighlighter() - it is the default method created by me that sets the rules for coloring of the keywords.

addKeyWord(Color color, String ...words) - this is the method that developer can use to specify the colour and words that need to be highlighted

import java.awt.Color;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.TabSet;
import javax.swing.text.TabStop;

/**
 * This class is a prototype for a syntax highlighter for java code.
 * It highlights common java keywords, boolean values and it highlights digits in the text.
 * 
 * Limitations of the current prototype:
 * -It does not highlight comments
 * -It does not highlight method calls
 * -It does not highlight objects that are not a part of common java keywords
 * -It does not have intellisense autosuggestion
 * 
 * Addendum:
 * Even though this syntax highlighter is designed for java code, {@link #initializeSyntaxHighlighter()} can be modified to highlight any other programming language or keywords
 */
public class JSyntaxTextPane extends JTextPane {

    // Default Styles
    final StyleContext cont = StyleContext.getDefaultStyleContext();
    AttributeSet defaultForeground = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, Color.white);
    AttributeSet defaultNumbers = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, Color.cyan);
    
    public JSyntaxTextPane () {
        // Styler
        DefaultStyledDocument doc = new DefaultStyledDocument() {
            public void insertString (int offset, String str, AttributeSet a) throws BadLocationException {
                super.insertString(offset, getDeveloperShortcuts(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")) {
                        // Colors words in appropriate style, if nothing matches, make it default black
                        boolean matchFound = false;
                        
                        for (KeyWord keyWord : keyWords) {
                            if (text.substring(wordL, wordR).matches("(\\W)*("+keyWord.getWords()+")")) {
                                setCharacterAttributes(wordL, wordR - wordL, keyWord.getColorAttribute(), false);
                                matchFound = true;
                            }
                        }
                        
                        // Highlight numbers
                        if (text.substring(wordL, wordR).matches("\\W\\d[\\d]*")) {
                            setCharacterAttributes(wordL, wordR - wordL, defaultNumbers, false);
                            matchFound = true;
                        }
                        
                        // ================ ANY ADDITIONAL HIGHLIGHTING LOGIC MAY BE ADDED HERE
                        // Ideas: highlighting a comment; highlighting method calls;
                        
                        // ================
                        
                        // If no match found, make text default colored
                        if(!matchFound) {
                            setCharacterAttributes(wordL, wordR - wordL, defaultForeground, 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);

                // Colors words in appropriate style, if nothing matches, make it default black
                boolean matchFound = false;
                
                for (KeyWord keyWord : keyWords) {
                    if (text.substring(before, after).matches("(\\W)*("+keyWord.getWords()+")")) {
                        setCharacterAttributes(before, after - before, keyWord.getColorAttribute(), false);
                        matchFound = true;
                    } 
                    
                    // Highlight numbers
                    if (text.substring(before, after).matches("\\W\\d[\\d]*")) {
                        setCharacterAttributes(before, after - before, defaultNumbers, false);
                        matchFound = true;
                    }
                    
                    // ================ ANY ADDITIONAL HIGHLIGHTING LOGIC MAY BE ADDED HERE
                    // Ideas: highlighting a comment; highlighting method calls;
                    
                    // ================
            
                    if(!matchFound) {
                        setCharacterAttributes(before, after - before, defaultForeground, false);
                    }
                }
            }
        };
        
        setStyledDocument(doc);
        
        // SET DEFAULT TAB SIZE
        setTabSize(40);

        // THIS PART APPLIES DEFAULT SYNTAX HIGHLIGHTER BEHAVIOUR
        initializeSyntaxHighlighter();
    }
    
    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;
    }
    
    /**
     * Shortcuts, when letter is typed, it will produce additional strings specified inside of this method
     * 
     * @param str
     * @return
     */
    private String getDeveloperShortcuts(String str) {
        // Add ending parenthesis when it is open
        if(str.equals("(")) {
            return "()";
        }
        
        // Add ending braces when it is open
        if(str.equals("{")) {
            return "{\n\n};";
        }
        
        return str;
    }
    
    /**
     * Sets size of space produced when user presses Tab button
     * 
     * @param tabSize
     */
    public void setTabSize(int tabSize) {
        // Once tab count exceed x times, it will make a small space only
        int maxTabsPerRow = 10;
        
        TabStop[] tabs = new TabStop[maxTabsPerRow];
        for(int i = 0; i < maxTabsPerRow; i++) {
            tabs[i] = new TabStop(tabSize*(i+1), TabStop.ALIGN_LEFT, TabStop.LEAD_NONE);
        }
        
        TabSet tabset = new TabSet(tabs);
        
        StyleContext sc = StyleContext.getDefaultStyleContext();
        AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY,
        StyleConstants.TabSet, tabset);
        setParagraphAttributes(aset, false);
    }
    
    /**
     * Adds a key word or keywords that will be colored in the JTextPane
     * 
     * @param color - color of the words
     * @param words - words that need to be colored
     */
    public void addKeyWord(Color color, String ...words) {
        keyWords.add(new KeyWord(color, words));
    }
    
    ArrayList<KeyWord> keyWords = new ArrayList<KeyWord>();
    
    /**
     * Holds information about list of words that need to be colored in a specific color
     * 
     */
    class KeyWord {
        Color color;
        String[] words;
        
        /**
         * Instantiates a new key word object that holds a list of words that need to be colored.
         *
         * @param color the color
         * @param words the words
         */
        public KeyWord(Color color, String...words) {
            this.color = color;
            this.words = words;
        }
        
        public String getWords() {
            String text = "";
            
            for (int i = 0; i < words.length; i++) {
                if(i != words.length-1) {
                    text = text + words[i] + "|";
                } else {
                    text = text + words[i];
                }
            }
            
            return text;
        }
        
        public AttributeSet getColorAttribute() {
            StyleContext cont = StyleContext.getDefaultStyleContext();
            return cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, color);
        }

    }
    
    /**
     * Sets color of all integers
     * 
     * @param color
     */
    public void setIntegerColours(Color color) {
        defaultNumbers = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, color);
        
    }
    
    /**
     * Sets color of non-keywords 
     * 
     * @param color
     */
    public void setDefaultTextColour(Color color) {
        defaultForeground = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, color);
    }
    
    /**
     * Initializes rules by which textpane should be coloring text
     */
    public void initializeSyntaxHighlighter() {
        // Set background color
        setBackground(Color.black);
        
        // Java keywords
        addKeyWord(Color.pink,
                "abstract",
                "continue",
                "for",
                "new",
                "switch",
                "assert",
                "default",
                "goto",
                "package",
                "synchronized",
                "do",
                "if",
                "private",
                "this",
                "break",
                "double",
                "implements",
                "protected",
                "throw",
                "else",
                "import",
                "public",
                "throws",
                "case",
                "enum",
                "instanceof",
                "return",
                "transient",
                "catch",
                "extends",
                "short",
                "try",
                "char",
                "final",
                "interface",
                "static",
                "void",
                "class",
                "finally",
                "strictfp",
                "volatile",
                "const",
                "native",
                "super",
                "while"
                );
        
        // Developer's preference
        addKeyWord(Color.green,
                "true"
                );
        
        addKeyWord(Color.red,
                "false"
                );
        
        addKeyWord(Color.red, 
                "!"
                );
        
        // Java Variables
        addKeyWord(Color.yellow,
                "String",
                "byte", "Byte",
                "short", "Short",
                "int", "Integer",
                "long", "Long",
                "float", "Float",
                "double", "Double",
                "char", "Character",
                "boolean", "Boolean");
    }
    
    /**
     * Demo for testing purposes
     */
    public static void main(String[] args) {
        // Our Component
        JSyntaxTextPane textPane = new JSyntaxTextPane();
        
        textPane.setText("public class Test {\r\n"
                + " int age = 18;\r\n"
                + " String name = \"Gerald\";\r\n"
                + " Long life = 100.50;\r\n"
                + " boolean alive = true;\r\n"
                + " boolean happy = false;\r\n"
                + " \r\n"
                + " // Comment Example\r\n"
                + " public static void shout(int loudness) {\r\n"
                + "     System.out.println(loudness);\r\n"
                + " };\r\n"
                + "\r\n"
                + "};");
        
        // JFrame
        JFrame frame = new JFrame("Test");
        frame.getContentPane().add(textPane);
        frame.pack();
        frame.setSize(350, 350);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

}
Diminish answered 18/1, 2023 at 20:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.