0

我只使用图像,我用来查看我的应用程序的窗口的尺寸在不同的系统上可能不同。我有一个鼠标动作监听器,它正在监听我的程序主视图上的点击。我有一个看起来像按钮的圆角矩形。我想让鼠标动作监听器只监听圆角矩形的区域,而不是所有系统上的整个图像。就像标题说的那样,不是整个图像都有内容,特别是角落看起来不像是图像的一部分,所以我不想让用户能够在没有内容的情况下点击图像的某些部分内容并获得与单击有内容的部分相同的结果。我的图像看起来与此类似(来源:youthedesigner.com图片

所以我只希望程序在用户点击图像内的按钮而不是按钮周围的好东西时做一些事情。这就是我现在要收听点击的内容:

@Override
public void mouseClicked(MouseEvent e) {
    for(int i = 0; i <= 200; i++) {
        if(e.getY() >= 100+i && e.getY() <= 300) {
            if(e.getX() >= 10+100-Math.pow(10000-(Math.pow((i-100),2.0)),.5)) && e.getX() <= 10+400-Math.pow(10000-(Math.pow((i-100),2.0)),.5))) {
                // do stuff
                i = 201;
            }
        }
    }
}

我在我的代码中使用的数学方程看起来像 110-(10000-(y-100)^2)^(1/2)),如果用图表表示,它看起来像一个左括号,而 410+(10000- (y-100)^2)^(1/2)),它看起来像一个距离第一张图 400 个单位的右括号。

该代码在我的系统上运行良好,但在其他系统上,它根本不起作用,我很好奇如何移动我正在收听的位置以对应于图像的缩放方式。

非常感谢您提供的任何帮助。

4

3 回答 3

1

for 循环是多余的。

您可以确保按钮 (.png) 外部的像素具有一定的透明度,然后检查 alpha 颜色分量。

在这种情况下,您可以添加一个 Rect 并查找:

private boolean insideButton(Rectangle buttonRect, Point mousePt) {
    if (buttonRect.contains(mousePt)) {
        int r = buttonRect.height() / 2;
        if (mousePt.x < r) {
            // Left circle with O at (r, r)
            int xFromO = r - mousePt.x;
            int yFromO = r - mousePt.y;
            if (xFromO * xFromO + yFromO * yFromO > r * r) {
                return false; // Outside circle
            }
        }
        if (mousePt.x > buttonRect.right - r) {
            // Right circle:
            ...
        }
        return true;
    }
    return false;
}
于 2012-11-22T08:48:31.233 回答
0

所以,我用乔普的答案来解决我的问题。他的回答不是我想要的,但它给了我解决问题所需的想法。我得出的解决方案是:

private boolean insideButton(Rectangle buttonRect, Point mousePt) {
    if (buttonRect.contains(mousePt)) {
        int r = (int)buttonRect.getHeight()/2; // radius of either of the circles that make up the sides of the rectangle
        if(mousePt.x <= buttonRect.getWidth()/2) { // if it is on the left of the button
            Point center = new Point((int)buttonRect.getX()+r, (int)buttonRect.getY()+r); // the center of the circle on the left
            double lengthToPoint = Math.pow(Math.pow(mousePt.x-center.x, 2)+Math.pow(mousePt.y-center.y, 2), 1.0/2); // length from center to the point that the user clicked at
            if(lengthToPoint > r && mousePt.x < center.x) { // if it is to the left of the center and out of the circle
                return false;
            } else {
                return true;
            }
        } else { // if it is on the right, the rest of the code is just about the same as the left circle
            Point center = new Point((int)buttonRect.getWidth()-r, (int)buttonRect.getY()+r);
            double lengthToPoint = Math.pow(Math.pow(mousePt.x-center.x, 2)+Math.pow(mousePt.y-center.y, 2), 1.0/2);
            if(lengthToPoint > r && mousePt.x > center.x) {
                return false;
            } else {
                return true;
            }
        }
    } else {
        return false;
    }
}

我知道它的计算有点过分而且效率低下,但我想以这种方式呈现它,以更好地了解我的解决方案是如何工作的。

于 2012-11-23T02:58:05.040 回答
0

我至少能想到两种方法。

第一个是生成蒙版图像(黑白),其中(例如)白色表示可点击区域。基本上,您可以根据原始图像的点击选取点来比较蒙版的像素颜色。

另一种方法是构建图像映射,基本上使用ShapeAPI 之类的东西来允许非矩形形状。这将允许用于Shape#contains确定鼠标是否在其中单击

无论哪种情况,您都需要考虑原始图像的 x/y 位置

于 2012-11-22T08:24:55.497 回答