How to get X and Y index of element inside GridLayout?
Asked Answered
S

7

17

I am studying a java tutorial and saw that the way to find the x/y indexes of a JButton inside a GridLayout is to traverse a bidimensional array of buttons b which is associated to the layout and checking if

b[i][j] == buttonReference.

  @Override
  public void actionPerformed(ActionEvent ae) {
    JButton bx = (JButton) ae.getSource();
    for (int i = 0; i < 5; i++)
      for (int j = 0; j < 5; j++)
        if (b[i][j] == bx)
        {
          bx.setBackground(Color.RED);
        }
  }

Is there an easier way to get the X/Y indexes of a button?

Something like:

JButton button = (JButton) ev.getSource();
int x = this.getContentPane().getComponentXIndex(button);
int y = this.getContentPane().getComponentYIndex(button);

this being a GameWindow instance and ev the ActionEvent triggered when the user presses the button.

In this case it should get: x == 2, y == 1

@GameWindow.java:

package javaswingapplication;

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

public class GameWindow extends JFrame implements ActionListener
{
  JButton b[][] = new JButton[5][5];

  int v1[] = { 2, 5, 3, 7, 10 };
  int v2[] = { 3, 5, 6, 9, 12 };

  public GameWindow(String title)
  {
    super(title);

    setLayout(new GridLayout(5, 5));
    setDefaultCloseOperation(EXIT_ON_CLOSE );

    for (int i = 0; i < 5; i++)
      for (int j = 0; j < 5; j++)
      {
        b[i][j] = new JButton();
        b[i][j].addActionListener(this);
        add(b[i][j]);
      }
  }

  @Override
  public void actionPerformed(ActionEvent ae) {
    ((JButton)ae.getSource()).setBackground(Color.red);
  }
}

@JavaSwingApplication.java:

package javaswingapplication;

public class JavaSwingApplication {
  public static void main(String[] args) {
    GameWindow g = new GameWindow("Game");
    g.setVisible(true);
    g.setSize(500, 500);
  }
}
Sporadic answered 9/10, 2011 at 9:55 Comment(2)
are you want to know that (from your picture) that from 3rd. column and 2dn. rowElainaelaine
If you start from 0; it is 2nd and 1st.Aman
C
20

This example shows how to create a grid button that knows its location on the grid. The method getGridButton() shows how to obtain a button reference efficiently based on its grid coordinates, and the action listener shows that the clicked and found buttons are identical.

GridButtonPanel

package gui;

import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @see http://stackoverflow.com/questions/7702697
 */
public class GridButtonPanel {

    private static final int N = 5;
    private final List<JButton> list = new ArrayList<JButton>();

    private JButton getGridButton(int r, int c) {
        int index = r * N + c;
        return list.get(index);
    }

    private JButton createGridButton(final int row, final int col) {
        final JButton b = new JButton("r" + row + ",c" + col);
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                JButton gb = GridButtonPanel.this.getGridButton(row, col);
                System.out.println("r" + row + ",c" + col
                    + " " + (b == gb)
                    + " " + (b.equals(gb)));
            }
        });
        return b;
    }

    private JPanel createGridPanel() {
        JPanel p = new JPanel(new GridLayout(N, N));
        for (int i = 0; i < N * N; i++) {
            int row = i / N;
            int col = i % N;
            JButton gb = createGridButton(row, col);
            list.add(gb);
            p.add(gb);
        }
        return p;
    }

    private void display() {
        JFrame f = new JFrame("GridButton");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(createGridPanel());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new GridButtonPanel().display();
            }
        });
    }
}
Capitate answered 9/10, 2011 at 21:31 Comment(3)
Ahha, a quick question PLEASE, I just learned one thing with this that in order to use this inside Anonymous Classes we can use the ClassName.this, but does that mean that this is static ? Hope I am not looking stupid, when I asked this question :-)Shuler
No, just the opposite. The first qualified this refers to the enclosing instance of GridButtonPanel, while the second refers to the enclosing instance of GridButton.Capitate
A related example Using JavaFX is shown here.Capitate
A
9

You have saved an array of all JButtons; you could search for ae.getSource() and you have the position.

for (int i = 0; i < 5; i++) {
  for (int j = 0; j < 5; j++) {
    if( b[i][j] == ae.getSource() ) { 
      // position i,j
    }
  }
}
Aman answered 9/10, 2011 at 10:1 Comment(3)
Yeah, that is the way it is done in the tutorial. In my question i was asking for a more direct way like in the example i gave.Buffet
You could add a different ActionLisenter to every button with this information.Aman
I know this is old, but this quick and dirty solution is exactly what I needed. Thanks. +1!Cornerwise
E
6

From JButtons

  • JButton#setName(String);

  • JBUtton#setActionCommand(String);

  • JBUtton#setAction(Action);

from/to Container

SwingUtilities#convert...

SwingUtilities#getDeepestComponentAt

Elainaelaine answered 9/10, 2011 at 10:30 Comment(1)
@Răzvan Panda the best examples for that are on this forum, for every methods that I posted to my answer :-)Elainaelaine
D
1

You can use setName() to store within a JButton its location(ex. button.setName(i+" "+j);) when you create it; you can then access it by splitting the string you get from button.getName() around the space. It is not an especially efficient method, but it sounds a little like what you are (or were, by now) looking for.

Domella answered 25/4, 2013 at 16:13 Comment(0)
I
1

this solution selects everything object between like them
first write method that get text or Everything needed for Jbuuton or jlable or.... second change under code

public class Event_mouse implements MouseListener {

    @Override
    public void mouseReleased(MouseEvent e) {
        try {
            Everything source = (Everything) e.getSource();
             if(Everything.gettext==gol){

             }

        } catch (Exception ee) {
            JOptionPane.showMessageDialog(null, ee.getMessage());

    }

}
Ilocano answered 9/10, 2016 at 10:51 Comment(0)
C
1

I think there is a better way, for example i made a new JButton class that extends JButton from javax.swing, i named it JButton2, then i added 2 new attributes to it (xGridPos and yGridPos) like this:

private class JButton2 extends JButton{
    public int xGridPos;
    public int yGridPos;
}

When I create a new JButton2 I set this new attributes with the x and y position on the grid so you can get the x and y and use them with getSource and using cast:

private class ListenerTest implements ActionListener{
    public void actionPerformed(ActionEvent theActionEvent){
        JButton2 theButton = (JButton2)actionE.getSource();
        // Use the xGridPos and yGridPos in section with theButton.xGridPos or
        // theButton.xGridPos
    }
}

I hope this is helpfull :D.

Cranage answered 10/12, 2020 at 17:18 Comment(0)
L
0

You do not need your buttons to explicitly store their x,y position. Consider the following code:

JComponent e=//something with GridLayout
var count=e.getComponentCount();
var row=count/11;//for example, you have an 11*11 grid
var col=count%11;
var bb=new JButton(row+" "+col);//or any other text you like
bb.addActionListener(unused->System.out.println(
    "pressed button "+count+ " in row="+row+" col="+col
    ));
this.add(bb);
Linehan answered 17/7, 2021 at 1:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.