I'm working on a GUI for a card game and am using the ACM's student graphics library for the sake of familiarity. I have written a program that draws my solitaire game to the screen, and am having trouble making it interactive.
Background:
There are a lot of classes here, and I'll do my best to describe them each.
- Top level JFrame containing the application.
- GCanvas (that holds all the graphics objects)
- SolitaireGameControl (GCompound holding all the other GCompounds making up the solitaire game)
- Array of PileViews, a pile of cards (GCompound consisting of an array of Cards)
- Cards (GCompound consisting of rectangles and labels)
- Array of PileViews, a pile of cards (GCompound consisting of an array of Cards)
- SolitaireGameControl (GCompound holding all the other GCompounds making up the solitaire game)
- GCanvas (that holds all the graphics objects)
(GCompound: a collection of graphics objects treated as one object. (If car
was a GCompound, it would have GOval[] wheels, GRect body
and so when I add it to the canvas, it displays as one object))
A card as seen from the top-level class would look like a bit like this: jFrame.gCanvas.solitaireGameControl.pileViews[pile number].cardView
What I've been trying to do is add a MouseListener to every single card, so that when a card is clicked and a MouseEvent is fired, MouseEvent e.getSource()
= the card that was clicked.
Here's how it looks now:
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.
}
When I run this program, the source of every event is SolitaireGameControl, granted I leave in the this.addMouseListener(this);
. If I take out this statement, nothing is printed at all, leading me to believe that the mouseListeners I have added are only working one level deep. (The first GCompound on the canvas, not the GCompounds inside it.)
Therefore, my question is as follows: Is there a way to get a MouseListener for a GCompound inside of a GCompound inside of a GCompound, and have MouseEvent's getSource to correctly identify the card? If not, is there a way to restructure my program to make it work as intended? (I know I should really be using a better graphics library for starters.)