Search code examples
javaswingeditorhighlightjtextpane

JTextPane: Highlighting Comment Lines


Please have a look the following three files.

Form.java 

  package Normal;      

import Keywords.JavaKeywords;    
import java.awt.Color;    
import java.awt.Dimension;    
import java.awt.FlowLayout;    
import java.awt.event.ActionEvent;    
import java.awt.event.ActionListener;    
import java.util.ArrayList;    
import java.util.List;    
import java.util.logging.Level;    
import java.util.logging.Logger;    
import javax.swing.*;    
import javax.swing.text.*;    

    public class Form extends JEditorPane      
    {      
        private JTextPane textPane;      
        private JPanel south;    
        private JScrollPane scroll;      
        private List<String> keywords, literals;     
        private String  content;      
        public String documentType;                
        private Style style, style2;               
        private KeywordConnector java;               
        private DefaultStyledDocument document;          
        int start, end, offset1,length1;         
        private JButton button;             
        JFrame frame;    


        public Form()      
        {      
            super();    
              frame = new JFrame();    

            //Declaring the instance variables      
            textPane = new JTextPane();      
            textPane.setMinimumSize(new Dimension(100,100));      

            button = new JButton("Save");      
            button.addActionListener(new Action());     

            document = (DefaultStyledDocument) textPane.getDocument();        
            document.setDocumentFilter(new HighlightFilter());      

            keywords = new ArrayList();       
            literals = new ArrayList();       

            //Adding Styles      
            style = document.addStyle("blue", null);        
            StyleConstants.setForeground(style, Color.BLUE);                    
            style2 = document.addStyle("red", null);      
            StyleConstants.setForeground(style2, Color.RED);                

            //Creating the main window     
            south = new JPanel();      
            south.setLayout(new FlowLayout());      
            south.add(button);                          
            scroll = new JScrollPane(textPane);      

            frame.getContentPane().add(scroll,"Center");      
            frame.getContentPane().add(south,"South");                  
            frame.setVisible(true);    
            frame.setSize(800,600);    
            frame.validate();    
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                          
        }     

        private class HighlightFilter extends DocumentFilter       
        {        

        public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)        
                throws BadLocationException {        
          if (string.isEmpty()) {        
            fb.insertString(offset, string, attr);            


          } else {        
            super.insertString(fb, offset, string, attr);        
             offset1 = offset;    
            length1 = string.length()+offset;    
            System.out.println(string.length());    

            System.out.println("Offset: "+offset1+" Length: "+length1);    
            highlight();        
          }        
        }        

        public void remove(FilterBypass fb, int offset, int length)        
                throws BadLocationException {        
          if (length == 0) {        
            fb.remove(offset, length);        
          } else {        
            super.remove(fb, offset, length);        
            offset1 = offset;    
            length1 = length;    
             System.out.println("Offset: "+offset1+" Length: "+length1);    
            highlight();        
          }        
        }        

        public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)        
                throws BadLocationException {        
          if (length == 0 && text.isEmpty()) {        
            fb.replace(offset, length, text, attrs);        
          } else {        
            super.replace(fb, offset, length, text, attrs);        
             offset1 = offset;    
            length1 = length;    
             System.out.println("Offset: "+offset1+" Length: "+length1);    
             highlight();      
          }  } }      

        private void highlight()       
        {        
              SwingUtilities.invokeLater(new Runnable()       
              {        
                  int next=0; int end=0;    

                @Override        
                public void run() {        
                  try {        
                        //content = document.getText(0, document.getLength());     

                        int preWord =Utilities.getPreviousWord(textPane, offset1);    

                        if(preWord<0)    
                        {    
                            preWord=preWord*-1;    
                        }    
                        System.out.println("Previous Word: "+preWord);    

                        int wordEnd = Utilities.getWordEnd(textPane, offset1);    

                        System.out.println("Word End: "+wordEnd);    

                       System.out.println("The Text: "+document.getText(preWord,wordEnd-preWord));    

                       content = document.getText(preWord,(wordEnd-preWord)-1);    

                       System.out.println("Length: "+(wordEnd-preWord));    

                    for (String word : content.split("\\s")) {        
                    next = content.indexOf(word, next);        
                     end = next + word.length();        

                     document.setCharacterAttributes(preWord, word.length(),        
                     textPane.getStyle(keywords.contains(word) ? "blue" : literals.contains(word)? "red":"default"),true);        
                     next = end;        
                }        
              } catch (BadLocationException ex) {        
                ex.printStackTrace();        
              }        
            }        
          });        
            }      

        private class Action implements ActionListener      
        {      
            public void actionPerformed(ActionEvent ae)      
            {                     
                java = new JavaKeywords();              
                keywords = java.getKeywords();      
                literals = java.getLiterals();      


                int next=0; int end=0;    
            try {    
                content = document.getText(0, document.getLength());    
            } catch (BadLocationException ex) {    
                Logger.getLogger(Form.class.getName()).log(Level.SEVERE, null, ex);    
            }    

                for (String word : content.split("\\s")) {        
                    next = content.indexOf(word, next);        
                     end = next + word.length();        

                     document.setCharacterAttributes(next, end,        
                     textPane.getStyle(keywords.contains(word) ? "blue" : literals.contains(word)? "red":"default"),true);        
                     next = end;        
                }        
            }      
        }      

       public static void main(String[] args) throws Exception {       
            SwingUtilities.invokeLater(new Runnable()       
            {        
              @Override        
              public void run() {        
               Form f = new Form();      
              }        
            });        
          }       
    }  

Keywords.java

 package Keywords;    

    import Normal.KeywordConnector;    
    import java.util.ArrayList;    
    import java.util.List;    
    import keywords.Literals;    

    public class JavaKeywords implements KeywordConnector     
    {    
        private ArrayList list, literals;    

        public JavaKeywords()    
        {    
            //Default Keywords    
            list = new ArrayList();    

            list.add("abstract");    
            list.add("assert");            
            list.add("break");    
            list.add("byte");    
            list.add("case");    
            list.add("catch");    
            list.add("char");    
            list.add("class");    


            //Literals    
            String string = "String";    

            literals = new ArrayList();    
            literals.add(string);    
            literals.add("bool");    
            literals.add("int");    
            literals.add("Double");    
            literals.add("float");    
            literals.add("char");    
            literals.add("long");    
            literals.add("byte");    

        }    


        @Override    
        public ArrayList getKeywords()    
        {    
            return list;    
        }    

        @Override    
        public List<String> getLiterals()     
        {    
            return literals;    
        }    

        @Override    
        public List getOthers() {    
            throw new UnsupportedOperationException("Not supported yet.");    
        }    

    }    

KeywordConnector.java

package Normal;  
import java.util.List;  

public interface KeywordConnector  
{  
    public List<String> getKeywords();  
    public List<String> getLiterals();  
    public List<String> getOthers();  
}

What happens here is, when the user clicks the save button, the program will search for Java keywords and start highlighting them. As you can see, there is no way in this program to highlight comment lines! I am trying to achieve this for more than a week now.

I can add the '//' symbols and '/*' '*' symbols to the list of keywords, but then what happens is,

  1. When comment line is entered, I have to check for number of letters in Comment. Then only I can highlight ALL OF them (Or else I can highlight the WHOLE ROW, but you know how it looks like at the end). But if I add it to keywords, I can't do it.

  2. When the comment "symbol" is deleted, the WHOLE COLORED COMMENT LETTERS has to be changed to "No Colour"

So, How can I add the comment highlight support with achieving the above two mentions?

Please help me to solve this issue!! Thank you...


Solution

  • add this to the end of the Form.actionPerformed(ActionEvent) method

    Pattern singleLinecommentsPattern = Pattern.compile("\\/\\/.*");
    Matcher matcher = singleLinecommentsPattern.matcher(content);
    
    while (matcher.find()) {
        document.setCharacterAttributes(matcher.start(), 
          matcher.end() - matcher.start(), textPane.getStyle("red"), true);
    }
    
    Pattern multipleLinecommentsPattern = Pattern.compile("\\/\\*.*?\\*\\/",
                            Pattern.DOTALL);
    matcher = multipleLinecommentsPattern.matcher(content);
    
    while (matcher.find()) {
        document.setCharacterAttributes(matcher.start(), 
          matcher.end() - matcher.start(), textPane.getStyle("red"), true);
    }