Как изменить цвет выделения в Java Swing TextArea? Кроме того, измените начало текста, соответствующего местоположению выделения

Проблема 1: Используя defaulthighlighter, я могу сделать сфокусированные линии меняющимися на синие. Теперь я хочу изменить его на другие цвета. Кто-нибудь знает, как изменить этот параметр? --- resolved

Проблема 2: pos - это начальный индекс моей подстроки, который я хочу выделить. Я использую setCaretPosition (pos); для обновления отображаемого содержимого. Но он всегда появляется в нижней части окна. Я хочу, чтобы он был наверху.. Может ли кто-нибудь сказать мне, как с этим бороться?

Я использую одно демо, чтобы показать свою проблему:

import java.awt.Color;
import java.net.MalformedURLException;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;

public class Test {
    public static void main(final String[] args) throws MalformedURLException {
        SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            try {
                init();
            } catch (BadLocationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    });
}

private static void init() throws BadLocationException {
    JFrame frame = new JFrame();
    final JTextArea textArea = new JTextArea();
    JScrollPane pane = new JScrollPane(textArea);
    textArea.setText("Something. Something else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Samething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sbmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Scmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sdmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Semething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sfmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sgmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n");
    textArea.setSelectionColor(Color.RED);
    frame.add(pane);
    frame.setSize(300, 120);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    String turnToString2 = "Sdmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla";
    int pos2 = textArea.getText().indexOf(turnToString2);
    textArea.getHighlighter().addHighlight(pos2,
            pos2 + turnToString2.length(),
            new DefaultHighlighter.DefaultHighlightPainter(Color.yellow));
    textArea.setCaretPosition(pos2);

Результат: enter image description here

Я хочу, чтобы это было в правой верхней части экрана, но в этом коде показано в нижней части scrollpane. Кто-нибудь знает, как это изменить? БЛАГОДАРЯ.

Ответ 1

Вы можете достичь этого, хотя и не напрямую, поскольку вам нужно сохранить ссылку на Highlight, добавленную вами в указанную строку, поэтому вам нужно пройти через все основные моменты, чтобы удалить тот, который вы хотите, посмотрите на прилагаемую программу, возможно, это поможет вам достичь того, чего вы так желаете:

ПОСЛЕДНИЙ РЕДАКТИРОВАТЬ: НОВЫЙ КОД, УДАЛЕН НЕКОТОРЫЕ ОШИБКИ И СМОТРЕТЬ, КАК ДОБАВЛЯЕТ ЖЕЛАЮЩАЯ ФУНКЦИОНАЛЬНОСТЬ, СВЯЗАННАЯ С УСТАНОВКОЙ ПОЛОЖЕНИЯ CARET

import java.awt.*;
import java.awt.event.*;
import java.util.Map;
import java.util.HashMap;
import javax.swing.*;
import javax.swing.text.*;

public class TextHighlight
{
    private JTextArea tarea;
    private JComboBox cbox;
    private JTextField lineField;
    private String[] colourNames = {"RED", "ORANGE", "CYAN"};

    private Highlighter.HighlightPainter redPainter;
    private Highlighter.HighlightPainter orangePainter;
    private Highlighter.HighlightPainter cyanPainter;   

    private int firstUpdateIndex;
    private int counter;

    private Map<Integer, Highlighter.Highlight> highlights = new HashMap<Integer, Highlighter.Highlight>();

    public TextHighlight()
    {
        redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
        orangePainter = new DefaultHighlighter.DefaultHighlightPainter(Color.ORANGE);
        cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.CYAN);

        firstUpdateIndex = -1;
        counter = 0;
    }

    private void createAndDisplayGUI()
    {
        final JFrame frame = new JFrame("Text HIGHLIGHT");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel();
        contentPane.setBorder(BorderFactory.createTitledBorder(
                BorderFactory.createEmptyBorder(5, 5, 5, 5), "Highlighter JTextArea"));

        tarea = new JTextArea(10, 10);
        JScrollPane scrollPane = new JScrollPane(tarea);
        contentPane.add(scrollPane);

        JButton remHighButton = new JButton("REMOVE HIGHLIGHT");
        remHighButton.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                String input = JOptionPane.showInputDialog(frame, "Please Enter Start Index : "
                                                        , "Highlighting Options : "
                                                        , JOptionPane.PLAIN_MESSAGE);

                if (input != null && (highlights.size() > 0))
                {               
                    int startIndex = Integer.parseInt(input.trim());
                    Highlighter highlighter = tarea.getHighlighter();
                    highlighter.removeHighlight(highlights.get(startIndex));
                    tarea.setCaretPosition(startIndex);
                    tarea.requestFocusInWindow();
                    highlights.remove(startIndex);
                }
            }
        });

        JButton button = new JButton("HIGHLIGHT TEXT");
        button.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent ae)
            {
                String text = null;
                text = tarea.getSelectedText();
                if (text != null && text.length() > 0)
                {
                    int startIndex = tarea.getText().indexOf(text);
                    int endIndex = startIndex + text.length();
                    Highlighter highlighter = tarea.getHighlighter();

                    int selection = JOptionPane.showConfirmDialog(
                                            frame, getOptionPanel(), "Highlight Colour : "
                                                , JOptionPane.OK_CANCEL_OPTION
                                                , JOptionPane.PLAIN_MESSAGE);

                    System.out.println("TEXT : " + text);
                    System.out.println("START INDEX : " + startIndex);
                    System.out.println("END INDEX : " + endIndex);

                    if (selection == JOptionPane.OK_OPTION)
                    {
                        String colour = (String) cbox.getSelectedItem();
                        try
                        {
                            if (colour == colourNames[0])
                            {
                                System.out.println("Colour Selected : " + colour);
                                highlighter.addHighlight(startIndex, endIndex, redPainter);
                            }
                            else if (colour == colourNames[1])
                            {
                                System.out.println("Colour Selected : " + colour);
                                highlighter.addHighlight(startIndex, endIndex, orangePainter);
                            }
                            else if (colour == colourNames[2])
                            {
                                System.out.println("Colour Selected : " + colour);
                                highlighter.addHighlight(startIndex, endIndex, cyanPainter);
                            }
                            Highlighter.Highlight[] highlightIndex = highlighter.getHighlights();
                            System.out.println("Lengh of Highlights used : " + highlightIndex.length);
                            highlights.put(startIndex, highlightIndex[highlightIndex.length - 1]);
                        }
                        catch(BadLocationException ble)
                        {
                            ble.printStackTrace();
                        }
                    }
                    else if (selection == JOptionPane.CANCEL_OPTION)
                    {
                        System.out.println("CANCEL BUTTON PRESSED.");
                    }
                    else if (selection == JOptionPane.CLOSED_OPTION)
                    {
                        System.out.println("JOPTIONPANE CLOSED DELIBERATELY.");
                    }                   
                }
            }
        });

        frame.add(remHighButton, BorderLayout.PAGE_START);
        frame.add(contentPane, BorderLayout.CENTER);
        frame.add(button, BorderLayout.PAGE_END);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel getOptionPanel()
    {
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createTitledBorder(
                        BorderFactory.createLineBorder(Color.DARK_GRAY, 2), "COLOUR SELECTION"));
        panel.setLayout(new GridLayout(0, 2, 5, 5));

        JLabel colourLabel = new JLabel("Select One Colour : ");
        cbox = new JComboBox(colourNames);

        panel.add(colourLabel);
        panel.add(cbox);

        return panel;
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new TextHighlight().createAndDisplayGUI();
            }
        });
    }
}

OUTPUT:

НАЧАТЬ: AT START

ПЕРВАЯ ЛИНИЯ ВЫСОКОЙ FIRST LINE ВТОРОЕ SECOND LINE

УДАЛЕННЫЙ ВЫСОТА AFTER

ОСВЕЩЕНИЕ ОДНОЙ ЛИНИИ С РАЗЛИЧНЫМ ЦВЕТОМ HIGHLIGHT AGAIN

ПОСЛЕДНИЙ РЕДАКТИРОВАТЬ в строках с КОДОМ ОБРАЗЦА В ВОПРОСЕ

import java.awt.*;
import java.net.MalformedURLException;

import javax.swing.*;
import javax.swing.text.*;

public class Test {
    public static void main(final String[] args) throws MalformedURLException {
        SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            try {
                init();
            } catch (BadLocationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    });
}

private static void init() throws BadLocationException {
    JFrame frame = new JFrame();
    final JTextArea textArea = new JTextArea();
    JScrollPane pane = new JScrollPane(textArea);
    textArea.setText("Something. Something else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Samething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sbmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Scmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sdmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Semething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sfmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sgmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n");
    textArea.setSelectionColor(Color.RED);
    frame.add(pane);
    frame.setSize(300, 120);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    String turnToString2 = "Sdmething else.\nA second line\na third line"
            + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla";
    int pos2 = textArea.getText().indexOf(turnToString2);
    Rectangle startIndex = textArea.modelToView(pos2);
    textArea.getHighlighter().addHighlight(pos2,
            pos2 + turnToString2.length(),
            new DefaultHighlighter.DefaultHighlightPainter(Color.yellow));    
    int y = startIndex.y + (pane.getHeight() - 10);
    System.out.println("Pane Height : " + pane.getHeight());
    System.out.println("X : " + startIndex.x);
    System.out.println("Y : " + y);
    System.out.println("Y (pos2) : " + startIndex.y);
    textArea.setCaretPosition(textArea.viewToModel(new Point(startIndex.x, y)));
    pane.scrollRectToVisible(new Rectangle(startIndex.x, y));
    }
}

Вот ВЫХОД:

TOP RIGHT

Ответ 2

Чтобы установить цвет фона выбора, используйте setSelectionColor (показано ниже, но не используется).

Я действительно не понимаю, что вы говорите с ним, всегда появляется в нижней части окна. Я хочу, чтобы он был наверху, но я предполагаю (и, может быть, я ошибаюсь здесь), что ваше текстовое поле находится в scrollpane и что, выделив текст, он прокручивается до конца вашего выбора, поэтому я предлагаю установить позицию каретки после выделения текста.

Вот пример того, что я понял. Сообщите мне, если это не то, что вы ищете:

import java.awt.Color;
import java.net.MalformedURLException;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;

public class Test {
    public static void main(final String[] args) throws MalformedURLException {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    init();
                } catch (BadLocationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        });
    }

    private static void init() throws BadLocationException {
        JFrame frame = new JFrame();
        final JTextArea textArea = new JTextArea();
        JScrollPane pane = new JScrollPane(textArea);
        textArea.setText("Something. Something else.\nA second line\na third line"
                + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"
                + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n");
        textArea.setSelectionColor(Color.RED);
        frame.add(pane);
        frame.setSize(300, 120);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        String turnToString = "Something else.\nA second line\na third line"
                + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla";
        final int pos = textArea.getText().indexOf(turnToString);
        textArea.getHighlighter().addHighlight(pos,
                pos + turnToString.length(),
                new DefaultHighlighter.DefaultHighlightPainter(Color.yellow));
        textArea.scrollRectToVisible(new Rectangle(0, 0, pane.getViewport().getWidth(), pane.getViewport().getHeight()));
            SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        textArea.setCaretPosition(pos);
                    }
            });
    }
}

Ответ 3

Я думаю, что не удалось изменить эти методы для всех JTextComponents в том случае, если там используется Highlighter, но возможно изменить только Foreground

например

import java.awt.*;
import javax.swing.*;
import javax.swing.text.DefaultHighlighter;

public class TextAreaLineHightLight {

    public static void main(String[] args) throws Exception {
        UIManager.put("TextArea.selectionBackground", Color.yellow);
        UIManager.put("TextArea.selectionForeground", Color.red);

        String string = "Lorem ipsum eum putant gubergren evertitur in, "
                + "no assueverit vituperatoribus eum. Ea cibo offendit vim, est et vivendum qualisque prodesset. "
                + "Vis doctus expetenda contentiones an, no ius mazim epicuri expetendis, "
                + "saperet salutandi forensibus ne usu. Ex fugit alterum usu. "
                + "His ignota cotidieque in, augue erroribus eam no.";
        JTextArea textArea = new JTextArea(string);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        JScrollPane textAreaScroll = new JScrollPane(textArea);
        JFrame frame = new JFrame();
        frame.setLayout(new BorderLayout());
        frame.add(textAreaScroll, BorderLayout.CENTER);
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        String term = "qualisque prodesset. "
                + "Vis doctus expetenda contentiones an, no ius mazim epicuri expetendis";
        int termOffset = string.indexOf(term);
        Rectangle view = textArea.modelToView(termOffset);
        int startOffset = textArea.viewToModel(new Point(0, view.y));
        //int rowH = textArea.
        int endOffset = textArea.viewToModel(new Point(textArea.getSize().width, view.y));
        textArea.getHighlighter().addHighlight(startOffset, endOffset, new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW));
    }
}

с тем же результатом для JTextPane

import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class TextPaneHighlighting extends JFrame {

    private static final long serialVersionUID = 1L;
    private Highlighter.HighlightPainter cyanPainter;
    private Highlighter.HighlightPainter redPainter;

    public TextPaneHighlighting() {
        UIManager.put("TextPane.selectionBackground", Color.yellow);
        UIManager.put("TextPane.selectionForeground", Color.red);
        JTextPane textPane = new JTextPane();
        textPane.setText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\n");
        JScrollPane scrollPane = new JScrollPane(textPane);
        getContentPane().add(scrollPane);//  Highlight some text
        cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.cyan);
        redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.red);
        try {
            textPane.getHighlighter().addHighlight(0, 3, DefaultHighlighter.DefaultPainter);
            textPane.getHighlighter().addHighlight(8, 14, cyanPainter);
            textPane.getHighlighter().addHighlight(19, 24, redPainter);
        } catch (BadLocationException ble) {
        }
    }

    public static void main(String[] args) {
        TextPaneHighlighting frame = new TextPaneHighlighting();
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setSize(300, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Ответ 4

Чтобы решить 2) Используйте modelToView для получения точки первой выбранной строки. Затем используйте scrollRectToVisible, используя точку (ПРИМЕЧАНИЕ: высота прямоугольника должна быть высотой вашего просмотра).