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

Graphics2D.hit方法返回不符合预期的布尔值,求解决方案

解决Graphics2D hit方法返回false的问题

你的问题根源在于存储的storedG2d对象在paintComponent方法执行完毕后已经失效,用它进行命中测试会导致坐标变换逻辑异常,从而返回错误结果。另外,对于简单矩形的命中测试,根本不需要用到Graphics2D.hit()方法,直接判断点是否在矩形范围内即可。

解决方案1:直接判断点是否在矩形内

对于简单的矩形,直接使用Rectangle.contains(Point)方法就能准确判断鼠标点击是否在矩形区域内,这是最简洁高效的方式。

修改SelectListener的mousePressed方法:

class SelectListener extends MouseInputAdapter {
    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println(e.getPoint());
        System.out.println(HitTest.canvas.rectangle);
        // 直接判断点是否在矩形内
        System.out.println(HitTest.canvas.rectangle.contains(e.getPoint()));
    }
}

解决方案2:正确使用Graphics2D进行命中测试(针对复杂场景)

如果后续需要处理带有变换(比如缩放、旋转)的复杂图形,不能存储paintComponent中的Graphics2D对象,而是要在命中测试时创建临时的Graphics2D,并应用和绘制时相同的变换逻辑,再调用hit方法。

修改后的核心代码示例:

class CanvasArea extends JPanel {
    Rectangle rectangle = new Rectangle();
    MouseInputAdapter mode;
    // 移除失效的storedG2d变量

    CanvasArea() {
        setBackground(Color.WHITE);
        setPreferredSize(new Dimension(1000, 600));
    }

    // 其他原有方法保持不变...

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        // 若有自定义变换,可在此记录变换矩阵
        // AffineTransform drawTransform = g2d.getTransform();
        g2d.draw(rectangle);
    }
}

class SelectListener extends MouseInputAdapter {
    @Override
    public void mousePressed(MouseEvent e) {
        System.out.println(e.getPoint());
        System.out.println(HitTest.canvas.rectangle);
        
        // 创建临时Graphics2D进行测试
        Graphics2D tempG2d = (Graphics2D) HitTest.canvas.getGraphics();
        try {
            Rectangle mouseRect = new Rectangle(e.getPoint(), new Dimension(1, 1));
            // 若绘制时有自定义变换,需先将相同变换应用到临时Graphics2D
            // tempG2d.setTransform(drawTransform);
            System.out.println(tempG2d.hit(mouseRect, HitTest.canvas.rectangle, false));
        } finally {
            tempG2d.dispose(); // 用完必须释放资源
        }
    }
}

关键原因解释

  1. paintComponent中的Graphics对象由Swing框架管理,方法执行完毕后框架会回收或重置其状态,存储并后续使用会导致不可预期的坐标变换或上下文错误。
  2. Graphics2D.hit()方法的第一个参数是设备空间的区域,第二个是用户空间的形状,当使用失效的Graphics2D时,它的变换矩阵可能已被修改,导致形状被错误转换,最终命中测试失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 10:03:16