Имея различное действие для каждой кнопки, динамически созданного в цикле
-
19-09-2019 - |
Вопрос
Используйте этот сайт много, но впервые публикуя. Моя программа создает несколько кнопок в зависимости от количества записей в файле. Например, 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();
}
});
}
}
}