【问题标题】:Having a different action for each button dynamically created in a loop在循环中动态创建的每个按钮都有不同的操作
【发布时间】:2010-03-12 01:55:23
【问题描述】:

经常使用这个网站,但第一次发帖。 我的程序根据文件中的记录数创建许多按钮。 例如。 5 条记录,5 个按钮。

正在创建按钮,但我遇到了动作监听器问题。

如果在循环中添加动作监听器,每个按钮都会做同样的事情;但是如果我在循环之外添加动作监听器,它只会将动作监听器添加到最后一个按钮。

有什么想法吗?

这是我的代码(我刚刚添加了 for 循环以节省空间):

int j=0;
for(int i=0; i<namesA.size(); i++)
{
    b = new JButton(""+namesA.get(i)+"");
    conPanel.add(b);
    conFrame.add(conPanel);

    b.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent ae2){

                System.out.println(namesA.get(j));

        }
    }});
    j++;
}

非常感谢

【问题讨论】:

    标签: java for-loop jbutton actionlistener


    【解决方案1】:

    当您为正在创建的每个按钮创建一个动作侦听器时,您可以这样:

    final int buttonIndex = i;
    b.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent ae2) {
           System.out.println("Button pressed is: " + buttonIndex);
       }
    }
    

    要访问匿名类方法中的变量,必须将其标记为 final。这就是你的final int buttonIndex = i; 声明。

    您可以使用按钮上的setActionCommand 方法为其定义一个操作命令,您可以从ActionEvent 类的actionCommand 属性中检索该操作命令。通过这样做,您可以为所有按钮使用相同的侦听器。您可以将该操作命令设置为我在您的示例中定义的 buttonIndex 变量。通过这样做,您可以在应用程序中创建更少的匿名类,这总是好的(更少的对象消耗更少的内存)。

    【讨论】:

      【解决方案2】:

      您可以在创建它们时将每个按钮的按钮引用和索引 (i) 添加到哈希映射中。

      在您的单一动作侦听器中,您可以通过按钮引用在哈希图中查找引发事件的按钮的索引。

      类似这样的东西(伪代码,所以如果它不能编译,请不要拒绝我):

      Hashmap<JButton, Integer> map = new Hashmap<JButton, Integer>();
      
      int j=0;
      for (int i = 0; i < namesA.size(); i++)
      {
          b = new JButton("" + namesA.get(i) + "");
          conPanel.add(b);
          conFrame.add(conPanel);
      
          // Add a mapping
          map.add(b, new Integer(i));
      
          b.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent ae2) {
                  // Look up the button in the map, and get its index
                  Integer index = map.get( ae2.getSource() );
      
                  // Do something different here based upon index
              }
          });
          j++;
      }
      

      【讨论】:

        【解决方案3】:

        为什么不在循环之外设置您的 ActionListener 并创建一个数组,其中您的 listeners 数组中的 actionListener 的索引对应于它被添加到的按钮。像这样的:

        ActionAdapter[] listeners = new ActionAdapter[namesA.size()];
        //fill listeners with ActionAdapters
        listeners[0] = new ActionAdapter() 
        {
            public void actionPerformed(ActionEvent e) {
                //Do stuff
            }
        };
        //Repeat for each button you need
        
        for(int i = 0; i < namesA.size(); i++)
        {
            b = new JButton("" + namesA.get(i) + "");
            conPanel.add(b);
            b.addActionListener(listeners[i]);
        }
        

        警告,我还没有测试过这段代码。

        【讨论】:

        • 太好了。谢谢,但我仍然无法提交听众,因为不知道需要多少按钮......可能是 5.. 可能是 100
        【解决方案4】:

        您的第一个问题在于对变量j 的依赖。

        您正在为所有按钮分配完全相同的 ActionListener,这将打印出索引 j 处的对象,在显示按钮时 == 时列表的最后一个索引增量,列表namesA

        【讨论】:

          【解决方案5】:
          public class Scroll_view extends Activity {
          
          Button btn;
          Button btn1;
          
              @Override
              public void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_scroll_view);
          
          
          
                  LinearLayout linear=(LinearLayout)findViewById(R.id.linear);
                  for(int i=1; i<=20 ;i++){
                      LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT);
                      btn=new Button(this);
                      btn.setId(i);
                      final int id_=btn.getId();
                      btn.setText("button " + id_);
                      linear.addView(btn,params);
          
          
                      btn1=((Button)findViewById(id_));
                      btn1.setOnClickListener(new View.OnClickListener(){         
                          public void onClick(View view){
                              Toast.makeText(view.getContext() , "Button clicked index = " + id_ , Toast.LENGTH_SHORT).show();
                          }
                          });
                         }
                      }
          }
          

          【讨论】:

          • 这个 (android) 答案与 op 有什么关系,谁没有要求 android 解决方案?
          猜你喜欢
          • 2013-10-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多