Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JLabel vertical alignment not working as expected

Font font = Font("Arial", Font.BOLD, 35);

JLabel label = new JLabel("57");
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
panel.add(label);

This creates a JLabel with an extra space above and below it. I tried setVerticalAlignment(SwingConstants.TOP) but it not working. Again, I don't want to align JLabel to top but the text inside JLabel should be aligned to top.

here is how my label looks like enter image description here

like image 414
arpanoid Avatar asked Aug 18 '11 22:08

arpanoid


People also ask

How do you change the alignment of a label in Java?

A JLabel object can display either text, an image, or both. You can specify where in the label's display area the label's contents are aligned by setting the vertical and horizontal alignment. By default, labels are vertically centered in their display area.

How are text only labels aligned by default in the display area?

By default, labels are vertically centered in their display area. Text-only labels are leading edge aligned, by default; image-only labels are horizontally centered, by default.

Whats a JLabel?

JLabel is a class of java Swing . JLabel is used to display a short string or an image icon. JLabel can display text, image or both . JLabel is only a display of text or image and it cannot get focus . JLabel is inactive to input events such a mouse focus or keyboard focus.


2 Answers

The text in your label is actually aligned to the top already. Even if you set all three of:

label.setVerticalAlignment(JLabel.TOP);
label.setVerticalTextPosition(JLabel.TOP);
panel.setAlignmentY(TOP_ALIGNMENT);

you still would find that gap.

The problem is related to font-metrics. The font leaves space for diacritics, and while English numbers and even letters do not contain diacritics on capital letters, Arial definitely contains a full-breadth of international characters including ones taller than a capital letter, for example, German umlauts (ÄÖÜ) or characters containing Portuguese diacritics (ÁÂÃ).

If you want a quick, easy solution that is a hack, that may not scale well across fonts and platforms, you can use a negative value on a border to compensate for the font metrics.

label.setBorder(BorderFactory.createEmptyBorder( -3 /*top*/, 0, 0, 0 ));

If you want to fix it "right" you should look into learning about the FontMetrics package, as it has many functions that could be useful to calculating the actual height and location of the text being displayed, such that you can move the whole string by the appropriate amount of pixels.

like image 55
Jessica Brown Avatar answered Oct 13 '22 11:10

Jessica Brown


The arrow in your diagram points to the difference between the glyph's nominal ascent and the maximum ascent, as discussed in FontMetrics. You can tinker with setBorder(null); but for absolute control, you'll have to render the glyphs yourself, as shown here. Fortunately, the digit glyphs of most fonts have a uniform advance and ascent.

like image 36
trashgod Avatar answered Oct 13 '22 11:10

trashgod