وجود عمل مختلف لكل زر تم إنشاؤه ديناميكيا في حلقة

StackOverflow https://stackoverflow.com/questions/2430008

سؤال

استخدم هذا الموقع كثيرا ولكن أول مرة ينشر. يقوم برنامجي بإنشاء عدد من الأزرار اعتمادا على عدد السجلات في ملف. على سبيل المثال 5 سجلات، 5 أزرار.

يتم إنشاء الأزرار ولكن أواجه مشكلة في مستمع العمل.

إذا أضف المستمع الإجراء في الحلقة، كل زر يفعل نفس الشيء؛ ولكن إذا قمت بإضافة مستمع الإجراء خارج الحلقة، فما عليك سوى إضافة مستمع الإجراء إلى زر آخر.

أيه أفكار؟

هنا ما لدي كود-الحكمة (لقد أضفت للتو لحلقة لحلقة لتوفير المساحة):

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

مقدر جدا

هل كانت مفيدة؟

المحلول

كما تقوم بإنشاء مستمع عمل واحد لكل زر تقوم بإنشائه، فقد يكون لديك هذا:

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

للوصول إلى متغير داخل طريقة فئة مجهولة، يجب أن تكون ملحوظة نهائية. هذا ما لديك ذلك final int buttonIndex = i; بيان.

يمكنك استعمال ال setActionCommand الطريقة الموجودة على الزر لتحديد أمر إجراء لذلك يمكنك استرداد من ActionCommand. خاصية ActionEvent صف دراسي. من خلال القيام بذلك، قد يكون لديك نفس المستمع لجميع الأزرار الخاصة بك. يمكنك تعيين الأمر هذا الإجراء إلى buttonIndex متغير الذي حددته في مثالك. من خلال القيام بذلك، تقوم بإنشاء فئة أقل هوية في التطبيق الخاص بك، وهي جيدة دائما (أشياء أقل تستهلك ذاكرة أقل).

نصائح أخرى

يمكنك إضافة المرجع الزر والفهرس (i) من كل زر إلى خريطة التجزئة كما كنت تخلقها.

في مستمع العمل الخاص بك، يمكنك البحث عن فهرس الزر الذي مصادر الحدث في HASHMAP الخاص بك بواسطة مرجع الزر.

شيء من هذا القبيل (رمز الزائفة، لذلك الثابتة والمتنقلة لا ترسم لي إذا لم يترجم):

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 it's index
            Integer index = map.get( ae2.getSource() );

            // Do something different here based upon index
        }
    });
    j++;
}

لماذا لا تقوم بإعداد ActionListeners خارج الحلقة وإنشاء مجموعة منهم، حيث يتوافق فهرس 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]);
}

تحذير رغم ذلك، لم أختبر هذا الرمز.

مشكلتك الأولى موجودة مع الاعتماد على المتغير j.

أنت تقوم بتعيين جميع الأزرار نفس ActionListener بالضبط، والتي من شأنها طباعة الكائن في الفهرس j, ، والتي يتم عرض الأزرار في ذلك الوقت == الفهرس الأخير للقائمة في وقت الزيادات، القائمة namesA.

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();
                }
                });
               }
            }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top