You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:20:28