简体   繁体   English

如何在Java Swing TextArea中更改突出显示颜色? 并且,更改与突出显示位置相对应的文本的开头

[英]How to change highlighting color in Java Swing TextArea? And also, change the beginning of text corresponding to the highlighting location

Problem 1: BY using defaulthighlighter, I can make the focused lines change to blue. 问题1:通过使用defaulthighlighter,我可以使聚焦线变为蓝色。 Now I want to change it to other colors. 现在,我想将其更改为其他颜色。 Do anyone know how to change this parameter? 有人知道如何更改此参数吗? --- solved - - 解决了

Problem 2: pos is the beginning index of my substring which I want to highlight. 问题2:pos是我要突出显示的子字符串的开始索引。 I use setCaretPosition(pos); 我使用setCaretPosition(pos); to update the showing content. 更新显示内容。 But it always appears at the bottom of the window. 但是它总是出现在窗口的底部。 I want to have it at the top. 我想把它放在顶部。 Could anyone tell me how to deal with that? 谁能告诉我该如何处理?

I use one demo to show my problem: 我使用一个演示来展示我的问题:

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);

The result is : 结果是: 在此处输入图片说明

I want it to be at the right top of the screen but in this code, it is shown at the bottom of the scrollpane. 我希望它位于屏幕的右上方,但是在这段代码中,它显示在滚动窗格的底部。 Can anyone know how to change this? 有人知道如何更改吗? THanks. 谢谢。

You can achieve this, though not directly, since you have to save the reference to the Highlight that you had added to the said line, hence you have to traverse through all the Highlights to remove the one you want, have a look at the program attached, might be this will help you to attain what you so desire : 您可以实现此操作,尽管不是直接实现,因为您必须保存对添加到上述行的“ Highlight的引用,因此您必须遍历所有“突出显示”以删除所需的突出显示,请看一下程序可能会帮助您实现自己的愿望:

LATEST EDIT : NEW CODE, REMOVED SOME BUGS AND SEEMS LIKE ADDED THE DESIRED FUNCTIONALITY RELATED TO SETTING CARET POSITION 最新编辑:新代码,已删除的一些错误和类似添加了与设置购物车位置有关的功能的零件

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 : 输出:

BEGIN : 开始 : 开始时

HIGHLIGHT FIRST LINE 重点第一线 第一行 SECOND 第二 第二行

REMOVED HIGHLIGHT 删除的要点 后

HIGHLIGHTING THE SAME LINE WITH DIFFERENT COLOUR 用不同的颜色突出显示同一行 再次亮点

LATEST EDIT in lines with the SAMPLE CODE in the QUESTION 与问题中的示例代码一致的最新编辑

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));
    }
}

Here is the OUTPUT : 这是输出:

右上

To set the selection background color, use setSelectionColor (illustrated below but not used). 要设置选择背景颜色,请使用setSelectionColor(如下所示,但未使用)。

I don't really understand what you're saying with it always appears at the bottom of the window. 我真的不明白您在说什么总是出现在窗口底部。 I want to have it at the top but I am guessing (and I may be wrong here) that your textarea is in a scrollpane and that by highlighting the text it scrolls to the end of your selection, so I suggest to set the caret position after highlighting the text. 我想将其放在顶部,但我猜(这里我可能错了),您的文本区域在滚动窗格中,并且通过突出显示文本滚动到您选择的末尾,因此我建议设置插入标记的位置突出显示文本后。

Here is a sample of what I understood. 这是我了解的示例。 Let me know if this is not what you're looking for: 让我知道这是否不是您想要的东西:

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);
                    }
            });
    }
}

I think that not accesible to change these methods for all JTextComponents in the case that is there used Highlighter, but is possible to change Foreground only 我认为在使用荧光笔的情况下无法为所有JTextComponents更改这些方法,但是只能更改前景

for example 例如

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));
    }
}

with the same result for JTextPane 对于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);
    }
}

To solve 2) Use modelToView to get point of the first selected row. 解决方案2)使用modelToView获取第一个选定行的点。 Then use scrollRectToVisible using the Point (NOTE: height of the rectangle must be your viewport height). 然后,使用Point使用scrollRectToVisible(注意:矩形的高度必须是您的视口高度)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM