Domanda

How to get position(I mean row and column) of the clicked button with gridlayout?

public void init(final Container pane) {
    JPanel controls = new JPanel();
    int size = (int) Math.sqrt(puzzle.getSize() + 1);
    controls.setLayout(new GridLayout(size, size));
    for (int i = 0; i < puzzle.getSize(); i++) {
        int k = puzzle.getListItem(i);
        if (k == puzzle.getEmptyFlag())
            controls.add(new JLabel(""));
        else {
            JButton jb = new JButton(String.valueOf(k));
            jb.addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    //get row and column
                }

            });
            controls.add(jb);
        }
    }
    pane.add(controls);
}
È stato utile?

Soluzione

  1. Never add a MouseListener on a JButton for that purpose. Use an ActionListener instead.
  2. Why not create an array or ArrayList of JButton and then simply iterate through the list to find the proper one?

i.e.,

private JButton[][] buttonGrid = new JButton[ROWS][COLS];

Elsewhere you will need to fill the grid with viable JButton objects and place those JButtons into your GUI.

Then later in program use a nested for loop iterating through the grid comparing the grid button with the getSource() JButton.

i.e. in the JButton's ActionListener

public void actionPerformed(ActionEvent e) {
  for (int row = 0; row < ROWS; row++) {
    for (int col = 0; col < COLS; col++) {
       if buttonGrid[row][col] == e.getSource();
       // here you have your row and column
    }
  }
}

Edit
You ask:

  1. why?

Because it won't work correctly in many situations. ActionListeners have been built to work specifically with JButtons and JMenuItems and have mechanisms that make this function work well l and easily. For example, say you decide to have a JButton that is only enabled once the user has filled two JTextFields, and you use the JButton's setEnabled(boolean enabled) method to do this, disabling the JButton will not stop the MouseListener from working, but it will stop the ActionListener.


Edit 2

For example,

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class ButtonGridEg extends JPanel {
   private static final int ROWS = 8;
   private static final int COLS = ROWS;
   private static final int GAP = 5;
   private JButton[][] buttonGrid = new JButton[ROWS][COLS];

   public ButtonGridEg() {
      setLayout(new GridLayout(ROWS, COLS, GAP, GAP));

      ActionListener buttonListener = new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent evt) {
            JButton selectedBtn = (JButton) evt.getSource();
            for (int row = 0; row < buttonGrid.length; row++) {
               for (int col = 0; col < buttonGrid[row].length; col++) {
                  if (buttonGrid[row][col] == selectedBtn) {
                     System.out.printf("Selected row and column: %d %d%n", row, col);
                  }
               }
            }
         }
      };
      for (int row = 0; row < buttonGrid.length; row++) {
         for (int col = 0; col < buttonGrid[row].length; col++) {
            String text = String.format("Button [%d, %d]", row, col);
            buttonGrid[row][col] = new JButton(text);
            buttonGrid[row][col].addActionListener(buttonListener);
            add(buttonGrid[row][col]);
         }
      }
   }

   private static void createAndShowGui() {
      ButtonGridEg mainPanel = new ButtonGridEg();

      JFrame frame = new JFrame("ButtonGridEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

Altri suggerimenti

In this case, you don't even have to search for the indices, because you know them when the button is created:

for (int i = 0; i < puzzle.getSize(); i++) {
    int k = puzzle.getListItem(i);
    if (k == puzzle.getEmptyFlag())
        controls.add(new JLabel(""));
    else {
        JButton jb = new JButton(String.valueOf(k));

        final int rowIndex = i / size;
        final int columnIndex = i % size;

        // Using an ActionListener, as Hovercraft Full Of Eels already told you:
        jb.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("rowIndex "+rowIndex+" columnIndex "+columnIndex);
            }

        });
        controls.add(jb);
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top