Как получить X и Y индекс элемента внутри GridLayout?

Я изучал Java-учебник и увидел, что способ найти x/y-индексы JButton внутри GridLayout - это пройти через двумерный массив кнопок b, который связан с макетом, и проверить,

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

Есть ли более простой способ получить индексы X/Y кнопки?

Что-то вроде:

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

this будучи экземпляром GameWindow и ev ActionEvent запускается, когда пользователь нажимает кнопку.

В этом случае должно получиться: 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);
  }
}

7 ответов

Решение

В этом примере показано, как создать кнопку сетки, которая знает свое местоположение в сетке. Метод getGridButton() показывает, как эффективно получить ссылку на кнопку на основе координат сетки, а слушатель действия показывает, что нажатые и найденные кнопки идентичны.

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://stackru.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();
            }
        });
    }
}

Вы сохранили массив всех JButtons; вы могли бы искать ae.getSource() и у вас есть позиция.

for (int i = 0; i < 5; i++) {
  for (int j = 0; j < 5; j++) {
    if( b[i][j] == ae.getSource() ) { 
      // position i,j
    }
  }
}

От JButtons

  • JButton# SetName (String);

  • JButton# setActionCommand (String);

  • JButton# SetAction(действий);

из / в контейнер

SwingUtilities# конвертировать...

SwingUtilities# getDeepestComponentAt

Я думаю, что есть лучший способ, например, я создал новый класс JButton, который расширяет JButton из javax.swing, я назвал его JButton2, затем я добавил к нему 2 новых атрибута (xGridPos и ​​yGridPos) следующим образом:

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

Когда я создаю новый JButton2, я устанавливаю эти новые атрибуты с позицией x и y в сетке, чтобы вы могли получить x и y и использовать их с getSource и с помощью 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
    }
}

Я надеюсь, что это полезно:D.

Вы можете использовать setName(), чтобы сохранить в JButton его местоположение (например, button.setName(i+" "+j);) при его создании; Вы можете получить к нему доступ, разделив строку, полученную из button.getName (), вокруг пробела. Это не особенно эффективный метод, но он немного похож на то, что вы ищете (или уже искали).

Это решение выбирает все объекты между ними, как они
первый метод записи, который получает текст или все необходимое для Jbuuton или jlable или.... второе изменение в коде

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

    }

}

Вам не нужно, чтобы ваши кнопки явно сохраняли свои координаты x,y. Рассмотрим следующий код:

      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);
Другие вопросы по тегам