我正在开发一个用于纸牌游戏的GUI,并且为了熟悉而使用ACM's student graphics library。我写了一个程序,将我的单人纸牌游戏吸引到屏幕上,并且无法使其成为互动游戏。
背景
这里有很多课程,我会尽力对它们进行描述。
( GCompound:一个被视为一个对象的图形对象集合。(如果car
是一个GCompound,它会有GOval[] wheels, GRect body
,所以当我将它添加到canvas,它显示为一个对象))
从顶级课程中看到的卡片看起来有点像这样: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);
。如果我拿出这个声明,根本没有打印任何内容,这让我相信我添加的mouseListeners只能在一个深度上工作。 (画布上的第一个GCompound,而不是其中的GCompound。)
因此,我的问题如下:是否有办法在 GCompound中的 GCompound 内部获取GCompound 的MouseListener,并将MouseEvent的getSource设置为正确识别卡?如果没有,有没有办法重组我的程序,使其按预期工作? (我知道我应该为初学者使用更好的图形库。)
答案 0 :(得分:1)
这是有道理的。根据我的经验,如果我将一些组件放在顶级容器中,那么容器就是接收输入事件的容器。
您是否尝试过以下方法:
/* 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'开头附近的元素是前面的卡片。