java swing associating JPanel with row col values for mouse listener

独自空忆成欢 提交于 2020-01-04 04:11:09

问题


I'm writing a board game with a GUI and basically I have a 10x10 GridLayout JPanel.

Each grid cell is a square JPanel (I used BorderLayout for these JPanels so the borders are visible).

Anyway I want it so that when one of these squares is clicked, it makes a change to the boardGameGrid which is a class imported to the GUI for the backend of the game. Say I want to use the method

boardGameGrid.setCellCross(x,y)

when the cell at position (x,y) is pressed.

I can't figure out how to do this since each JPanel does not contain any information about its position.

thanks


回答1:


You have to prepare this JPanels as Object and put that to the Map or List, simple example based on great but simple idea

import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.LineBorder;
//based on @trashgod code from http://stackoverflow.com/a/7706684/714968
public class FocusingPanel extends JFrame {

    private static final long serialVersionUID = 1L;
    private int elements = 10;
    private List<GridPanel> list = new ArrayList<GridPanel>();
    private final JFrame mainFrame = new JFrame();
    private final JPanel fatherPanel = new JPanel();

    public FocusingPanel() {
        fatherPanel.setLayout(new GridLayout(elements, elements));
        for (int i = 0; i < elements * elements; i++) {
            int row = i / elements;
            int col = i % elements;
            GridPanel gb = new GridPanel(row, col);
            list.add(gb);
            fatherPanel.add(gb);
        }
        mainFrame.setLayout(new BorderLayout(5, 5));
        mainFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        mainFrame.add(fatherPanel, BorderLayout.CENTER);
        mainFrame.pack();
        mainFrame.setVisible(true);
    }

    private GridPanel getGridPanel(int r, int c) {
        int index = r * elements + c;
        return list.get(index);
    }

    private class GridPanel extends JPanel {

        private int row;
        private int col;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(20, 20);
        }

        public GridPanel(int row, int col) {
            this.row = row;
            this.col = col;
            this.setBackground(Color.red);
            this.setBorder(new LineBorder(Color.black,1));
            this.addMouseListener(new MouseListener() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    int r = GridPanel.this.row;
                    int c = GridPanel.this.col;
                    GridPanel gb = FocusingPanel.this.getGridPanel(r, c);
                    System.out.println("r" + r + ",c" + c
                            + " " + (GridPanel.this == gb)
                            + " " + (GridPanel.this.equals(gb)));
                }

                @Override
                public void mousePressed(MouseEvent e) {
                }

                @Override
                public void mouseReleased(MouseEvent e) {
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                    int r = GridPanel.this.row;
                    int c = GridPanel.this.col;
                    GridPanel gb = FocusingPanel.this.getGridPanel(r, c);
                    System.out.println("r" + r + ",c" + c
                            + " " + (GridPanel.this == gb)
                            + " " + (GridPanel.this.equals(gb)));
                    setBackground(Color.blue);

                }

                @Override
                public void mouseExited(MouseEvent e) {
                    setBackground(Color.red);
                }
            });
        }
    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                FocusingPanel focusingPanel = new FocusingPanel();
            }
        });
    }
}



回答2:


Why don't you simply make each panel know about his position:

public MyPanel(int x, int y) {
    this.x = x;
    this.y = y;
}

and, in the mouse listener:

MyPanel p = (MyPanel) event.getSource();
boardGameGrid.setCellCross(p.getX(), p.getY());

Or you could also use a Map<MyPanel, Point> if you don't want to alter MyPanel, and store the position of each panel in this map:

MyPanel p = (MyPanel) event.getSource();
Point point = panelPositionMap.get(p);
boardGameGrid.setCellCross(p.x, p.y);



回答3:


Why don't you do it as a JTable instead of JPanel, and you can add a listener per cell. This way you will know what row and what column was clicked




回答4:


Each JPanel does knows about its location, which you can get by using panel.getX()/getY(). Seems like what you asking for is this :

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PanelLocation extends JFrame implements MouseListener
{
    private JPanel mainPanel, footerPanel;
    private JPanel[] panel = new JPanel[9];
    private JTextField tfield;

    public PanelLocation()
    {
        mainPanel = new JPanel();
        mainPanel.setLayout(new GridLayout(3, 3));

        for (int i = 0; i < 9; i++)
        {
            panel[i] = new JPanel();
            panel[i].addMouseListener(this);
            panel[i].setBorder(BorderFactory.createLineBorder(Color.BLUE));
            mainPanel.add(panel[i]);
        }   

        footerPanel = new JPanel();

        tfield = new JTextField(10);
        footerPanel.add(tfield);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        add(mainPanel, BorderLayout.CENTER);
        add(footerPanel, BorderLayout.PAGE_END);

        pack();     
        setVisible(true);
    }



     private void getWhichButtonGotPressed(int x, int y)
     {
         if ((x == panel[0].getX()) && (y == panel[0].getY()))
         {
            panel[0].setBackground(Color.MAGENTA);
            tfield.setText("You Clicked Panel : " + panel[0].getToolTipText());
         }
         else if ((x == panel[1].getX()) && (y == panel[1].getY()))
         {
            panel[1].setBackground(Color.YELLOW);
            tfield.setText("You Clicked Panel : " + panel[1].getToolTipText());
         }
         else if ((x == panel[2].getX()) && (y == panel[2].getY()))
         {
            panel[2].setBackground(Color.RED);
            tfield.setText("You Clicked Panel : " + panel[2].getToolTipText());
         }
         else if ((x == panel[3].getX()) && (y == panel[3].getY()))
         {
            panel[3].setBackground(Color.DARK_GRAY);
            tfield.setText("You Clicked Panel : " + panel[3].getToolTipText());
         }
         else if ((x == panel[4].getX()) && (y == panel[4].getY()))
         {
            panel[4].setBackground(Color.ORANGE);
            tfield.setText("You Clicked Panel : " + panel[4].getToolTipText());
         }
         else if ((x == panel[5].getX()) && (y == panel[5].getY()))
         {
            panel[5].setBackground(Color.PINK);
            tfield.setText("You Clicked Panel : " + panel[5].getToolTipText());
         }
         else if ((x == panel[6].getX()) && (y == panel[6].getY()))
         {
            panel[6].setBackground(Color.BLUE);
            tfield.setText("You Clicked Panel : " + panel[6].getToolTipText());
         }
         else if ((x == panel[7].getX()) && (y == panel[7].getY()))
         {
            panel[7].setBackground(Color.CYAN);
            tfield.setText("You Clicked Panel : " + panel[7].getToolTipText());
         }
         else if ((x == panel[8].getX()) && (y == panel[8].getY()))
         {
            panel[8].setBackground(Color.GRAY);
            tfield.setText("You Clicked Panel : " + panel[8].getToolTipText());
         }
    }

    public void mouseClicked(MouseEvent ae)
    {
        JPanel panel = (JPanel) ae.getSource();

        getWhichButtonGotPressed(panel.getX(), panel.getY());
    }

    public void mousePressed(MouseEvent ae)
    {
    }

    public void mouseReleased(MouseEvent ae)
    {
    }

    public void mouseEntered(MouseEvent ae)
    {
    }

    public void mouseExited(MouseEvent ae)
    {
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    new PanelLocation();
                }
            });
    }
}

A sample program showing the Co-ordinates of the clicked panel. You just click the panel, the co-ordinates are passed to the function and that function will check which panel is clicked on, and returns the toopTipText for the said panel.

Here is the output of the program :

Hope this might help in some way.

Regards




回答5:


You can use a 2d array to store references to your panels.

Example:

JPanel[][] panels = new JPanel[10][10];

//to store a panel:
JPanel p = new JPanel();
panels[x][y] = p;

//then change your method so that it gets the panel at position (x,y) from the array
public void setCellCross(int x, int y){
     JPanel clickedPanel = panels[x][y];
}


来源:https://stackoverflow.com/questions/8941939/java-swing-associating-jpanel-with-row-col-values-for-mouse-listener

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!