Ayant une action différente pour chaque bouton créé dynamiquement dans une boucle
-
19-09-2019 - |
Question
utiliser ce site beaucoup, mais la première affectation de temps. Mon programme crée un certain nombre de boutons en fonction du nombre d'enregistrements dans un fichier. Par exemple. 5 disques, 5 boutons.
Les boutons sont créés, mais je suis un problème avec l'auditeur d'action.
Si ajouter l'écouteur d'action dans la boucle chaque bouton fait la même chose; mais si j'ajoute l'auditeur d'action en dehors de la boucle, il ajoute que l'écouteur d'action dernier bouton.
Toutes les idées?
Voici ce que j'ai-sage code (je viens d'ajouter la boucle pour économiser l'espace):
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++;
}
PRÉCIEUSE
La solution
Comme vous créez une seule action d'écoute pour chaque bouton que vous créez, vous pourriez avoir ceci:
final int buttonIndex = i;
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae2) {
System.out.println("Button pressed is: " + buttonIndex);
}
}
Pour accéder à une variable à l'intérieur d'une méthode de classe anonyme, il doit être marqué finale. C'est ce que vous avez cette déclaration de final int buttonIndex = i;
.
Vous pouvez utiliser la méthode setActionCommand
sur le bouton pour définir une commande d'action à ce que vous pouvez récupérer à partir de ActionCommand propriété de la classe ActionEvent
. En faisant cela, vous pourriez avoir le même écouteur pour tous vos boutons. Vous pouvez définir cette commande d'action à la variable buttonIndex
que je défini dans votre exemple. En faisant cela, vous créez moins classe anonyme dans votre application, ce qui est toujours bon (moins d'objets consommant moins de mémoire).
Autres conseils
Vous pouvez ajouter la référence bouton et l'index (i
) de chaque bouton à une carte de hachage comme vous les créer.
Dans votre un auditeur d'action, vous pouvez consulter l'index du bouton qui provient l'événement dans votre hashmap par sa référence bouton.
Quelque chose comme ça (pseudo code, pls ne me downvote si elle ne compile pas):
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++;
}
Pourquoi ne pas configurer vos ActionListeners en dehors de la boucle et faire un tableau d'entre eux, où l'indice de la actionListener dans votre tableau auditeurs correspond à quel bouton il est ajouté à. Quelque chose comme ceci:
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]);
}
Attention cependant, je n'ai pas testé ce code.
Votre premier problème réside dans le recours à j
variable.
Vous assignez tous les boutons même de ActionListener exacte, qui imprimerait sur l'objet à l'index j
, qui, au moment où les boutons sont affichés est == le dernier index de la liste au moment des incréments, Liste des 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();
}
});
}
}
}