jTextArea stops showing highlighting on text after losing focus
Asked Answered
C

2

7

When my jTextArea is in focus it allows text highlighting, but it doesn't show the text selection when it loses focus. Is it possible to continue displaying the text highlighting even if the user moves focus to another component on the related jFrame?

Carter answered 16/8, 2013 at 12:23 Comment(2)
For better help sooner, post your code as an SSCCE that demonstrates your problem. This allows users to copy/paste and reproduce your issue.Garibay
I think it is possible, but not with the standard included widgets. You'll have to write a subclass of JTextArea for that.Omura
C
5

but doesn't show selection on text when looses focus.

there are three ways:

enter image description here

  • or programatically override Highlighter

enter image description here

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;

public class MultiHighlight implements ActionListener {

    private JTextComponent comp;
    private String charsToHighlight;

    public MultiHighlight(JTextComponent c, String chars) {
        comp = c;
        charsToHighlight = chars;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Highlighter h = comp.getHighlighter();
        h.removeAllHighlights();
        String text = comp.getText().toUpperCase();
        for (int j = 0; j < text.length(); j += 1) {
            char ch = text.charAt(j);
            if (charsToHighlight.indexOf(ch) >= 0) {
                try {
                    h.addHighlight(j, j + 1, DefaultHighlighter.DefaultPainter);
                } catch (BadLocationException ble) {
                }
            }
        }
    }

    public static void main(String args[]) {
        final JFrame frame = new JFrame("MultiHighlight");
        frame.add(new JTextField("Another focusable JComponents"), BorderLayout.NORTH);
        JTextArea area = new JTextArea(10, 20);
        area.setText("This is the story\nof the hare who\nlost his spectacles."
                + "\nThis is the story\nof the hare who\nlost his spectacles.");
        frame.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
        JButton b = new JButton("Highlight All Vowels");
        b.addActionListener(new MultiHighlight(area, "aeiouAEIOU"));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(b, BorderLayout.SOUTH);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
Chemurgy answered 16/8, 2013 at 12:53 Comment(0)
T
13

One simple workaround for caret selection is a simple subclassing of DefaultCaret:

textArea.setCaret(new DefaultCaret() {
   @Override
   public void setSelectionVisible(boolean visible) {
      super.setSelectionVisible(true);
   }
});
Torn answered 16/8, 2013 at 17:44 Comment(1)
This worked perfectly. Just needed the highlight to remain after focus was lost.Entrenchment
C
5

but doesn't show selection on text when looses focus.

there are three ways:

enter image description here

  • or programatically override Highlighter

enter image description here

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import javax.swing.text.JTextComponent;

public class MultiHighlight implements ActionListener {

    private JTextComponent comp;
    private String charsToHighlight;

    public MultiHighlight(JTextComponent c, String chars) {
        comp = c;
        charsToHighlight = chars;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Highlighter h = comp.getHighlighter();
        h.removeAllHighlights();
        String text = comp.getText().toUpperCase();
        for (int j = 0; j < text.length(); j += 1) {
            char ch = text.charAt(j);
            if (charsToHighlight.indexOf(ch) >= 0) {
                try {
                    h.addHighlight(j, j + 1, DefaultHighlighter.DefaultPainter);
                } catch (BadLocationException ble) {
                }
            }
        }
    }

    public static void main(String args[]) {
        final JFrame frame = new JFrame("MultiHighlight");
        frame.add(new JTextField("Another focusable JComponents"), BorderLayout.NORTH);
        JTextArea area = new JTextArea(10, 20);
        area.setText("This is the story\nof the hare who\nlost his spectacles."
                + "\nThis is the story\nof the hare who\nlost his spectacles.");
        frame.getContentPane().add(new JScrollPane(area), BorderLayout.CENTER);
        JButton b = new JButton("Highlight All Vowels");
        b.addActionListener(new MultiHighlight(area, "aeiouAEIOU"));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(b, BorderLayout.SOUTH);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}
Chemurgy answered 16/8, 2013 at 12:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.