The "right way" for this is to extend "BasicLabelUI" and override the "protected String layoutCL ()" method. This is the method that is responsible for laying out everything inside the label and is called when the "getPreferredSize ()" JLabel is called. Thus, this method determines the height of the component.
If you drill deep enough, you will see that the height is determined by the following line in the SwingUtilities class: 1021 (which is used by layoutCL):
textR.height = fm.getHeight();
Thus, the shortcut does not cause a space font. The label simply matches what the FontMetrics object says - this is the maximum font height for that size.
The easiest way is to cheat; Force the size calculation to do something that it shouldn't. Below is an example with a custom LabelUI component on which you can experiment. For example, if you force the variable "dy" to "-40", the text will be at the top. If you want to make something more durable, you can check all the letters in the label string, measure their maximum height and use it in the layoutCL method. But this is more obvious.
package Core; import sun.swing.SwingUtilities2; import javax.swing.*; import javax.swing.plaf.LabelUI; import javax.swing.plaf.basic.BasicLabelUI; import javax.swing.text.View; import java.awt.*; public class LabelDemo extends JPanel { public LabelDemo() { super(new GridBagLayout()); JLabel label2; GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 0; // Create the other labels. label2 = new JLabel("Text-Only Label"); label2.setVerticalAlignment(SwingUtilities.TOP); label2.setVerticalTextPosition(SwingUtilities.TOP); label2.setUI(SkinnyLabelUI.createUI(label2)); label2.setBorder(BorderFactory.createTitledBorder("aaaaaaaa")); label2.setFont(new Font("Verdana", Font.PLAIN, (int) 220)); // label2.setBorder(new EmptyBorder(-50, 0, 0, 0)); // Add the labels. add(label2, c); } /** * Create the GUI and show it. For thread safety, this method should be * invoked from the event dispatch thread. */ private static void createAndShowGUI() { // Create and set up the window. JFrame frame = new JFrame("LabelDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Add content to the window. frame.add(new LabelDemo()); // Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { // Schedule a job for the event dispatch thread: // creating and showing this application GUI. SwingUtilities.invokeLater(new Runnable() { public void run() { // Turn off metal use of bold fonts UIManager.put("swing.boldMetal", Boolean.FALSE); createAndShowGUI(); } }); } private static class SkinnyLabelUI extends BasicLabelUI { private static final SkinnyLabelUI labelUI = new SkinnyLabelUI(); public static LabelUI createUI(JComponent c) { return labelUI; } protected String layoutCL( JLabel label, FontMetrics fm, String text, Icon icon, Rectangle viewR, Rectangle iconR, Rectangle textR) { int verticalAlignment = label.getVerticalAlignment(); int horizontalAlignment = label.getHorizontalAlignment(); int verticalTextPosition = label.getVerticalTextPosition(); int horizontalTextPosition = label.getHorizontalTextPosition(); if (icon != null) { iconR.width = icon.getIconWidth(); iconR.height = icon.getIconHeight(); } else { iconR.width = iconR.height = 0; } /* Initialize the text bounds rectangle textR. If a null * or and empty String was specified we substitute "" here * and use 0,0,0,0 for textR. */ boolean textIsEmpty = (text == null) || text.equals(""); int lsb = 0; int rsb = 0; /* Unless both text and icon are non-null, we effectively ignore * the value of textIconGap. */ int gap; View v; if (textIsEmpty) { textR.width = textR.height = 0; text = ""; gap = 0; } else { int availTextWidth; gap = (icon == null) ? 0 : label.getIconTextGap(); if (horizontalTextPosition == SwingUtilities.CENTER) { availTextWidth = viewR.width; } else { availTextWidth = viewR.width - (iconR.width + gap); } v = (label != null) ? (View) label.getClientProperty("html") : null; if (v != null) { textR.width = Math.min(availTextWidth, (int) v.getPreferredSpan(View.X_AXIS)); textR.height = (int) v.getPreferredSpan(View.Y_AXIS); } else { textR.width = SwingUtilities2.stringWidth(label, fm, text); lsb = SwingUtilities2.getLeftSideBearing(label, fm, text); if (lsb < 0) { // If lsb is negative, add it to the width and later // adjust the x location. This gives more space than is // actually needed. // This is done like this for two reasons: // 1. If we set the width to the actual bounds all // callers would have to account for negative lsb // (pref size calculations ONLY look at width of // textR) // 2. You can do a drawString at the returned location // and the text won't be clipped. textR.width -= lsb; } if (textR.width > availTextWidth) { text = SwingUtilities2.clipString(label, fm, text, availTextWidth); textR.width = SwingUtilities2.stringWidth(label, fm, text); } textR.height = fm.getHeight(); System.out.println("font height: " + textR.height); } } /* Compute textR.x,y given the verticalTextPosition and * horizontalTextPosition properties */ if (verticalTextPosition == SwingUtilities.TOP) { if (horizontalTextPosition != SwingUtilities.CENTER) { textR.y = 0; } else { textR.y = -(textR.height + gap); } } else if (verticalTextPosition == SwingUtilities.CENTER) { textR.y = (iconR.height / 2) - (textR.height / 2); } else { // (verticalTextPosition == BOTTOM) if (horizontalTextPosition != SwingUtilities.CENTER) { textR.y = iconR.height - textR.height; } else { textR.y = (iconR.height + gap); } } if (horizontalTextPosition == SwingUtilities.LEFT) { textR.x = -(textR.width + gap); } else if (horizontalTextPosition == SwingUtilities.CENTER) { textR.x = (iconR.width / 2) - (textR.width / 2); } else { // (horizontalTextPosition == RIGHT) textR.x = (iconR.width + gap); } // WARNING: DefaultTreeCellEditor uses a shortened version of // this algorithm to position it Icon. If you change how this // is calculated, be sure and update DefaultTreeCellEditor too. /* labelR is the rectangle that contains iconR and textR. * Move it to its proper position given the labelAlignment * properties. * * To avoid actually allocating a Rectangle, Rectangle.union * has been inlined below. */ int labelR_x = Math.min(iconR.x, textR.x); int labelR_width = Math.max(iconR.x + iconR.width, textR.x + textR.width) - labelR_x; int labelR_y = Math.min(iconR.y, textR.y); int labelR_height = Math.max(iconR.y + iconR.height, textR.y + textR.height) - labelR_y; int dx, dy; if (verticalAlignment == SwingUtilities.TOP) { dy = viewR.y - labelR_y; } else if (verticalAlignment == SwingUtilities.CENTER) { dy = (viewR.y + (viewR.height / 2)) - (labelR_y + (labelR_height / 2)); } else { // (verticalAlignment == BOTTOM) dy = (viewR.y + viewR.height) - (labelR_y + labelR_height); } if (horizontalAlignment == SwingUtilities.LEFT) { dx = viewR.x - labelR_x; } else if (horizontalAlignment == SwingUtilities.RIGHT) { dx = (viewR.x + viewR.width) - (labelR_x + labelR_width); } else { // (horizontalAlignment == CENTER) dx = (viewR.x + (viewR.width / 2)) - (labelR_x + (labelR_width / 2)); } /* Translate textR and glypyR by dx,dy. */ textR.x += dx; textR.y += dy; iconR.x += dx; iconR.y += dy; if (lsb < 0) { // lsb is negative. Shift the x location so that the text is // visually drawn at the right location. textR.x -= lsb; textR.width += lsb; } if (rsb > 0) { textR.width -= rsb; } return text; } } }