2014-04-16 2 views
-1

J'écris un programme pour calculer GPA. Il se compose de plusieurs panneaux. Le premier panneau indique à l'utilisateur de spécifier le nombre de cours afin que Comboboxes (gradeCombo), (hourCombo) et Textfields soient ajoutés dynamiquement au deuxième panneau. Tout va bien à ce point mais le problème est avec les auditeurs. Dans les premiers stades, j'ai enregistré les écouteurs d'événement pour ces comboboxes individuellement pour chaque élément dans le tableau et il a abouti à 900 lignes de codes, mais cela a bien fonctionné et tous mes résultats étaient corrects. Pour améliorer mon code, j'essaye d'écrire une boucle for pour enregistrer les événements pour les comboboxes et jusqu'ici je n'ai pas réussi.Comment ajouter ItemListeners dynamiquement?

J'ai essayé d'écrire le code de gestion en tant que classe interne anonyme et comme classe interne séparée, voici mon dernier essai:

for(i = 0; i<courseN;i++) 
      { 
       hourCombo[i].addItemListener(new HoursHandler()); 
       gradeCombo[i].addItemListener(new GradeHandler()); 
      } 


public class HoursHandler implements ItemListener 
{ 
     public void itemStateChanged(ItemEvent event) 
     { 
      if(event.getStateChange()==ItemEvent.SELECTED) 
      { 
       String hour; 
       hour = (String) hourCombo[i].getSelectedItem(); 
       currentHour[i]=Integer.parseInt(hour); 
       aquiredHours=aquiredHours+currentHour[i] prevHour[i]; 
       prevHour[i]=currentHour[i]; 
      } 
     } 
} 


public class GradeHandler implements ItemListener 
{ 
     public void itemStateChanged(ItemEvent event) 
     { 
      if(event.getStateChange()==ItemEvent.SELECTED) 
      { 
      String grade; 
      grade=(String) gradeCombo[i].getSelectedItem(); 

      switch(grade) 
      { 
      case "A+": 
       currentPoint[i]=5*currentHour[i]; 

       break; 
      case "A": 
       currentPoint[i]= 4.75 * currentHour[i]; 
       break; 
      case "B+": 
       currentPoint[i]= 4.5 * currentHour[i]; 
       break; 
      case "B": 
       currentPoint[i]= 4 * currentHour[i]; 
       break; 
      case "C+": 
       currentPoint[i]= 3.5 * currentHour[i]; 
       break; 
      case "C": 
       currentPoint[i]= 3 * currentHour[i]; 
       break; 
      case "D+": 
       currentPoint[i]= 2.5 * currentHour[i]; 
       break; 
      case "D": 
       currentPoint[i]= 2 * currentHour[i]; 
       break; 
      case "F": 
       currentPoint[i]= 1 * currentHour[i]; 
       break; 
     } 
      aquiredPoints=aquiredPoints+currentPoint[i]-prevPoint[i]; 
      prevPoint[i]=currentPoint[i]; 
     } 
     } 
} 

Je reçois un NullPointerException pour cette déclaration:

    hour = (String) hourCombo[i].getSelectedItem(); 

et tout va mal, aucune de mes variables n'est mise à jour et je ne peux pas calculer le GPA ..

Répondre

1

Il est difficile de dire à partir du code affiché ce qui ne va pas. Cependant, je suppose que i est déclaré en tant que variable d'instance. Dans ce cas, la boucle for(i = 0; i<courseN;i++) va changer la valeur de cette variable d'instance. Par la suite, tous les les écouteurs utilisent en interne i avec la dernière valeur qu'il a reçue dans le for -loop. Pour contourner ceci, vous pouvez déclarer une variable d'instance pour chaque instance d'écouteur. Ainsi, vous pouvez changer vos cours d'écoute comme ceci:

public class HoursHandler implements ItemListener 
{ 
    private final int index; 

    HoursHandler(int index) 
    { 
     this.index = index; 
    } 

    @Override 
    public void itemStateChanged(ItemEvent event) 
    { 
     // Use the "index" here: 

     String hour = (String) hourCombo[index].getSelectedItem(); 
     currentHour[index]=Integer.parseInt(hour);  
     ... 
    } 
} 

(de même, d'introduire un tel indice pour la GradeHandler).

Ensuite, lorsque vous créez les auditeurs, vous pouvez passer à chaque fois l'indice qu'il se réfère à:

// Note: "i" is declared here, and should NO longer 
// be an instance variable! 
for(int i = 0; i<courseN;i++) 
{ 
    hourCombo[i].addItemListener(new HoursHandler(i)); // Use "i" as "index" 
    gradeCombo[i].addItemListener(new GradeHandler(i)); // Use "i" as "index" 
} 

Je suppose qu'il pourrait y avoir des solutions plus élégantes, mais c'est un possible solution, basée uniquement sur le code que vous avez fourni.

+0

Merci beaucoup pour votre aide. J'ai le problème que j'ai créé maintenant. – user3458260

0

Il semble que i soit un champ membre de votre classe externe. Lorsque votre auditeur est exécuté, et votre auditeur

hour = (String) hourCombo[i].getSelectedItem(); 

cette déclaration utilisera toute valeur i se trouve être dans cette classe externe. Et après avoir exécuté votre boucle for, i sera probablement égal à courseN, à moins qu'il y ait quelque chose d'autre qui le change ailleurs. Dans tous les cas, il n'utilise pas la valeur que i contenait lorsque vous avez configuré l'écouteur, car vous n'avez rien fait pour lui dire d'utiliser cette valeur.

Une façon simple de résoudre ce problème est de construire vos auditeurs en lui donnant l'index que vous voulez utiliser:

public class HoursHandler implements ItemListener 
{ 
    private final int index; 
    public HoursHandler(int index) { 
     this.index = index; 
    } 
    public void itemStateChanged(ItemEvent event) 
    { 
     if(event.getStateChange()==ItemEvent.SELECTED) 
     { 
      String hour; 
      hour = (String) hourCombo[index].getSelectedItem(); 

et utiliser index au lieu de i partout dans l'auditeur.Lorsque vous construisez l'écouteur, il va stocker l'index que vous voulez, et le code l'utilisera à la place de la valeur actuelle de i. De même pour GradeHandler. Puis

for(i = 0; i<courseN;i++) 
     { 
      hourCombo[i].addItemListener(new HoursHandler(i)); 
      gradeCombo[i].addItemListener(new GradeHandler(i)); 
     } 

Notez que l'index que vous souhaitez que les écouteurs utilisent est maintenant transmis en tant que paramètre aux constructeurs des écouteurs.

EDITED pour utiliser final sur l'index membre - plagié à partir de la bonne idée de Marco13.

+0

Merci beaucoup pour la réponse détaillée. J'ai maintenant une idée claire de mon problème. – user3458260