简体   繁体   中英

How do I add MouseListeners to an individual panel in a grid of panels?

I'm trying to create a game of Reversi, and I'm in the beginning stages trying to figure out how to have a square respond to a click event. Here is my code so far.

To be clear, at the moment, I'm just trying to change the background color of a clicked panel in the grid. I'm still learning how ActionListeners work.

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.MouseListener;

public class Reversi {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        ReversiFrame frame = new ReversiFrame();
        frame.setSize(400,450);
        frame.setResizable(false);
        frame.setVisible(true);


    }  
}
/**
 * 
 * Class for the frame
 */
class ReversiFrame extends JFrame{

    /**
     * Constructor for ReversiFrame
     */
    public ReversiFrame(){

        super("Reversi");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JMenuBar bar = new JMenuBar();
        setJMenuBar(bar);

        JMenu gameMenu = new JMenu("Game");
        JMenu helpMenu = new JMenu("Help");

        bar.add(gameMenu);
        bar.add(helpMenu);

        final JMenuItem newGame = new JMenuItem("New Game");
        final JMenuItem exit = new JMenuItem("Exit");
        final JMenuItem help = new JMenuItem("Help");

        gameMenu.add(newGame);
        gameMenu.add(exit);
        helpMenu.add(help);

        /**
         * Exits program when exit menu item is clicked.
         */
        exit.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                dispose();
            }
        });

        ReversiPanel panel = new ReversiPanel();
        add(panel);


    }
}

class ReversiPanel extends JPanel{
    public static final int GRID_ROWS = 8;
    public static final int GRID_COLS = 8;
    public static final int HEIGHT = 50;
    public static final int WIDTH = 50;

    private GridPanel [][] panels = new GridPanel[GRID_ROWS][GRID_COLS];

    public ReversiPanel(){
        setLayout(new GridLayout(GRID_ROWS,GRID_COLS));
        setSize(HEIGHT, WIDTH);
        for(int row = 0; row < GRID_ROWS; row++){
            for(int col = 0; col < GRID_COLS; col++){
                panels[row][col] = (new GridPanel(row, col));
                setFocusable(true);
                panels[row][col].addMouseListener(new MouseAdapter(){
                    /*public void mouseClicked(MouseEvent e){
                        ((GridPanel)e.getSource()).getParent().setBackground(Color.red);
                        repaint();
                    }*/
                });
            }
        }
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        for(int row = 0; row < GRID_ROWS; row++){
            for(int col = 0; col < GRID_COLS; col++){
                panels[row][col].draw(g2);
            }
        }
    }
}

class GridPanel extends JPanel{
    public static final int HEIGHT = 50;
    public static final int WIDTH = 50;
    private boolean filled;
    private int numberGridsFilled = 0;
    private int x, y;


    public GridPanel(int row, int col){
        x = row * WIDTH;
        y = + col * HEIGHT;
        setSize(HEIGHT, WIDTH);
        filled = false;
        setBorder(BorderFactory.createLineBorder(Color.GRAY));
        setBackground(Color.red);

        addMouseListener(new MouseAdapter(){


            public void mouseClicked(MouseEvent e){
                setBackground(Color.RED);
                repaint();
            }
        });

    }



    public void draw(Graphics2D g2){
        g2.setPaint(Color.GRAY);
        Rectangle2D r = new Rectangle2D.Double(x, y, WIDTH, HEIGHT);
        g2.draw(r);
    }

    public void changeColor(){
        setBackground(Color.BLACK);
    }

    public void setColor() {
        setBackground(Color.BLACK);
    }
}

class Tile{
    private Color color;

    public Tile(Color color){

    }
}

To start with, I wouldn't do panels[row][col].draw(g2); in your paintComponent , GridPanel extends from JPanel and JPanel is very capable of painting itself.

Start by getting rid the paintComponent method and add the GridPanel s to the ReversiPanel ...

public ReversiPanel() {
    setLayout(new GridLayout(GRID_ROWS, GRID_COLS));
    for (int row = 0; row < GRID_ROWS; row++) {
        for (int col = 0; col < GRID_COLS; col++) {
            panels[row][col] = (new GridPanel(row, col));
            add(panels[row][col]);
            setFocusable(true);
            panels[row][col].addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e){
                 ((GridPanel)e.getSource()).getParent().setBackground(Color.red);
                 repaint();
                 }
            });
        }
    }
}

When a component is added to a container (which is attached to a native peer), it becomes eligible for event notification

Now, in you GridPanel , replace the draw method with paintComponent and override the getPreferredSize to return the desired size of the component

class GridPanel extends JPanel {

    public static final int HEIGHT = 50;
    public static final int WIDTH = 50;
    private boolean filled;
    private int numberGridsFilled = 0;
    private int row, col;

    public GridPanel(int row, int col) {
        row = row;
        col = col;
        filled = false;
        setBorder(BorderFactory.createLineBorder(Color.GRAY));
        setBackground(Color.red);
    }

    public Dimension getPreferredSize() {
        return new Dimenions(WIDTH, HEIGHT);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setPaint(Color.GRAY);
        Rectangle2D r = new Rectangle2D.Double(x, y, WIDTH, HEIGHT);
        g2d.draw(r);
        g2d.dispose();
    }

… trying to figure out how to have a square respond to a click event.

Make the square a (possibly undecorated) JButton instead of a JPanel . Give the button an icon, and/or text, then add an ActionListener .

A button with an action listener will respond to both mouse and keyboard events.

EG as seen in this answer to Add a complex image in the panel, with buttons around it in one customized user interface .

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