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);
  }
}
2
  • are you want to know that (from your picture) that from 3rd. column and 2dn. row
    – mKorbel
    Oct 9, 2011 at 10:02
  • 1
    If you start from 0; it is 2nd and 1st.
    – Tobias
    Oct 9, 2011 at 10:03

7 Answers 7

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();
            }
        });
    }
}
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 :-)
    – nIcE cOw
    Apr 29, 2012 at 17:02
  • 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.
    – trashgod
    Apr 29, 2012 at 17:21
  • A related example Using JavaFX is shown here.
    – trashgod
    Oct 4, 2021 at 3:11
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
    }
  }
}
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. Oct 9, 2011 at 10:04
  • You could add a different ActionLisenter to every button with this information.
    – Tobias
    Oct 9, 2011 at 10:08
  • 1
    I know this is old, but this quick and dirty solution is exactly what I needed. Thanks. +1!
    – Bryan
    May 30, 2014 at 2:50
6

From JButtons

  • JButton#setName(String);

  • JBUtton#setActionCommand(String);

  • JBUtton#setAction(Action);

from/to Container

SwingUtilities#convert...

SwingUtilities#getDeepestComponentAt

1
  • @Răzvan Panda the best examples for that are on this forum, for every methods that I posted to my answer :-)
    – mKorbel
    Oct 9, 2011 at 18:16
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.

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());

    }

}
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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.