如何获取JButton/JLabel文本屏幕坐标及实现字体同款下划线
解决方案:自定义字体匹配下划线实现与文本坐标获取
一、精准获取JButton/JLabel中文本坐标
无需硬编码,借助Swing的*FontMetrics*和组件绘画上下文即可计算文本的绘制位置:
- 重写组件的
paintComponent(JLabel)或paint(JButton)方法,在绘画流程中获取文本边界:@Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); FontMetrics fm = g2d.getFontMetrics(); String text = getText(); if (text == null || text.isEmpty()) { return; } // 计算文本在组件内的起始坐标(适配组件对齐方式) int textWidth = SwingUtilities.computeStringWidth(fm, text); int offsetX = (getWidth() - textWidth) / 2; int offsetY = (getHeight() - fm.getHeight()) / 2 + fm.getAscent(); // offsetX为文本基线的水平起始点,offsetY为文本基线的垂直位置 // 若需获取文本整体边界: Rectangle2D textBounds = fm.getStringBounds(text, g2d); double textStartX = offsetX; double textStartY = offsetY - fm.getAscent(); g2d.dispose(); } - 说明:
*FontMetrics*提供了字体的基线、 ascent(基线到文本顶部距离)、descent(基线到文本底部距离)等核心参数,结合组件尺寸可精准定位文本,完全避免硬编码。
二、实现匹配自定义字体的下划线
方案1:使用字体自带下划线字符(推荐)
如果自定义字体包含匹配风格的下划线字符(如你示例中的样式),可直接绘制该字符模拟下划线:
@Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); String originalText = getText(); String customUnderlineChar = "̲"; // 替换为你的字体自带下划线字符 FontMetrics fm = g2d.getFontMetrics(); int offsetX = (getWidth() - fm.stringWidth(originalText)) / 2; int offsetY = (getHeight() - fm.getHeight()) / 2 + fm.getAscent(); // 绘制原文本 g2d.drawString(originalText, offsetX, offsetY); // 绘制字体自带下划线,对齐原文本位置 int underlineY = offsetY + fm.getDescent() / 2; // 可根据字体微调垂直偏移 g2d.drawString(customUnderlineChar.repeat(originalText.length()), offsetX, underlineY); g2d.dispose(); }
方案2:自定义绘制下划线路径
若字体无自带下划线字符,直接用*Graphics2D*绘制匹配风格的线条:
@Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); String text = getText(); FontMetrics fm = g2d.getFontMetrics(); Rectangle2D textBounds = fm.getStringBounds(text, g2d); int x = (int) ((getWidth() - textBounds.getWidth()) / 2); int y = (int) ((getHeight() - textBounds.getHeight()) / 2 + fm.getAscent()); // 绘制原文本 g2d.drawString(text, x, y); // 绘制自定义下划线(示例为粗线,可调整粗细、形状匹配字体) int underlineY = y + fm.getDescent() / 3; int underlineHeight = 3; g2d.setColor(getForeground()); g2d.fillRect(x, underlineY, (int) textBounds.getWidth(), underlineHeight); g2d.dispose(); }
方案3:全局扩展UI组件
若需多个组件统一使用该样式,可自定义UI类替换默认实现:
public class CustomUnderlineLabelUI extends BasicLabelUI { @Override protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) { super.paintEnabledText(l, g, s, textX, textY); Graphics2D g2d = (Graphics2D) g.create(); FontMetrics fm = g2d.getFontMetrics(); int underlineY = textY + fm.getDescent() / 2; int underlineHeight = 2; g2d.fillRect(textX, underlineY, fm.stringWidth(s), underlineHeight); g2d.dispose(); } } // 使用方式: yourLabel.setUI(new CustomUnderlineLabelUI());
内容的提问来源于stack exchange,提问作者Advaitya Jadhav
相关产品推荐
相关产品推荐

