Search code examples
javaswingawtjtextarea

Java: How to select multiple NON-CONSECUTIVE lines of text in a Text Area, the same way Ctrl functions in MS Word?


I want to select multiple, non-consecutive lines within a TextArea, as shown in this image (but non-consecutive)

https://i.sstatic.net/vjtTv.png

and pass the selected lines (as a String[] argument) to a method that is invoked when a Button is pressed.

How can I do this?


Solution

  • You can't. Swing a JTextArea only supports contiguous selection.

    You could use a JList and display each line of text as a separate item in the JList. A JList does support non contiguous selection and have methods to return the Array of selected lines.

    Read the section from the Swing tutorial on How to Use JLists for more information.

    Note a JTextArea does support the concept of adding "highlights" to text. You can highlight any piece of text but there is no automatic processing to add/remove highlights so you would need to create a whole new UI to dynamically add and remove highlights which is above my pay grade.

    Edit:

    As I mentioned you might be able so use a Highlighter to track individual selections.

    A simple example to get you started:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.text.*;
    
    public class TextAreaHighlighting extends JPanel
    {
        private JTextArea textPane = new JTextArea(10, 30);
        private DefaultHighlighter highlighter =  (DefaultHighlighter)textPane.getHighlighter();
    
        private Highlighter.HighlightPainter cyanPainter;
        private Highlighter.HighlightPainter yellowPainter;
    
        public TextAreaHighlighting()
        {
            setLayout( new BorderLayout() );
    
            textPane.setText( "one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten" );
            add( new JScrollPane( textPane ) );
    
            //  Highlight some text
    
            highlighter.setDrawsLayeredHighlights(false);
    
            cyanPainter = new DefaultHighlighter.DefaultHighlightPainter( Color.CYAN );
            yellowPainter = new DefaultHighlighter.DefaultHighlightPainter( Color.YELLOW );
    
            try
            {
                highlighter.addHighlight( 0, 3, cyanPainter );
            }
            catch(BadLocationException ble) {}
    
            JPanel buttons = new JPanel();
            add(buttons, BorderLayout.PAGE_END);
    
            JButton addHighlight = new JButton("Highlight Selected");
            buttons.add(addHighlight);
            addHighlight.addActionListener( new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    try
                    {
                        int start = textPane.getSelectionStart();
                        int end = textPane.getSelectionEnd();
    
                        highlighter.addHighlight( start, end, yellowPainter );
                    }
                    catch(BadLocationException ble) {}
                }
            });
    
            //  Add Remove Highlight button
    
            JButton removeHighlight = new JButton("Remove Selected Highlight");
            buttons.add( removeHighlight );
            removeHighlight.addActionListener( new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    int start = textPane.getSelectionStart();
                    int end = textPane.getSelectionEnd();
    
                    Highlighter.Highlight[] highlights = textPane.getHighlighter().getHighlights();
    
                    for (int i = 0; i < highlights.length; i++)
                    {
                        Highlighter.Highlight h = highlights[i];
                        DefaultHighlighter.DefaultHighlightPainter thePainter =
                            (DefaultHighlighter.DefaultHighlightPainter)h.getPainter();
    
                        if (h.getStartOffset() >= start
                        &&  h.getEndOffset() <= end)
                            highlighter.removeHighlight(h);
                    }
                }
            });
    
        }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("Text Pane Highlighting");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new TextAreaHighlighting());
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args)
        {
            EventQueue.invokeLater( () -> createAndShowGUI() );
    /*
            EventQueue.invokeLater(new Runnable()
            {
                public void run()
                {
                    createAndShowGUI();
                }
            });
    */
        }
    }