Java选定文本超过突出显示的文本

Java选定文本超过突出显示的文本,java,swing,Java,Swing,我有一个文本JTextArea,其中有一些突出显示的文本,使用: inputTextArea.getHighlighter().addHighlight(start, end, new DefaultHighlighter.DefaultHighlightPainter(new Color(color))); 它工作得很好,但是如果我使用鼠标选择一些文本,当它位于高亮显示的文本上时,选择不会被绘制 例如,如果我只想选择高亮显示文本的一部分,我就看不到选择 如何使选择显示在高光上?您只需要一个允

我有一个文本JTextArea,其中有一些突出显示的文本,使用:

inputTextArea.getHighlighter().addHighlight(start, end, new DefaultHighlighter.DefaultHighlightPainter(new Color(color)));
它工作得很好,但是如果我使用鼠标选择一些文本,当它位于高亮显示的文本上时,选择不会被绘制

例如,如果我只想选择高亮显示文本的一部分,我就看不到选择


如何使选择显示在高光上?

您只需要一个允许修改绘制坐标的代理荧光灯。以下是一个例子:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Shape;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter.HighlightPainter;
import javax.swing.text.JTextComponent;


public class HighlightTest {

    public static void main(String[] args) {
        JTextArea textArea = new JTextArea(10, 30);
        textArea.setText("It's a small test to understand whether proxy works or not.");
        try {
            textArea.getHighlighter().addHighlight(5, 15,
                    new ProxyHighlightPainer(new DefaultHighlighter.DefaultHighlightPainter(Color.RED)));
        } catch (Exception e) {
            // add something when required
        }
        textArea.addCaretListener(e -> textArea.repaint()); // must provoke repaint of highlighter
        JFrame frm = new JFrame("Test");
        frm.add(new JScrollPane(textArea));
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.pack();
        frm.setLocationRelativeTo(null);
        frm.setVisible(true);
    }
    private static class ProxyHighlightPainer implements HighlightPainter {

        private final HighlightPainter delegate;

        public ProxyHighlightPainer(HighlightPainter delegate) {
            this.delegate = delegate;
        }

        @Override
        public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
            int startSel = c.getSelectionStart();
            int endSel = c.getSelectionEnd();
            if (startSel == endSel || startSel >= p1 || endSel <= p0) {
                // no selection or no intersection: paint normal
                delegate.paint(g, p0, p1, bounds, c);
            } else if (startSel >= p0 && endSel >= p1) {
                delegate.paint(g, p0, startSel, bounds, c);
            } else if (startSel <= p0 && endSel <= p1) {
                delegate.paint(g, endSel, p1, bounds, c);
            } else if (startSel <= p0 && endSel <= p1) {
                delegate.paint(g, p0, startSel, bounds, c);
                delegate.paint(g, endSel, p1, bounds, c);
            } else {
                // just to be safe
                delegate.paint(g, p0, p1, bounds, c);
            }
        }

    }
}

您只需要一个允许修改绘制坐标的代理荧光灯。以下是一个例子:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Shape;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter.HighlightPainter;
import javax.swing.text.JTextComponent;


public class HighlightTest {

    public static void main(String[] args) {
        JTextArea textArea = new JTextArea(10, 30);
        textArea.setText("It's a small test to understand whether proxy works or not.");
        try {
            textArea.getHighlighter().addHighlight(5, 15,
                    new ProxyHighlightPainer(new DefaultHighlighter.DefaultHighlightPainter(Color.RED)));
        } catch (Exception e) {
            // add something when required
        }
        textArea.addCaretListener(e -> textArea.repaint()); // must provoke repaint of highlighter
        JFrame frm = new JFrame("Test");
        frm.add(new JScrollPane(textArea));
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.pack();
        frm.setLocationRelativeTo(null);
        frm.setVisible(true);
    }
    private static class ProxyHighlightPainer implements HighlightPainter {

        private final HighlightPainter delegate;

        public ProxyHighlightPainer(HighlightPainter delegate) {
            this.delegate = delegate;
        }

        @Override
        public void paint(Graphics g, int p0, int p1, Shape bounds, JTextComponent c) {
            int startSel = c.getSelectionStart();
            int endSel = c.getSelectionEnd();
            if (startSel == endSel || startSel >= p1 || endSel <= p0) {
                // no selection or no intersection: paint normal
                delegate.paint(g, p0, p1, bounds, c);
            } else if (startSel >= p0 && endSel >= p1) {
                delegate.paint(g, p0, startSel, bounds, c);
            } else if (startSel <= p0 && endSel <= p1) {
                delegate.paint(g, endSel, p1, bounds, c);
            } else if (startSel <= p0 && endSel <= p1) {
                delegate.paint(g, p0, startSel, bounds, c);
                delegate.paint(g, endSel, p1, bounds, c);
            } else {
                // just to be safe
                delegate.paint(g, p0, p1, bounds, c);
            }
        }

    }
}

您可能可以使用:

JTextArea textArea = new JTextArea(10, 20);
textArea.setText( "one\ntwo\nthree\nfour\nfive\nsix\nseven\neight" );

DefaultHighlighter highlighter =  (DefaultHighlighter)textArea.getHighlighter();
highlighter.setDrawsLayeredHighlights(false);

try
{
    highlighter.addHighlight(10, 20, new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW));
}
catch(Exception e) {}
更改“分层高光”特性有两种效果:

现在您将看到选择 高亮显示是在一行的文本区域的末尾进行的,而不是在高亮显示的文本跨越多行时仅在文本的末尾进行。
您可能可以使用:

JTextArea textArea = new JTextArea(10, 20);
textArea.setText( "one\ntwo\nthree\nfour\nfive\nsix\nseven\neight" );

DefaultHighlighter highlighter =  (DefaultHighlighter)textArea.getHighlighter();
highlighter.setDrawsLayeredHighlights(false);

try
{
    highlighter.addHighlight(10, 20, new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW));
}
catch(Exception e) {}
更改“分层高光”特性有两种效果:

现在您将看到选择 高亮显示是在一行的文本区域的末尾进行的,而不是在高亮显示的文本跨越多行时仅在文本的末尾进行。
也许你需要使用caretListener来更新突出显示的文本-也许你需要使用caretListener来更新突出显示的文本-1+很好的解决方案。我一直不明白为什么这不是默认行为。1+很好的解决方案。我一直不明白为什么这不是默认行为。