我有一个带有图像的框架,我希望每次有人单击图像中的不同对象时,它都会充当按钮并执行某些操作。
问题是,这些对象不是简单的形状,所以我正在考虑以这些对象的形状绘制我自己的隐形按钮。
那可能吗?或者有什么更好的方法来完成这样的事情?
-谢谢你
我有一个带有图像的框架,我希望每次有人单击图像中的不同对象时,它都会充当按钮并执行某些操作。
问题是,这些对象不是简单的形状,所以我正在考虑以这些对象的形状绘制我自己的隐形按钮。
那可能吗?或者有什么更好的方法来完成这样的事情?
-谢谢你
概念:带有圆形和多边形调度区域的隐形按钮
首先,您需要一个定义一个不可见按钮的类,并对其进行扩展,javax.swing.AbstractButton
以便它仍然是一个可以添加侦听器的功能齐全的按钮。
public abstract class InvisibleButton extends AbstractButton {
public abstract boolean contains(Point point);
@Override
public boolean isVisible() {
return false;
}
}
然后,当然,您将需要该类的实现。这里有两个例子:一个使用多边形来表示复杂的形状,一个使用圆形。
public class PolygonalButton extends InvisibleButton {
private Polygon area = null;
public PolygonalButton(Polygon area) {
this.area = area;
}
@Override
public boolean contains(Point point) {
return area.contains(point);
}
}
public class CircularButton extends InvisibleButton {
private int x;
private int y;
private double radius;
public CircularButton(int x, int y, double radius) {
this.x = x;
this.y = y;
this.radius = radius;
}
@Override
public boolean contains(Point point) {
double dx = x - point.x;
double dy = y - point.y;
return Math.sqrt(dx * dx + dy * dy) <= radius;
}
}
最后,您需要实现一个处理所有这些按钮的容器,但您应该使用面板而不是框架。您可以简单地覆盖框架的事件处理器并将它们传递给必要的按钮,而不是挂钩每个单独的侦听器。
public class InvisibleButtonImagePanel extends JPanel {
private BufferedImage image = null;
private List<InvisibleButton> buttons = new ArrayList<>();
public InvisibleButtonImagePanel(BufferedImage image) {
this.image = image;
}
public void add(InvisibleButton button) {
buttons.add(button);
}
public void remove(InvisibleButton button) {
buttons.remove(button);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(), image.getHeight());
}
@Override
public void processKeyEvent(KeyEvent event) {
for (InvisibleButton button : buttons) {
if (button.isFocusOwner()) {
button.dispatchEvent(event);
}
}
super.processKeyEvent(event);
}
@Override
public void processMouseEvent(MouseEvent event) {
for (InvisibleButton button : buttons) {
if (button.contains(event.getPoint())) {
button.dispatchEvent(event);
}
}
super.processMouseEvent(event);
}
@Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
super.paintComponent(g);
}
}
您可能希望将面板重命名为不那么笨重的名称,并可能实现您自己的高级图像代码,但这是其背后的基本思想。
您可以通过坐标跟踪用户的鼠标位置吗?
PointerInfo a = MouseInfo.getPointerInfo();
Point b = a.getLocation();
int x = (int)b.getX();
int y = (int)b.getY();
现在放置一个 ActionPerformed 方法并测试 x 和 y = 例如 200、300是否执行此操作。这样当用户点击一个点(你的目标区域)时,它会将他重定向到一个方法。
为区域定义一个接口,例如:
//represents any clickable area.
public interface IButton{
boolean contains(int x, int y);
}
然后,如果您希望圆形区域可单击,请定义一个类来检查 ax,y 坐标是否在某个位置的某个距离内。
public class CircleButton implements IButton{
Point center;
double radius;
public CircleButton(int x, int y, double radius){
this.center = new Point(x,y);
this.radius = radius;
}
//check if x,y coords are within a radius
//from the center of this circle button
public boolean contains(int x, int y){
double dx = x-center.x;
double dy = y-center.y;
return (Math.sqrt(dx*dx+dy*dy) <= radius);
}
}
创建一个 IButton 列表。您将遍历这些以查看用户是否单击了您的一个不可见按钮。
List<IButton> buttons = new List<IButton>();
buttons.add(new CircleButton(100,100,200);
然后,每次有人单击您的框架时,都会使用该鼠标单击的位置迭代您的不可见按钮。
public void mouseReleased(MouseEvent e){
for(IButton b : buttons){
if(b.contains(evt.getX(),e.getY()){
//do something depending on what button was clicked.
}
}
}
您可以轻松地看到如何定义像这样的不可见矩形按钮,甚至是不规则的多边形形状。您只需要contains
正确实现该方法。
而且我希望每次有人单击图像中的不同对象时,它都会充当按钮并执行某些操作。
您可以创建Shape
对象的 ArrayList。然后将 MouseListener 添加到包含图像的组件中。每当生成 mousePressed 事件时,您循环遍历 ArrayList 并使用组件的 containsts(...) 方法来确定用户是否单击 Shapes 坐标。
查看玩转形状。该代码不会帮助您解决当前的问题,但它会让您了解Shapes
您可以定义的类型。