Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JLabel shifts the text vertically down while displaying HTML

I would like to understand why a JLabel, rendering HTML, shifts the vertical position of it's output text, whereas a JLabel which renders non-HTML, does not.

  • Java version used: 1.6.0_37
  • Swing Look and Feel used: Windows ("com.sun.java.swing.plaf.windows.WindowsLookAndFeel")
  • OS: Windows 7 64 Bit

I did not put a SSCCE together since the code is really trivial. But if it helps please say so.

I rather give an examples using an images displaying the behavior:

Example of JLabel, rendering plain text and HTML

I put a JPanel as the container around the JLabel to visualize the label's bounds. After setting the font and text for the JLabel, the

jLabel.getPreferredSize()

method returns the bounds of the rendered plain text or HTML (and this is the exact size I set for the surrounding JPanel). You can clearly see, that, if rendering HTML, the whole text is shifted a small amount down.

I would like to know why this happens and what I can do to correct the placement.

One workaround would be to translate the Graphics2D on which to render the text, to compensate the vertical shift, like this:

g2d.translate( 0, -20 );

But I don't know the correct y value in relation to the font metrics (e.g. font size). Anyway, this workaround also feels "wrong".

I really appreciate your answers, thanks a lot!

like image 854
It's Leto Avatar asked Feb 19 '26 14:02

It's Leto


1 Answers

It seems that if we set the Font (family,size etc) for the HTML JLabel using setFont(..) the font is not rendered to the correct metrics of JLabel.

Here is an example I made to demonstrate (Both JLabels shown are using HTML):

enter image description here

A simple work around is to the the font size, family etc in HTML too.

As we can see the cyan HTML JLabel used setFont(..) (and was incorrectly rendered) while the green HTML JLabel used HTML to set the font and was rendered correctly:

JLabel labelHtml2 = new JLabel("<html><font size=10 family='Calibri'>" + text + "</font></html>");

Test.java:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static Font font = new Font("Calibri", Font.PLAIN, 38);

    public Test() {
        initComponents();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();

                }
                new Test();
            }
        });
    }

    private void initComponents() {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        String text = "Hello world";

        //this label will not render correctly due to setting font via setFont(..)
        JLabel labelHtml1 = new JLabel("<html>" + text + "</html>");
        labelHtml1.setBackground(Color.CYAN);
        labelHtml1.setOpaque(true);//so background will be painted
        labelHtml1.setFont(font);

        //this label will render correcty font is set via html
        JLabel labelHtml2 = new JLabel("<html><font size=10 family='Calibri'>" + text + "</font></html>");
        labelHtml2.setBackground(Color.GREEN);
        labelHtml2.setOpaque(true);
        //labelHtml2.setFont(font);

        frame.add(labelHtml1, BorderLayout.NORTH);
        frame.add(labelHtml2, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);

    }
}
like image 147
David Kroukamp Avatar answered Feb 22 '26 02:02

David Kroukamp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!