Java 15 向Canvas添加自定义文本时出现缩放/位置偏移问题求助
问题原因
这个问题是Java 9及以上版本AWT渲染逻辑严格化导致的,你的代码存在两处核心错误:
- 直接调用
Graphics2D.setTransform()方法替换全局变换矩阵:传入的旋转变换矩阵完全覆盖了t2D原本携带的画布全局缩放、平移参数,相当于丢弃了原有缩放设置。 - 绘制完成后重置变换时,你自行构造了旋转角度为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
相关产品推荐
相关产品推荐

