Java 如何更改 JTextArea 中的文本颜色?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9650992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 05:38:29  来源:igfitidea点击:

How to change text color in the JTextArea?

javaswingcolorsjtextareajtextcomponent

提问by Celine

I need to know how to do this:

我需要知道如何做到这一点:

Let's say: I have a code in the JTextArealike this:

比方说:我有这样的代码JTextArea

LOAD R1, 1
DEC R1
STORE M, R1
ADD R4, R1,8

I wanted to change the color of LOAD, DEC, STOREand ADDto color BLUE R1, R4to color green Mto RED numbers to ORANGE

我想改变的颜色LOADDECSTOREADD以颜色为蓝色 R1R4颜色绿色 M到红色的数字橙色

How to change the color of this text? These text were from notepad or can be directly type to the text area.

如何更改此文本的颜色?这些文本来自记事本或可以直接输入到文本区域。

采纳答案by nIcE cOw

JTextAreais meant to entertain Plain Text. The settings applied to a single character applies to whole of the document in JTextArea. But with JTextPaneor JEditorPaneyou have the choice, to colour your String Literalsas per your liking. Here with the help of JTextPane, you can do it like this :

JTextArea是为了娱乐Plain Text。应用于单个字符的设置适用于JTextArea. 但是,JTextPane或者JEditorPane您可以选择,String Literals根据自己的喜好为您着色。在JTextPane的帮助下,您可以这样做:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.border.*;

import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;

public class TextPaneTest extends JFrame
{
    private JPanel topPanel;
    private JTextPane tPane;

    public TextPaneTest()
    {
        topPanel = new JPanel();        

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);            

        EmptyBorder eb = new EmptyBorder(new Insets(10, 10, 10, 10));

        tPane = new JTextPane();                
        tPane.setBorder(eb);
        //tPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
        tPane.setMargin(new Insets(5, 5, 5, 5));

        topPanel.add(tPane);

        appendToPane(tPane, "My Name is Too Good.\n", Color.RED);
        appendToPane(tPane, "I wish I could be ONE of THE BEST on ", Color.BLUE);
        appendToPane(tPane, "Stack", Color.DARK_GRAY);
        appendToPane(tPane, "Over", Color.MAGENTA);
        appendToPane(tPane, "flow", Color.ORANGE);

        getContentPane().add(topPanel);

        pack();
        setVisible(true);   
    }

    private void appendToPane(JTextPane tp, String msg, Color c)
    {
        StyleContext sc = StyleContext.getDefaultStyleContext();
        AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);

        aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
        aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);

        int len = tp.getDocument().getLength();
        tp.setCaretPosition(len);
        tp.setCharacterAttributes(aset, false);
        tp.replaceSelection(msg);
    }

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

here is the Output :

这是输出:

JTextPane

JTextPane

回答by Scott Faria

Use can either use a JEditorPane with HTML or write a custom Document that colors elements.

用户可以将 JEditorPane 与 HTML 一起使用,也可以编写为元素着色的自定义文档。

回答by Gigatron

You can't have different characters in different colors in a JTextArea (at least not without some complex hackery). Use a JTextPane or JEditorPane instead. Then you can access its StyledDocument:

在 JTextArea 中不能有不同颜色的不同字符(至少在没有一些复杂的技巧的情况下不能)。请改用 JTextPane 或 JEditorPane。然后你可以访问它的StyledDocument

StyledDocument sdoc = pane.getStyledDocument()

EDITED: changed to directly calling getStyledDocument, instead of casting the result of getDocument()

已编辑更改为直接调用getStyledDocument,而不是转换 getDocument() 的结果

Call setCharacterAttributeson the StyledDocumentto change the colors of individual characters or substrings.

呼叫setCharacterAttributesStyledDocument改变单个字符或字符串的颜色。

回答by mKorbel

since is possible use Highlighter(or Html) for JTextArea, this API implementing reduced options for stylled text

由于可以使用Highlighter(或 Html) for JTextArea,此 API 实现了样式文本的减少选项

enter image description here

在此处输入图片说明

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

public class TextPaneHighlighting {

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

    public TextPaneHighlighting() {
        JFrame frame = new JFrame();
        JTextPane textPane = new JTextPane();
        textPane.setText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\n");
        JScrollPane scrollPane = new JScrollPane(textPane);
        frame.add(scrollPane, BorderLayout.CENTER);//  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) {
        }
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(300, 200));
        frame.setLocationRelativeTo(null);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                TextPaneHighlighting tph = new TextPaneHighlighting();
            }
        });
    }
}

in compare with JTextPanethere is options more variable, e.g. Highlighter, with Html or without Html, Font, or put another JComponent inside by using Html or directly (know JTextArea too, but...)

相比之下,JTextPane有更多可变的选项,例如荧光笔,带 Html 或不带 Html,字体,或者通过使用 Html 或直接将另一个 JComponent 放入其中(也知道 JTextArea,但是...)

enter image description here

在此处输入图片说明

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

public class Fonts implements Runnable {

    private String[] fnt;
    private JFrame frm;
    private JScrollPane jsp;
    private JTextPane jta;
    private int width = 450;
    private int height = 300;
    private GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
    private StyledDocument doc;
    private MutableAttributeSet mas;
    private int cp = 0;
    private Highlighter.HighlightPainter cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.cyan);
    private Highlighter.HighlightPainter redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.red);
    private Highlighter.HighlightPainter whitePainter = new DefaultHighlighter.DefaultHighlightPainter(Color.white);
    private int _count = 0;
    private int _lenght = 0;

    public Fonts() {
        jta = new JTextPane();
        doc = jta.getStyledDocument();
        jsp = new JScrollPane(jta);
        jsp.setPreferredSize(new Dimension(height, width));
        frm = new JFrame("awesome");
        frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frm.setLayout(new BorderLayout());
        frm.add(jsp, BorderLayout.CENTER);
        frm.setLocation(100, 100);
        frm.pack();
        frm.setVisible(true);
        jta.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
        fnt = ge.getAvailableFontFamilyNames();
        mas = jta.getInputAttributes();
        new Thread(this).start();
    }

    @Override
    public void run() {
        for (int i = 0; i < fnt.length; i++) {
            StyleConstants.setBold(mas, false);
            StyleConstants.setItalic(mas, false);
            StyleConstants.setFontFamily(mas, fnt[i]);
            StyleConstants.setFontSize(mas, 16);
            dis(fnt[i]);
            try {
                Thread.sleep(75);
            } catch (Exception e) {
                e.printStackTrace();
            }
            StyleConstants.setBold(mas, true);
            dis(fnt[i] + " Bold");
            try {
                Thread.sleep(75);
            } catch (Exception e) {
                e.printStackTrace();
            }
            StyleConstants.setItalic(mas, true);
            dis(fnt[i] + " Bold & Italic");
            try {
                Thread.sleep(75);
            } catch (Exception e) {
                e.printStackTrace();
            }
            StyleConstants.setBold(mas, false);
            dis(fnt[i] + " Italic");
            try {
                Thread.sleep(75);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        jta.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }

    public void dis(String s) {
        _count++;
        _lenght = jta.getText().length();
        try {
            doc.insertString(cp, s, mas);
            doc.insertString(cp, "\n", mas);
        } catch (Exception bla_bla_bla_bla) {
            bla_bla_bla_bla.printStackTrace();
        }
        if (_count % 2 == 0) {
            try {
                jta.getHighlighter().addHighlight(1, _lenght - 1, cyanPainter);
            } catch (BadLocationException bla_bla_bla_bla) {
            }
        } else if (_count % 3 == 0) {
            try {
                jta.getHighlighter().addHighlight(1, _lenght - 1, redPainter);
            } catch (BadLocationException bla_bla_bla_bla) {
            }
        } else {
            try {
                jta.getHighlighter().addHighlight(1, _lenght - 1, whitePainter);
            } catch (BadLocationException bla_bla_bla_bla) {
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                Fonts fs = new Fonts();
            }
        });
    }
}

回答by Rok T.

For some basic coloring (the only thing you can do with JTextArea) you can change the background and foreground colors to something like this, but this will color all text of course:

对于一些基本的着色(您可以使用 JTextArea 做的唯一事情),您可以将背景和前景色更改为这样的颜色,但这当然会为所有文本着色:

    textArea.setBackground(Color.ORANGE);
    textArea.setForeground(Color.RED);

The result you get:

你得到的结果:

enter image description here

在此处输入图片说明

回答by Mark Jeronimus

Just another alternative. For the theory, see other answers.

只是另一种选择。有关理论,请参阅其他答案。

This one uses preconfigured styles as fields. Watch out when exposing these fields as they are, ehm, mutable.

这个使用预配置的样式作为字段。当暴露这些字段时要小心,嗯,可变的。

public final class SomeClass {
    private final JTextPane           textPane = new JTextPane();
    private final MutableAttributeSet attributes1;
    private final MutableAttributeSet attributes2;

    public SomeClass() {
        attributes1 = new SimpleAttributeSet(textPane.getInputAttributes());
        StyleConstants.setForeground(attributes1, Color.BLACK);
        StyleConstants.setBackground(attributes1, Color.GREEN);
        attributes2 = new SimpleAttributeSet(textPane.getInputAttributes());
        StyleConstants.setForeground(attributes2, Color.WHITE);
        StyleConstants.setBackground(attributes2, Color.RED);
    }

    private void print(String msg, AttributeSet attributes) {
        try {
            textPane.getStyledDocument().insertString(textPane.getDocument().getLength(), msg, attributes);
        } catch (BadLocationException ignored) { }
    }
}

[Edit] changed back to insertStringinstead of replaceSelectionbecause the latter fails when the pane is not editable

[编辑] 改回insertString而不是replaceSelection因为后者在窗格不可编辑时失败

回答by Mark Jeronimus

Just another alternative. For the theory, see other answers.

只是另一种选择。有关理论,请参阅其他答案。

This one creates attributes when adding text, instead of deriving the style like in the answer of nIcE cOw. The functionality is the same, as the pane will merge the attributes with any previously used attributes.

这个在添加文本时创建属性,而不是像 nIcE cOw 的答案那样派生样式。功能是相同的,因为窗格会将属性与任何以前使用的属性合并。

public final class SomeClass {
    private final JTextPane           textPane = new JTextPane();

    private void print(String msg, Color foreground, Color background) {
        AttributeSet attributes = new SimpleAttributeSet(textPane.getInputAttributes());
        StyleConstants.setForeground(attributes, foreground);
        StyleConstants.setBackground(attributes, background);

        try {
            textPane.getStyledDocument().insertString(textPane.getDocument().getLength(), msg, attributes);
        } catch (BadLocationException ignored) { }
    }
}

[Edit] changed back to insertStringinstead of replaceSelectionbecause the latter fails when the pane is not editable

[编辑] 改回insertString而不是replaceSelection因为后者在窗格不可编辑时失败