【问题标题】:Best practice for setting onclickListener for buttons on an array buttons为数组按钮上的按钮设置 onclickListener 的最佳实践
【发布时间】:2012-12-19 20:49:24
【问题描述】:

我有一个类Game 和一组按钮buts,我想在单击任何按钮[i][j] 时调用游戏类fun(i,j) 上的函数,我试过这样:

buts = new JButton[Setting.length][Setting.width];
    Game game = new Game(setting);
    int hgap = 4, vgap = 4;
    panel = new JPanel(new GridLayout(Setting.length, Setting.width, hgap, vgap));
for (int i = 0; i < Setting.length; i++) {
            for (int j = 0; j < Setting.width; j++) {
                //JButton btn = new JButton();
                buts[i][j] = new JButton();
                buts[i][j].setText(String.valueOf(j));
                setColor(buts[i][j], Game.cells[i][j].getColor());
                buts[i][j].addActionListener(new java.awt.event.ActionListener() {

                    @Override
                    public void actionPerformed(java.awt.event.ActionEvent evt) {
                        buttonActionPerformed(evt);
                    }
                });
                panel.add(buts[i][j]);
            }
        }
    private void buttonActionPerformed(ActionEvent evt) {

    }

但是我怎样才能将 i,j 发送到函数 buttonActionPerformed

【问题讨论】:

    标签: java arrays swing jbutton actionlistener


    【解决方案1】:

    您可以为每个JButton 使用具体的Action,并将值ij 传递到类的构造函数中。

    添加:

    buts[i][j].setAction(new MyAction(i, j));
    

    Action 实现:

    class MyAction extends AbstractAction {
       private final int iValue;
       private final int jValue;
    
       public MyAction(int i, int j) {
          this.iValue = i;
          this.jValue = j;
       }
    
       @Override    
       public void actionPerformed(ActionEvent e) {
          buttonActionPerformed(e, iValue, jValue);
       }
    }
    

    还有:

    private void buttonActionPerformed(ActionEvent evt, int i, int j) {
       // ...
    }
    

    【讨论】:

      【解决方案2】:
      class MyActionListener implemments ActionListener{
      
           private final int i;
           private final int j;
           MyActionListener (int i, int j){
                this.i = i;
                this.j = j;
           }
      }
      
      buts[i][j].addActionListener(new MyActionListener(i,j) {
             public void actionPerformed(java.awt.event.ActionEvent evt) {
                          buttonActionPerformed(evt,this.i,this.j);
             }
      });
      
      private void buttonActionPerformed(ActionEvent evt,int i,int j) {
      
      }
      

      【讨论】:

        【解决方案3】:

        有几种选择:

        • 您可以将事件源(ActionEvent#getSource())与数组中的按钮进行比较,并检索ij。缺点是你不断循环遍历数组
        • 您可以按照其他答案中的建议将ij 传递给ActionActionListener
        • 您可以使用JComponent#putClientPropertyJComponent#getClientProperty 方法将ij 存储在JButton 中。可以使用ActionEvent#getSource 方法访问JButton

        【讨论】:

          【解决方案4】:

          我最喜欢的做法是将 actionListener 设置为一个函数,并将 i 和 j 声明为 final。所以你应该像这样设置你的按钮:

              for (int i = 0; i < Setting.length; i++) {
                  for (int j = 0; j < Setting.width; j++) {
                      //JButton btn = new JButton();
                      buts[i][j] = new JButton();
                      buts[i][j].setText(String.valueOf(j));
                      setColor(buts[i][j], Game.cells[i][j].getColor());
                      setButtonAction(buts[i][j], i, j);
                      panel.add(buts[i][j]);
                  }
              }
          

          并像这样声明方法setButtonAction

          public void setButtonAction(JButton button, final int i, final int j){
              button.addActionListener(new java.awt.event.ActionListener() {
          
                  @Override
                  public void actionPerformed(java.awt.event.ActionEvent evt) {
                      fun(i,j);
                  }
              });
          }
          

          您也可以在没有额外方法的情况下完成所有这些操作,但是您必须声明一些 final int 变量并将 i 和 j 的值传递给 final... 它看起来很丑。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多