martes, 25 de febrero de 2014

Tool Tip multilínea en Java Swing

Introducción


Si has programado en Java Swing estarás familiarizado con el método JComponent#setToolTipText(String) para mostrar Tool Tips (esos pequeños mensajes emergentes que suelen ser descripciones o sugerencias). Si no es así, aquí está el tutorial oficial:

En principio, todo el texto se muestra en una única línea, eliminándose todos los saltos de línea (tabuladores también) presentes en la String.

¿Y si necesitas mostrar varias líneas de texto en un Tool Tip?

HTML al rescate


Diversos componentes de Swing permiten mostrar HTML 3.2 estático con cierto soporte de CSS. Aprovechando dicha característica, si en vez de pasar una String directamente, se envuelve en un elemento PRE de HTML se obtiene fácilmente el comportamiento multilínea. Por ejemplo:


String toolTipHTML= ""
    + "<html><body><pre>"
    + "This is a\nmultiline tooltip."
    + "</pre></body></html>"
;

En el siguiente enlace hay un pequeño programa para demostrar esta característica.

Conclusiones


La limitación de una única línea en los Tool Tips se puede evitar de un modo muy simple añadiendo muy poco código. Hay otras alternativas, pero aquí se muestra una efectiva y muy sencilla de implementar.
El soporte de HTML incrustado en Swing tiene importantes limitaciones, pero para algunas cosas resulta muy útil.


Enlaces


Enlaces de interés relacionados con este artículo:


(Actualizado 28/02/2014)

Source code: MultilineToolTipTest

Código fuente del programa MultilineToolTipTest

Ver la entrada correspondiente en el siguiente enlace:


Tool Tip multilínea en Java Swing

package pruebas;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;

public class MultilineToolTipTest {

    public static void test() {
        StringBuilder buf= new StringBuilder();
        buf.append("This is a tool tip:\n");

        for (int i= 0; i < 5; i++) {
            String line= String.format("\t Line %s%n", i);
            buf.append(line);
        }

        String toolTip= buf.toString();
        String toolTipHTML= "<html><body><pre>"+ toolTip + "</pre></body></html>";

        JLabel label1= new JLabel();
        label1.setText("Label with monoline tool tip text.");
        label1.setToolTipText(toolTip);

        JLabel labelN= new JLabel();
        labelN.setText("Label with multiline tool tip text.");
        labelN.setToolTipText(toolTipHTML);

        JPanel content= new JPanel(null);
        BoxLayout boxLayout= new BoxLayout(content, BoxLayout.PAGE_AXIS);
        content.setLayout(boxLayout);
        content.add(label1);
        content.add( new JSeparator(JSeparator.HORIZONTAL) );
        content.add(labelN);

        JFrame frame= new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() { public void run() {
            MultilineToolTipTest.test();
        }});
    }

}