Débuter avec les EventListener
Bonsoir,
Je bataille quelque peu sur les interfaces graphiques sous NetBeans 6.
Mon souhait est de mieux maitriser tout ce qui touche aux évènements, aussi j'ai pris en main sans trop de difficulté les évènements liés à l'action d'un utilisateur sur l'interface (ActionEvent) étant donné que NetBeans se charge de presque tout générer.
Par contre j'ai plus de difficultés à maitriser les évènements de émis par une classe et écoutés par l'interface. Je me suis donc référé à ce tutoriel, mais je ne parviens à faire fonctionner cela correctement sur mon exemple.
Mon exemple se compose de deux classes, dont la structure est généré par NetBeans lorsque l'on créée une classe d'interface. En somme je dispose d'une classe principale et d'une UI.
L'UI dispose de 2 boutons et de 1 label.
Si on clic sur le premier bouton, j'affiche un message en ligne de commande.
Si on clic sur le second bouton, je souhaite lancer des évènements qui vont modifier le texte du label.
Voici donc ma classe principale qui va se charger d'afficher l'interface.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
/*
* Essais_GUIApp.java
*/
package essais_gui;
import org.jdesktop.application.Application;
import org.jdesktop.application.SingleFrameApplication;
/**
* The main class of the application.
*/
public class Essais_GUIApp extends SingleFrameApplication {
/**
* At startup create and show the main frame of the application.
*/
@Override protected void startup() {
show(new Essais_GUIView(this));
}
/**
* This method is to initialize the specified window by injecting resources.
* Windows shown in our application come fully initialized from the GUI
* builder, so this additional configuration is not needed.
*/
@Override protected void configureWindow(java.awt.Window root) {
}
/**
* A convenient static getter for the application instance.
* @return the instance of Essais_GUIApp
*/
public static Essais_GUIApp getApplication() {
return Application.getInstance(Essais_GUIApp.class);
}
/**
* Main method launching the application.
*/
public static void main(String[] args) {
launch(Essais_GUIApp.class, args);
}
} |
Et voici maintenant ma classe d'interface :
(J'ai omis du code généré par NetBeans : initialisation de composants, etc.)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
|
/*
* Essais_GUIView.java
*/
package essais_gui;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventListener;
import javax.swing.event.EventListenerList;
/**
* The application's main frame.
*/
public class Essais_GUIView extends FrameView
{
public Essais_GUIView(SingleFrameApplication app)
{
super(app);
initComponents();
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
private void initComponents()
{
[...]
bouton_1 = new javax.swing.JButton();
bouton_1.setText(resourceMap.getString("bouton_1.text"));
bouton_1.setName("bouton_1"); // NOI18N
bouton_1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bouton_1_ActionPerformed(evt);
}
});
bouton_2 = new javax.swing.JButton();
bouton_2.setText(resourceMap.getString("bouton_2.text"));
bouton_2.setName("bouton_2"); // NOI18N
bouton_2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bouton_2_ActionPerformed(evt);
}
});
mon_label = new javax.swing.JLabel();
mon_label.setText(resourceMap.getString("mon_label.text"));
mon_label.setName("mon_label");
[...]
}
private void bouton_1_ActionPerformed(java.awt.event.ActionEvent evt)
{
System.out.println("bouton cliqué");
}
// Un seul objet pour tous les types d'écouteurs
private final EventListenerList listeners = new EventListenerList();
public interface IndiceListener extends EventListener
{
void IndiceChanged(int nouvelIndice);
}
public void addIndiceListener(IndiceListener listener)
{
listeners.add(IndiceListener.class, listener);
}
public void removeIndiceListener(IndiceListener listener)
{
listeners.remove(IndiceListener.class, listener);
}
public IndiceListener[] getIndiceListeners() {
return listeners.getListeners(IndiceListener.class);
}
protected void fireIndiceChanged(int nouvelIndice)
{
for(IndiceListener listener : getIndiceListeners())
{
listener.IndiceChanged(nouvelIndice);
}
}
private void bouton_2_ActionPerformed(java.awt.event.ActionEvent evt)
{
for(int i=1; i<=10; i++)
{
System.out.println("---> " + i);
fireIndiceChanged(i);
/*
try
{
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
*/
}
}
// Variables declaration - do not modify
[...]
} |
Normalement un clic sur le second bouton déclenche ici une série de 10 évènements successifs. (J'ai bien mes println).
Pourriez-vous, s'il vous plait, m'aider à ajuster ma gestion d'évènements pour que chaque émission de IndiceChanged écrive la nouvelle valeur de l'indice dans le label ? (private javax.swing.JLabel mon_label;)
Dans le même ordre d'idée, le tutoriel recommande d'utiliser une classe abstraite appelée "adapter", qui implémente le listener et qui définit toutes ses méthodes avec un corps vide. Cela permettrait de lever des événements sans redéfinir toutes les méthodes, si une seule nous intéresse... Mais une fois encore je bloque un peu. Cela fonctionnera probablement mieux lorsque je maitriserai correctement mes Listeners :)
Enfin, une fois que je maitriserai mieux cela je m'intéresserai aux problème de freeze de l'interface (ici ca freeze si je fais par exemple 10000 tours de boucle avec une pause de 1s. à chaque tour).