How to remove gap in java swing label of large size

JDigit may give you some ideas:

  • It override’s paintComponent() to down-sample a high-resolution BufferedImage and control the geometry.

  • It uses setBorderPainted(false) to set the borderPainted property.

  • It uses a FocusHandler for custom highlighting.

image

Addendum: As noted here, the underlying problem is the font’s leading, defined in FontMetrics as being included in the font’s height. As suggested in a comment by @Guillaume Polet, you can render the text wherever you want in your own JComponent. TextLayout, discussed here, can be used to calculate the bounds, as shown below.

Pros:

  • Absolute control over placement.

  • Geometry of TexteLayout bounds based on FontMetrics.

Cons:

  • No Icon support.

  • No HTML support.

Note that the JComponent authors “recommend that you put the component in a JPanel and set the border on the JPanel.”

Unleaded image

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @see https://stackoverflow.com/a/16014525/230513
 */
public class UnleadedTest {

    private static class Unleaded extends JComponent {

        private Font font = new Font("Verdana", Font.PLAIN, 144);
        private FontRenderContext frc = new FontRenderContext(null, true, true);
        private String text;
        private TextLayout layout;
        private Rectangle r;

        public Unleaded(String text) {
            this.text = text;
            calcBounds();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(r.width, r.height);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            calcBounds();
            layout.draw(g2d, -r.x, -r.y);
        }

        private void calcBounds() {
            layout = new TextLayout(text, font, frc);
            r = layout.getPixelBounds(null, 0, 0);
        }
    }

    private void display() {
        JFrame f = new JFrame("Unleaded");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Unleaded label = new Unleaded("Unleaded");

        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createTitledBorder("Title"));
        panel.add(label);
        f.add(panel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new UnleadedTest().display();
            }
        });
    }
}

Leave a Comment