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

Java 15 向Canvas添加自定义文本时出现缩放/位置偏移问题求助

问题原因

这个问题是Java 9及以上版本AWT渲染逻辑严格化导致的,你的代码存在两处核心错误:

  1. 直接调用Graphics2D.setTransform()方法替换全局变换矩阵:传入的旋转变换矩阵完全覆盖了t2D原本携带的画布全局缩放、平移参数,相当于丢弃了原有缩放设置。
  2. 绘制完成后重置变换时,你自行构造了旋转角度为0的单位矩阵,再次用setTransform()覆盖,彻底清空了画布原本的全局缩放配置,导致后续所有绘制元素的缩放失效,视觉上表现为缩放比例减半。
    Java 8的AWT渲染逻辑存在隐式的变换参数容错,因此问题不会暴露,升级到Java 15后容错逻辑被移除,问题就显现出来了。

修复代码

修改核心逻辑为先保存原有变换、叠加旋转变换绘制、完成后恢复原有变换,不要自行构造变换矩阵覆盖全局配置:

//TEXT  
public void paintText(Graphics2D t2D, Color color,Text t, Font font, double bearing, Rectangle2D bounds, double scale, boolean selected, boolean isRotationTool, double enhance) {

    //Draws text where ever the user clicks
    FontMetrics fm = t2D.getFontMetrics();

    t2D.setFont(default_FONT);
    
    int x = (int) ((t.getX() - bounds.getX())*(scale));
    int y = (int) ((bounds.getHeight() + bounds.getY() - t.getY()) *(scale));

    // 保存原有全局变换,不要自己构造变换覆盖
    AffineTransform originalAt = t2D.getTransform();
    try {
        // 叠加旋转变换
        AffineTransform rotationAt = new AffineTransform();
        rotationAt.setToRotation(Math.toRadians(bearing+270), x,y);
        t2D.transform(rotationAt);
        
        FontRenderContext frc = t2D.getFontRenderContext();
        TextLayout layout = new TextLayout(t.getText(), t2D.getFont(), frc);
        
        if (!selected) {
            t2D.setColor(color);
        } else {
            //pixel size of the circle
            float size = 20;//(float) (fm.stringWidth(t.getText())*0.5);
            t2D.setColor(p_selectedObjectsColour);
            t2D.setStroke(LINE_100);
            
            //Highlight and origin indicator when selected - START
            t2D.setColor(p_selectedObjectsColour);
            t2D.draw(new Ellipse2D.Double((((t.getX() - bounds.getX())*scale) - size), (((bounds.getHeight() + bounds.getY() - t.getY())*scale) - size), (size*2), (size*2))); 
            
            if(isRotationTool){
                t2D.drawString("  : ⟳ "+dec1P.format(bearing)+"°",(float) (x + (fm.stringWidth(t.getText())*1.05)),y);
            }
            
            t2D.setColor(p_selectedObjectsColour);
            
            t2D.draw(new Rectangle2D.Double(
                    (t.getX() - bounds.getX())* scale,
                    ((bounds.getHeight() + bounds.getY() - t.getY())*scale)-fm.getStringBounds(t.toString(), t2D).getHeight(),
                    t.getBounds().getWidth(),
                    t.getBounds().getHeight()
                    ));
            t2D.drawLine((int) (((t.getX() - bounds.getX())) * scale),
                    (int)(((bounds.getHeight() + bounds.getY())-(t.getY()))*scale), 
                    (int)(((t.getX())- bounds.getX())*scale)+fm.stringWidth(t.getText()),
                    (int)(((bounds.getHeight() + bounds.getY())-(t.getY()))*scale));
        }
        t2D.setColor(color);
        layout.draw(t2D, x, y);
    } finally {
        // 直接恢复原来的全局变换,不要自己构造单位矩阵
        t2D.setTransform(originalAt);
    }
}

额外优化建议

你当前选中状态下的椭圆、矩形、直线绘制逻辑是在旋转变换叠加后执行的,坐标计算没有适配旋转,会导致高亮元素位置偏移,建议把这部分高亮绘制逻辑移到叠加旋转变换之前执行,避免坐标错乱。


内容的提问来源于stack exchange,提问作者BChin B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 20:18:03