【问题标题】:How to get X and Y index of element inside GridLayout?如何获取 GridLayout 中元素的 X 和 Y 索引?
【发布时间】:2011-12-03 21:36:03
【问题描述】:

我正在研究一个 java 教程,发现在 GridLayout 中查找 JButton 的 x/y 索引的方法是遍历与布局关联的按钮 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);
  }
}

【问题讨论】:

  • 您是否想知道(从您的照片中)从 3 开始。列和 2dn。行
  • 如果从0开始;它是第 2 和第 1。

标签: java swing awt grid-layout


【解决方案1】:

此示例展示了如何创建一个知道其在网格上的位置的网格按钮。 getGridButton() 方法展示了如何根据其网格坐标有效地获取按钮引用,并且动作监听器显示点击和找到的按钮是相同的。

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

【讨论】:

  • 啊哈,问一个简单的问题,我刚刚学到了一件事,为了在Anonymous Classes 中使用this,我们可以使用ClassName.this,但这是否意味着this是静态的吗?希望当我问这个问题时,我看起来并不愚蠢:-)
  • 不,正好相反。第一个qualified this 引用GridButtonPanel 的封闭实例,而第二个引用GridButton 的封闭实例。
  • 使用 JavaFX 的相关示例显示为here
【解决方案2】:

您已经保存了一个包含所有 JButton 的数组;您可以搜索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
    }
  }
}

【讨论】:

  • 是的,教程中就是这样做的。在我的问题中,我要求一种更直接的方式,就像我给出的例子一样。
  • 您可以使用此信息为每个按钮添加不同的 ActionLisenter。
  • 我知道这是旧的,但这种快速而肮脏的解决方案正是我所需要的。谢谢。 +1!
【解决方案3】:

来自 JButtons

  • JButton#setName(String);

  • JBUtton#setActionCommand(String);

  • JBUtton#setAction(Action);

从/到容器

SwingUtilities#convert...

SwingUtilities#getDeepestComponentAt

【讨论】:

  • @Răzvan Panda 最好的例子在这个论坛上,对于我发布到我的答案的每一种方法:-)
【解决方案4】:

您可以在创建 JButton 时使用 setName() 在 JButton 中存储其位置(例如 button.setName(i+" "+j););然后,您可以通过在空间周围拆分从 button.getName() 获得的字符串来访问它。这不是一种特别有效的方法,但听起来有点像您正在(或现在)正在寻找的东西。

【讨论】:

    【解决方案5】:

    此解决方案选择喜欢它们之间的所有对象
    第一的 编写获取文本或 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());
    
        }
    
    }
    

    【讨论】:

      【解决方案6】:

      我认为有更好的方法,例如我创建了一个从 javax.swing 扩展 JButton 的新 JButton 类,我将它命名为 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。

      【讨论】:

        【解决方案7】:

        您不需要您的按钮显式存储它们的 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);
        

        【讨论】:

          猜你喜欢
          • 2012-05-13
          • 2022-08-02
          • 1970-01-01
          • 2021-02-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多