How to change text color in the JTextArea?
Asked Answered
L

7

39

I need to know how to do this:

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

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

I wanted to change the color of LOAD, DEC, STORE and ADD to color BLUE R1, R4 to color green M to RED numbers to ORANGE

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

Lettyletup answered 10/3, 2012 at 23:11 Comment(2)
Best probably not to use a JTextArea but instead to use a JEditorPane or similar.Piton
right use JTextComponent that support stylled text, JTextArea isn't right way how to do it ...Orel
C
94

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

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

Caundra answered 11/3, 2012 at 3:24 Comment(4)
thanks for the answer.,, but words are dynamic sir.?., it is not static.Lettyletup
@Lettyletup : Your Welcome and Glad it helped you in some way. Well then you simply have to pass your words one by one to this function, this one is just a small example program. You have to find the logic to supply words according to your needs :-)Caundra
@vijay : Nah, it's the background of the Desktop, the JFrame is transparent from Windows Look And Feel from Windows 7. Though you can change the JFrame by using any of these Look And Feel, specified in that answer :-)Caundra
Hey I know this was posted a while ago, but this really helped me out. I had been struggling to find an answer to this and this makes things so much easier. Would you mind explaining a bit more of what you did in the appendToPane method? Just so I better understand what's happeningGanda
O
24

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

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 JTextPane there 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...)

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();
            }
        });
    }
}
Orel answered 11/3, 2012 at 0:29 Comment(2)
Is it possible to also change text color and not just BG?Mercado
@Lennart Rolland only one Color for JTextArea, for JTextPane is possible to set fore&backgroundOrel
W
10

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:

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

The result you get:

enter image description here

Weywadt answered 25/8, 2017 at 13:1 Comment(0)
M
3

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

Macedo answered 10/3, 2012 at 23:35 Comment(0)
G
2

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:

StyledDocument sdoc = pane.getStyledDocument()

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

Call setCharacterAttributes on the StyledDocument to change the colors of individual characters or substrings.

Genius answered 10/3, 2012 at 23:47 Comment(0)
I
1

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 insertString instead of replaceSelection because the latter fails when the pane is not editable

Ickes answered 5/6, 2018 at 10:38 Comment(0)
I
0

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.

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 insertString instead of replaceSelection because the latter fails when the pane is not editable

Ickes answered 5/6, 2018 at 10:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.