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

Java使用drawString垂直绘制文本时出现前置间隙的问题排查与修复

Java使用drawString垂直绘制文本时出现前置间隙的问题排查与修复

嘿,我来帮你搞定这个垂直文本绘制的间隙问题~ 你遇到的奇怪间隙,本质是旋转后坐标系变化导致文本绘制的基准坐标计算错误,还有对drawString的绘制基准点理解不到位,咱们一步步来解决:

问题根源分析

  1. 坐标系旋转后的坐标映射错误:当你围绕矩形中心旋转文本时,原来的水平坐标系会跟着旋转,此时你用原坐标系的r.x(矩形左边界)作为旋转后文本的x坐标,已经不再是你期望的“矩形垂直边缘”位置了。
  2. drawString的绘制基准点误解:drawString默认是基于文本的**基线(baseline)**来绘制的,旋转后基线的方向也跟着改变了,直接用y0(矩形中心y坐标)会导致文本偏移。
  3. 文本尺寸的方向混淆:旋转90度后,原来的文本宽度(textWidth)会变成垂直方向的高度,原来的高度(textHeight)会变成水平方向的宽度,你没有对应调整这个尺寸关系。

修复方案与代码调整

我们重新调整drawLabel方法里的坐标计算逻辑,确保旋转后的文本起始端刚好贴合矩形的垂直边缘:

private void drawLabel(Graphics g, String text, double rotation, Rectangle r) {
    final int AXIS_OFFSET = 20;
    final int TOP_BUFFER = 30; // where additional text is drawn

    Graphics2D g2d = (Graphics2D)g.create();
    g2d.setFont(font);
    FontMetrics fontMetrics = g2d.getFontMetrics();
    int textHeight = fontMetrics.getHeight();
    int textWidth = fontMetrics.stringWidth(text);

    int rectCenterX = r.x + r.width / 2;
    int rectCenterY = r.y + r.height / 2;

    // 绘制辅助线和矩形(保留你的调试代码)
    g2d.drawLine(rectCenterX, getBounds().y, rectCenterX, getBounds().y + getBounds().height);
    g2d.drawLine(getBounds().x, rectCenterY, getBounds().x + getBounds().width, rectCenterY);
    g2d.drawRect(r.x, r.y, r.width, r.height);

    // 先旋转坐标系
    g2d.rotate(rotation, rectCenterX, rectCenterY);

    // 根据旋转方向计算文本的绘制坐标,让文本起始端贴合矩形垂直边缘
    int drawX, drawY;
    if (rotation == -Math.PI / 2) {
        // 顺时针旋转90度:文本向下排列,起始端对齐矩形左垂直边缘
        // 旋转后,原矩形的左边缘x坐标对应旋转后的y方向位置,调整基线对齐
        drawX = r.x;
        drawY = rectCenterY + textWidth / 2 - fontMetrics.getDescent();
    } else if (rotation == Math.PI / 2) {
        // 逆时针旋转90度:文本向上排列,起始端对齐矩形左垂直边缘
        drawX = r.x;
        drawY = rectCenterY - textWidth / 2 + fontMetrics.getAscent();
    } else {
        // 其他旋转角度的默认处理(这里只针对垂直旋转)
        drawX = rectCenterX - textWidth / 2;
        drawY = rectCenterY + fontMetrics.getDescent();
    }

    // 只保留正确的一次绘制
    g2d.drawString(text, drawX, drawY);
    g2d.dispose();
}

关键调整点说明

  • 旋转后坐标的重新映射:针对顺时针/逆时针两种垂直旋转方向,分别计算文本的y坐标(因为旋转后y轴方向改变了),利用textWidth(原水平宽度,旋转后变成垂直方向的长度)来居中对齐,同时通过fontMetrics的ascent和descent调整基线位置,消除间隙。
  • 移除多余的绘制代码:你原来的代码里调用了两次drawString,这会导致文本重叠,只保留计算好的一次绘制即可。
  • 明确矩形中心变量名:把x0/y0改成更清晰的rectCenterX/rectCenterY,避免混淆。

调整后,你会看到文本的起始端刚好贴合矩形的垂直边缘,不会再有奇怪的间隙了。如果需要调整文本在矩形内的上下位置,可以微调drawY的计算逻辑,比如增减偏移量。

备注:内容来源于stack exchange,提问作者Alex B.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 09:44:27