检查在Jframe(Java)中单击了哪个Jbutton(多个Jbutton)

问题描述 投票:0回答:3

im做一个棋盘游戏,在一个框架中有64个Jbutton的8X8矩阵。到目前为止,我的代码是这样的:

public class Main {
static JFrame f  = new JFrame();;
static JButton btn;
static JButton btnTemp;


    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setLayout((new GridLayout(8,8)));//size of the board
    f.setTitle("ex");
    f.setSize(800,800);

for (int i=0;i<=7;i++)
    {
        for (int j = 0; j<=7;j++)
        {

            btn=new JButton();
            btn = new JButton(new SoliderW());  
            btn.setName("btn"+i+""+j);
            btn.setBackground(Color.BLACK); 
            btn.addActionListener(actionListener); // make a listener to the button
            f.add(btn);
            }

    }


    f.setVisible(true);

我正在尝试使用此代码来确定单击了哪个JButoon:

Component[] components = f.getContentPane().getComponents();


    ActionListener actionListener = new ActionListener()
    {
      @Override
        public void actionPerformed(ActionEvent e)
         {
              System.out.println("Hello");
          }
     };

       for (Component component : components)
          {
               if (component instanceof JButton)
                  {
                  ((JButton) component).addActionListener(actionListener);
                  }
          }

但是,我不知道如何知道单击了哪个Jbutton。

java swing user-interface jframe jbutton
3个回答
1
投票

让我们以static开头不是您的朋友,应该避免使用它,尤其是当您尝试跨对象边界引用实例时。

您可以...

例如,使用Anonymous Classes ...

btn = new JButton();
btn = new JButton(new SoliderW());
btn.setName("btn" + i + "" + j);
btn.setBackground(Color.BLACK);
btn.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        // Do some work
    }
}); // make a listener to the button

但是,老实说,由于btnstatic,这对您没有帮助

您可以...

使用actionCommand属性

ActionListener actionListener = new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent evt) {
        String command = evt.getActionCommand();
        // Do more work
    }
};

//...

for (int i = 0; i <= 7; i++) {
    for (int j = 0; j <= 7; j++) {

        btn = new JButton();
        btn = new JButton(new SoliderW());
        btn.setName("btn" + i + "" + j);
        btn.setBackground(Color.BLACK);
        // Replace the text with something that will
        // uniquely identify this button
        btn.setActionCommand("some cell identifier");
        btn.addActionListener(actionListener); // make a listener to the button
        f.add(btn);
    }

}

您可以...

创建一个自定义ActionListener,它将接收所需的信息,以便可以更好地决定要做什么(并将其与按钮本身分离)

public class CardActionListener implements ActionListener {
    private int row, col;

    public CardActionListener(int row, int col) {
        this.row = row;
        this.col = col;
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // Do some work...
    }
}

//...

for (int i = 0; i <= 7; i++) {
    for (int j = 0; j <= 7; j++) {

        btn = new JButton();
        btn = new JButton(new SoliderW());
        btn.setName("btn" + i + "" + j);
        btn.setBackground(Color.BLACK);
        btn.addActionListener(new CardActionListener(i, j)); // make a listener to the button
        f.add(btn);
    }

}

您可以...

我的个人喜好,请使用Action API

这类似于上一个建议,但是创建了一个更加独立的工作单元,该单元与调用者分离了。

Action

重要的是...

我正在尝试的事情之一就是将动作功能与按钮本身分离,因此动作不依赖于按钮,而是提供了执行动作所需的信息。

这是“模型-视图-控制器”的核心概念,它将使您的代码更易于维护


1
投票

您也可以在侦听器中执行此操作:

public class CardAction extends AbstractAction {
    private int row, col;

    public CardAction(int row, int col) {
        this.row = row;
        this.col = col;
        putValue(Action.LARGE_ICON_KEY, new SoliderW());
    }

    @Override
    public void actionPerformed(ActionEvent evt) {
        // Do some work...
    }

}

//...

for (int i = 0; i <= 7; i++) {
    for (int j = 0; j <= 7; j++) {

        btn = new JButton(new CardAction(i, j));
        f.add(btn);
    }

}

但是最好将所有按钮放在ArrayList中,然后只使用Object src = e.getSource(); if ( src instanceof JButton ) { System.out.println( "Button is: " + ((JButton)src).getName() ); }


0
投票

int index = list.indexOf(src);建议的实现MVC Pattern可以如下进行:有一个MadProgrammer类,其中包含视图(gui)所需的所有信息。有一个Model类,使用该模型来显示gui。有一个View类可以控制模型和视图。

以下Controller演示了如何使用MVC模式来实现所需的功能。为了方便和简单起见,可以将以下代码复制粘贴到一个名为mre的文件中并运行:

Main.java
© www.soinside.com 2019 - 2024. All rights reserved.