如何更改JTextPane中特定单词的颜色?

时间:2023-01-27 16:29:02

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

如何在用户输入时更改JTextPane中特定单词的颜色?我应该覆盖JTextPane paintComponent方法吗?

4 个解决方案

#1


14  

Overwriting paintComponent will not help you.

覆盖paintComponent对你没有帮助。

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.

你可能需要调整一下,但至少它会告诉你从哪里开始。

#2


31  

No. You are not supposed to override the paintComponent() method. Instead, you should use StyledDocument. You should also delimit the words by your self.

不。您不应该覆盖paintComponent()方法。相反,您应该使用StyledDocument。你也应该用自己划分单词。

Here is the demo, which turns "public", "protected" and "private" to red when typing, just like a simple code editor:

这是演示,在键入时将“public”,“protected”和“private”变为红色,就像一个简单的代码编辑器:

如何更改JTextPane中特定单词的颜色?

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.

代码不是那么漂亮,因为我快速键入它但它的工作原理。我希望它会给你一些暗示。

#3


8  

Another solution is to use a DocumentFilter.

另一种解决方案是使用DocumentFilter。

Here is an example:

这是一个例子:

Create a class that extends DocumentFilter:

创建一个扩展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:

您需要做的就是将您创建的DocumentFilter应用于JTextPane,如下所示:

((AbstractDocument) yourTextPane.getDocument()).setDocumentFilter(new CustomDocumentFilter());

#4


3  

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

您可以像我在这里为我正在使用关键字文本着色构建的SQL编辑器一样扩展DefaultStyledDocument ...

    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 ...

这是缺少的HiliteWord课程......

public class HiliteWord {

    int _position;  
    String _word;

    public HiliteWord(String word, int position) {
        _position = position;   
        _word = word;
    }
}

#1


14  

Overwriting paintComponent will not help you.

覆盖paintComponent对你没有帮助。

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.

你可能需要调整一下,但至少它会告诉你从哪里开始。

#2


31  

No. You are not supposed to override the paintComponent() method. Instead, you should use StyledDocument. You should also delimit the words by your self.

不。您不应该覆盖paintComponent()方法。相反,您应该使用StyledDocument。你也应该用自己划分单词。

Here is the demo, which turns "public", "protected" and "private" to red when typing, just like a simple code editor:

这是演示,在键入时将“public”,“protected”和“private”变为红色,就像一个简单的代码编辑器:

如何更改JTextPane中特定单词的颜色?

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.

代码不是那么漂亮,因为我快速键入它但它的工作原理。我希望它会给你一些暗示。

#3


8  

Another solution is to use a DocumentFilter.

另一种解决方案是使用DocumentFilter。

Here is an example:

这是一个例子:

Create a class that extends DocumentFilter:

创建一个扩展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:

您需要做的就是将您创建的DocumentFilter应用于JTextPane,如下所示:

((AbstractDocument) yourTextPane.getDocument()).setDocumentFilter(new CustomDocumentFilter());

#4


3  

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

您可以像我在这里为我正在使用关键字文本着色构建的SQL编辑器一样扩展DefaultStyledDocument ...

    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 ...

这是缺少的HiliteWord课程......

public class HiliteWord {

    int _position;  
    String _word;

    public HiliteWord(String word, int position) {
        _position = position;   
        _word = word;
    }
}