简体   繁体   中英

How can I get the component I clicked on from a grid?

I am displaying a grid of objects, and I want to print the name of the one I click on. However the following code only registers a click when I click the top-left-most square, and then every single card prints its name.

Any idea what I need to do differently?

public class GHand extends JPanel {

    GCard[] grid; //names the grid of buttons

    public GHand(int width, int height, Hand hand) { //constructor
        this.setLayout(new GridLayout(width, 4));
        grid = new GCard[hand.size()]; //allocate the size of grid
        for (int i = 0; i < grid.length; i++) {
            grid[i] = new GCard(hand.getCard(i)); //creates new card
            this.add(grid[i]); //adds card to grid
        }

        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me) {
                super.mouseClicked(me);
                for (GCard g : grid) {

                    if (g.contains(me.getPoint())) {//check if mouse is clicked within card

                        System.out.println("Clicked a " + g.getCardName());

                    }
                }
            }
        });
    }
}

I imagine it would be wasteful to add a listener to every object in the grid right? What's the best practice for this?

I think you are on the right track...

I don't think that you should be using MouseEvent since that tracks the mouse motion and clicking and so you would have to track where exactly your grid item is. You may want to do this but you will have to create more code in order to solve where your grid item is and that will involve much complicated code to do with the GUI.

My opinion is that you should be using an ActionEvent Listener so that you when you do click on an object (I am assuming a JPanel or Button object) you can respond to the click that has happened. Through the .getCommand() method.

You will have to change the GHand object or the GCard object (depending on what you are using to show on the grid) to include a name variable that can be used to differentiate between different objects. (This can be as simple as a single counter method to determine the ID of the object) OR you could just leave it as a name variable. You will have to override the .toString() method (inside the GHand/GCard object) in order to allow the .getCommand() method to respond with a reader friendly response so that you can direct your program flow according to what has been clicked.


This should not be wasteful to adding a listener since you should be adding already to the single object class. I have assumed that you are using a grid to allow the user to click on the object (I don't know if were using many GHands with multiple GCards or just the one GHand with multiple GCards to display on the screen). Because of this you can create simple objects and spread them over a grid, where you can click on the grid object and it should respond to the click, therefore grabbing your method and then calling it.

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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