3

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

ddriver1
  • 723
  • 10
  • 18

5 Answers5

5

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

enter image description hereenter image description hereenter image description here

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();
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Why is this better than a Jtable? I actually believe it is a waste of ressources. Because your GridPanel contains a row and a column which is an exact duplicate of a Jtable behavior – Adel Boutros Jan 20 '12 at 14:22
  • What I mean is that you're mimicking a Jtable when it already exist in Java. So why reinvent the wheel? – Adel Boutros Jan 20 '12 at 14:23
  • 1) you are right for simple JPanel in the JTable's cell, but in case that JPanel nested another JComponents or Graphics, then required SwingUtilities, 2) JTable knows return Rectangle or cell from MouseEvent, – mKorbel Jan 20 '12 at 14:29
  • The unclear question is why do he need JPanels in the first place? 1) Maybe he doens't know about JTable 2) he has not provided enough information about what he wants to do – Adel Boutros Jan 20 '12 at 14:30
  • I am just trying to know why he wants to place JPanels in the first place – Adel Boutros Jan 20 '12 at 14:30
  • majorities of askers doesn't interesting somehow about alternatives, s/he wanted/look for shoutcuts, – mKorbel Jan 20 '12 at 14:36
  • +1 for coordinate transformation; see also [`GridButtonPanel`](http://stackoverflow.com/a/7706684/230513). – trashgod Jan 20 '12 at 18:43
  • thanks to your simple and direct idea traslated to the code, my learning item on this day – mKorbel Jan 20 '12 at 19:05
3

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);
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
2

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

Adel Boutros
  • 10,205
  • 7
  • 55
  • 89
2

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 :

Panel Selection through X, Y Co-ordinates

Hope this might help in some way.

Regards

nIcE cOw
  • 24,468
  • 7
  • 50
  • 143
1

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];
}
dogbane
  • 266,786
  • 75
  • 396
  • 414
  • If I understood correctly, the problem is to get the position from the panel, not the panel from the position. – JB Nizet Jan 20 '12 at 13:26