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

Posted

技术标签:

【中文标题】如何更改 JTextArea 中的文本颜色?【英文标题】:How to change text color in the JTextArea? 【发布时间】:2012-03-27 21:41:07 【问题描述】:

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

假设:我在JTextArea 中有这样的代码:

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

我想将LOADDECSTOREADD 的颜色更改为蓝色 R1, R4 变为绿色 M 到红 数字变为橙色

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

【问题讨论】:

最好不要使用 JTextArea 而是使用 JEditorPane 或类似的。 正确使用JTextComponent that support stylled text,JTextArea 不是正确的方法...... 【参考方案1】:

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

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

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] 改回 insertString 而不是 replaceSelection,因为后者在窗格不可编辑时失败

【讨论】:

【参考方案2】:

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

这是在添加文本时创建属性,而不是像 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] 改回 insertString 而不是 replaceSelection,因为后者在窗格不可编辑时失败

【讨论】:

【参考方案3】:

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

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

你得到的结果:

【讨论】:

【参考方案4】:

JTextArea 是为了招待Plain Text。应用于单个字符的设置应用于JTextArea 中的整个文档。但是对于JTextPaneJEditorPane,您可以选择根据自己的喜好为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();
                
            );
    

这是输出:

【讨论】:

感谢您的回答。,但是先生的话是动态的。?不是静态的。 @Celine :欢迎您,很高兴它在某种程度上帮助了您。那么你只需将你的话一一传递给这个函数,这只是一个小示例程序。您必须根据需要找到提供单词的逻辑:-) @vijay : 不,它是桌面的背景,JFrameWindows Look And FeelWindows 7 是透明的。尽管您可以使用该答案中指定的Look And Feel 中的任何一个来更改JFrame :-) 嘿,我知道这是不久前发布的,但这确实帮助了我。我一直在努力寻找答案,这让事情变得容易多了。您介意多解释一下您在 appendToPane 方法中所做的事情吗?只是为了让我更好地了解正在发生的事情【参考方案5】:

在 JTextArea 中不能有不同颜色的不同字符(至少在没有一些复杂的黑客攻击的情况下是这样)。请改用 JTextPane 或 JEditorPane。然后就可以访问它的StyledDocument

StyledDocument sdoc = pane.getStyledDocument()

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

StyledDocument 上调用setCharacterAttributes 以更改单个字符或子字符串的颜色。

【讨论】:

【参考方案6】:

因为JTextArea 可以使用Highlighter(或html),所以这个API 实现了风格化文本的减少选项

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

JTextPane 相比,有更多变数的选项,例如荧光笔,带 Html 或不带 Html、Font,或使用 Html 或直接将另一个 JComponent 放入其中(也知道 JTextArea,但是...)

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

【讨论】:

是否可以同时更改文本颜色而不仅仅是 BG? @Lennart Rolland JTextArea 只有一种颜色,JTextPane 可以设置前景和背景【参考方案7】:

使用可以使用带有 HTML 的 JEditorPane 或编写为元素着色的自定义文档。

【讨论】:

以上是关于如何更改 JTextArea 中的文本颜色?的主要内容,如果未能解决你的问题,请参考以下文章

JTextArea 中的文本更改事件?如何?

如何在 JTextArea 中使用 html 标签

Java / Swing:JScrollPane中的JTextArea,如何防止自动滚动?

Java - 在 JTextArea 中将颜色设置为文本

如何将 JTextArea 中的选定文本转换为字符串?

如何计算文本在 JTextArea 中的行数(以及每行中的列数)?