Format Jlabel text with different colors

Asked

Viewed 804 times

2

How could I format with different "properties" a JLabel and its content?

For example, I wish I could set a color for my text JLabel, and another to string that this concatenated with it. It is possible?

In my case, he was alone in a "way", and the html that I tried to use, also did not work.

What I tried to:

import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Teste extends JFrame {

    public static void main(String[] args) {
        new Teste().setVisible(true);
    }

    private JPanel painel = new JPanel();

    private Font fonte = new Font("SansSerif", Font.BOLD, 15);
    private JLabel label = new JLabel();

    private String string = "string";

    public Teste() {

        setSize(500, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        painel.add(label);
        add(painel);

        label.setText("Label + " + "<html><font color=#166B44> " + string + " </font></html>");
        label.setFont(fonte);
        label.setForeground(Color.red);

    }
}

2 answers

2

For the purpose you want to work. All the text of JLabel has to be inside the <html>...</html>. Anything you put out of it will go wrong.

For example:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class TesteCor {

    public static void main(String[] args) {
        EventQueue.invokeLater(TesteCor::executar);
    }

    public static void executar() {
        JFrame frame = new JFrame();
        JPanel painel = new JPanel();

        Font fonte = new Font("SansSerif", Font.BOLD, 15);
        JLabel label = new JLabel();

        frame.setSize(500, 200);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        painel.add(label);
        frame.add(painel);

        label.setText(""
                + "<html>"
                + "Cor padrão "
                + "<font color=\"red\">Vermelho</font> "
                + "<font color=\"blue\">Azul</font> "
                + "<font color=\"green\">Verde</font> "
                + "<font color=\"yellow\">Amarelo</font> "
                + "</html>");
        label.setFont(fonte);
        label.setForeground(Color.pink);
        frame.setVisible(true);
    }
}

Notice I put the Color.pink like the foreground label.

As to the EventQueue.invokeLater, see this my other answer that explains it.

That is the result:

Tela resultante

2


It is not possible to do this using JLabel, this component is for plain text. Of course it accepts HTML tags for text formatting, but in addition to "clutter" the code, it will make it very difficult to maintain afterwards.

Fortunately there are alternatives of components for this purpose, which is the case of JTextPane or JEditorPane, which accept text stylization, even if fragmented, as you need.

Take this example:

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

public class JTextPaneExample {

    public void createAndShowGUI() {
        JFrame f = new JFrame("JTextPaneExample");

        // cria um StyleContext e um Document para o jtextpane
        StyleContext sc = new StyleContext();
        final DefaultStyledDocument doc = new DefaultStyledDocument(sc);
        JTextPane pane = new JTextPane(doc);
        pane.setEditable(false);

        // cria um estilo e adiciona atributos personalizados nele
        final Style redStyle = sc.addStyle("RED", null);
        redStyle.addAttribute(StyleConstants.Foreground, Color.red);
        redStyle.addAttribute(StyleConstants.FontSize, new Integer(16));

        final Style blueStyle = sc.addStyle("BLUE", null);
        blueStyle.addAttribute(StyleConstants.Foreground, Color.blue);
        blueStyle.addAttribute(StyleConstants.FontSize, new Integer(14));
        blueStyle.addAttribute(StyleConstants.Bold, new Boolean(true));

        try {
            // insere um texto inicial com uma style
            doc.insertString(0, "Texto inicial ", redStyle);
            // insere texto concatenado com outra style
            doc.insertString(pane.getText().length(), "texto concatenado", blueStyle);
        } catch (BadLocationException e1) {
            e1.printStackTrace();
        }

        f.getContentPane().add(new JScrollPane(pane));
        f.setSize(400, 300);
        f.setVisible(true);
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            new JTextPaneExample().createAndShowGUI();;
        });
    }
}

Which results in:

inserir a descrição da imagem aqui

A StyleContext is nothing more than a pool styles, where we will add the styles we will use in the component. The DefaultStyledDocument is the class that will interpret these styles and apply to the text, as we concatenate and pass the styles to the text fragments. The interface Style is the style itself, where we configure details like color, size and font type we want from the text.


References:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.