Le plus simple est d'utiliser un timer, instance de la classe javax.swing.Timer. Un timer sert à provoquer des actions à intervalles réguliers. Ces actions sont provoquées par l'intermédiaire d'instances de la classe ActionEvent engendrées par le timer. Il faut associer au timer un ou plusieurs listeners de type ActionListener qui ont pour tâche d'effectuer les actions à la réception des ActionEvent ; on fournit aussi au timer le délai qui doit séparer deux actions successives. Les actions sont traitées par le gestionnaire d'événements (event-dispatching thread). On doit démarrer le timer avec la méthode start ; on peut choisir le temps écoulé avant le premier appel du timer par la méthode setInitialDelay(int t); on peut choisir que le timer ne fasse qu'un seul appel par la méthode setRepeats(boolean b) ; on peut arrêter le timer avec la méthode stop. On peut faire repartir le timer avec la méthode restart.
Du fait que les actions demandées par le timer sont prises en charge par le gestionnaire d'événements, il ne serait pas judicieux, dans une interface graphique un peu complexe, de faire par l'intermédiaire du timer des actions consommatrices de beaucoup de temps car cela empêcherait la gestion correcte des autres événements. Pour une action « lourde », il faut envisager de définir un nouveau thread pour exécuter celle-ci.
Dans notre programme, on peut remarquer que nous avons ajouté deux ActionListener à chacun des boutons ; l'un (défini par la classe Ardoise) s'occupe de gérer, selon le cas, l'arrêt ou le redémarrage de l'animation, l'autre (défini par la classe Anneaux) s'occupe de rendre les boutons disponibles ou non.
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; class Ardoise extends JPanel implements ActionListener { private static final long serialVersionUID = 1L; private int dep = 0; private Timer declencheur; private int largeur = 200, hauteur = 200; Ardoise() { setPreferredSize(new Dimension(largeur, hauteur)); setBackground(Color.WHITE); declencheur = new Timer(100, this); declencheur.start(); } public void actionPerformed(ActionEvent e) { if (e.getSource() == declencheur) { repaint(); dep = (dep - 1) % 10; } else { String commande = e.getActionCommand(); if (commande.equals("arreter")) declencheur.stop(); else if(commande.equals("reprendre")) declencheur.restart(); } } public void paintComponent(Graphics g) { super.paintComponent(g); for (int i = dep - 5; i < largeur/2; i += 10) { for (int j = i; j < i + 5; j++) if (j > 0) g.drawOval(j, j, largeur - 2*j, hauteur - 2*j); } } } class IHMAnneaux extends JPanel implements ActionListener { private static final long serialVersionUID = 1L; Ardoise ardoise = new Ardoise(); JButton arret = new JButton("arret"); JButton reprise = new JButton("reprendre"); IHMAnneaux() { arret.setActionCommand("arreter"); arret.addActionListener(ardoise); arret.addActionListener(this); reprise.setActionCommand("reprendre"); reprise.addActionListener(ardoise); reprise.addActionListener(this); reprise.setEnabled(false); JPanel boutons = new JPanel(); boutons.setBackground(Color.WHITE); boutons.add(arret); boutons.add(reprise); setLayout(new BorderLayout()); add(boutons, BorderLayout.NORTH); add(ardoise, BorderLayout.CENTER); setBackground(Color.WHITE); } public void actionPerformed(ActionEvent e) { String commande = e.getActionCommand(); if (commande.equals("arreter")) { arret.setEnabled(false); reprise.setEnabled(true); } else if (commande.equals("reprendre")){ arret.setEnabled(true); reprise.setEnabled(false); } } } class Anneaux { public static void main(String[] arg) { JFrame fenetre = new JFrame(); fenetre.setContentPane(new IHMAnneaux()); fenetre.pack(); fenetre.setLocation(100, 100); fenetre.setVisible(true); fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
© Irène Charon, Télécom ParisTech 2011