Как добавить MouseListeners на отдельную панель в сетке панелей?

1

Я пытаюсь создать игру Reversi, и я нахожусь на начальных этапах, пытаясь понять, как квадрат реагировать на событие click. Вот мой код до сих пор.

Чтобы быть ясным, на данный момент я просто пытаюсь изменить цвет фона щелкнутой панели в сетке. Я все еще участвую в работе ActionListeners.

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){

    }
}
  • 0
    Этот вопрос слишком широкий. В его текущем состоянии это по сути "напиши этот код для меня". Вы должны сузить свой вопрос до чего-то более конкретного. (В идеале, то, что можно продемонстрировать, не используя весь текст вашего кода)
  • 0
    Да, довольно сложно сформулировать то, что я хочу спросить, потому что я думаю, что я мог бы найти это гораздо проще, если бы знал, что сказать. По сути, вопрос в том, «как мне обратиться к самой панели на событии, щелкнувшей, чтобы изменить фон?» Судя по чьему-то ответу, это e.getSource (), но поправьте меня, если что-то еще поможет.
Теги:
grid
swing
mouselistener
actionlistener

2 ответа

4
Лучший ответ

Для начала я бы не сделал panels[row][col].draw(g2); в вашем paintComponent, GridPanel простирается от JPanel и JPanel очень способен рисовать сам.

Начните с paintComponent метода paintComponent и добавьте GridPanel в 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();
                 }
            });
        }
    }
}

Когда компонент добавляется в контейнер (который привязан к собственному равноправному узлу), он становится пригодным для уведомления о событии

Теперь, в GridPanel, замените метод draw с помощью paintComponent и переопределите getPreferredSize чтобы вернуть желаемый размер компонента

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();
    }
  • 0
    Спасибо большое за вашу помощь! Это объяснило именно то, что я хотел знать. Иногда трудно, как новичку, правильно задавать вопросы. Еще раз спасибо! Хотел бы я отозвать тебя, но я только что создал аккаунт. знак равно
  • 0
    Рад, что это могло помочь. Кроме того, вы можете добавить MouseListener непосредственно в GridPanel , но это зависит от ваших собственных потребностей.
Показать ещё 2 комментария
3

... пытаясь выяснить, как квадрат реагировать на событие click.

Сделайте квадрат (возможно, не декорированный) JButton вместо JPanel. Дайте кнопке значок и/или текст, а затем добавьте ActionListener.

Кнопка с прослушивателем действий будет реагировать на события мыши и клавиатуры.

EG, как показано в этом ответе " Добавить сложное изображение на панели, с кнопками вокруг него в одном настраиваемом пользовательском интерфейсе".

Изображение 174551

  • 0
    Я бы предпочел добавить события на панели, но если это невозможно, я обязательно опробую вашу идею. Спасибо за совет!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню