javaswingjtextareaswing-highlighter

Highlighting a selected line in JTextArea


I've been searching for a way to highlight the selected line in JTextArea. There are many post on how to highlight text in a JTextArea, but it only goes as far as the letters go. I want to be able to highlight the whole line (much like how the eclipse editor highlights the whole current line that you are on when you click on a row). All the post I've found suggest the Highlighter object, but I am not sure if that will highlight the non-character area of a JTextArea. Also, is there a way to find what the selected line in a JTextArea is? Not how many lines there are, but the selected one (say someone clicks back towards an earlier point). Or is it a very complicated process to calculate?


Solution

  • You need to turn layered highlights off:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.text.*;
    
    public class SSCCE extends JPanel
    {
        public SSCCE()
        {
            JTextArea textArea = new JTextArea(4, 30);
            textArea.setText("one\ntwo\nthree");
            add( new JScrollPane(textArea) );
    
    
            DefaultHighlighter highlighter =  (DefaultHighlighter)textArea.getHighlighter();
            DefaultHighlighter.DefaultHighlightPainter painter = new DefaultHighlighter.DefaultHighlightPainter( Color.RED );
            highlighter.setDrawsLayeredHighlights(false); // this is the key line
    
            try
            {
                int start =  textArea.getLineStartOffset(1);
                int end =    textArea.getLineEndOffset(1);
                highlighter.addHighlight(start, end, painter );
            }
            catch(Exception e)
            {
                System.out.println(e);
            }
        }
    
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new SSCCE());
            frame.setLocationByPlatform( true );
            frame.pack();
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater( () -> createAndShowGUI() );
    /*
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowGUI();
                }
            });
    */
        }
    }
    

    You may also want to check out the Line Painter class which will highlight the current line as the caret is moved. So this class will manage the highlight. That is as the caret is moved from row to row, the previous highlight is removed and a new highlight is added.