繁体   English   中英

如何将MouseListener添加到另一个图形对象内的图形对象?

[英]How do I add a MouseListener to a graphics object inside another graphics object?

我正在为纸牌游戏设计GUI,并且为了熟悉起见,正在使用ACM的学生图形库 我编写了一个程序,将我的单人纸牌游戏绘制到屏幕上,但无法使其具有交互性。

背景:

这里有很多类,我将尽力描述每个类。

  • 包含应用程序的顶级JFrame。
    • GCanvas(包含所有图形对象)
      • SolitaireGameControl(GCompound容纳组成纸牌游戏的所有其他GCompounds)
        • 一组PictureViews,一堆纸牌(由一组纸牌组成的GCompound)
          • 卡(由矩形和标签组成的GCompound)

GCompound:被视为一个对象的图形对象的集合。(如果car是GCompound,它将具有GOval[] wheels, GRect body ,因此当我将其添加到画布中时,它将显示为一个对象))

从顶级类中看到的卡片看起来像这样: jFrame.gCanvas.solitaireGameControl.pileViews[pile number].cardView

我一直想做的是向每张卡中添加一个MouseListener,以便在单击卡并触发MouseEvent时,MouseEvent e.getSource() =被单击的卡。

现在是这样的:

public SolitaireGameControl(SolitaireGame game) {
    this.game = game; // Model of the game.
    this.pileViews = PileView.getPileViews(game.drawPiles); // ArrayList of PileViews (the pile of cards)

    for(PileView pv : pileViews) {
        for(CardView cv : pv.cardViews) {
            cv.addMouseListener(this); // add a mouseListener to the card
        }
    }

    this.addMouseListener(this); // if I don't include this, nothing happens when I click anything. If I do include this, this whole object is the source.
}

@Override
public void mouseClicked(MouseEvent e) {
    System.out.println(e.getSource()); // should return the card I clicked.
}

问题图片

当我运行该程序时,每个事件的源头都是SolitaireGameControl, this.addMouseListener(this);是我留在this.addMouseListener(this); 如果我删除该语句,则什么都不会打印,这使我相信我添加的mouseListeners只能深入一层。 (画布上的第一个GCompound,而不是其中的GCompounds。)

因此,我的问题如下:是否有办法在GCompound 内的 GCompound 获取GCompound的MouseListener,并使MouseEvent的getSource正确识别卡? 如果没有,是否可以重组程序以使其按预期工作? (我知道我确实应该为初学者使用更好的图形库。)

那是有道理的。 根据我的经验,如果我将某些组件放在顶层容器中,则该容器就是接收输入事件的容器。

您是否尝试过执行以下操作的方法:

/* This is the mouse listener for the top-level container. */
@Override
public void mouseClicked(MouseEvent e) {
    for(PileView pv : pileViews) {
        for(CardView cv : pv.cardViews) {
            if(cv.getBounds().contains(e.getPoint())) {
                cv.dispatchEvent(e);
            }
        }
    }
}

...然后正常处理“ CardView”级别的鼠标单击。

当顶级容器收到鼠标事件时,它将根据事件的位置(如果卡的区域包含该点)检查鼠标是否与卡进行了交互。 如果是这样,它将鼠标事件传递给卡的鼠标侦听器。

我假设“ pv.cardViews”开头附近的元素是最靠前的卡片。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM