Dans le cadre du développement d’une application pour un client, je me suis trouvée confrontée à pouvoir afficher durant l’exécution d’un code composé de plusieurs étapes, l’état de chaque étape.
De base, un JFrame n’est rafraîchi qu’à la fin de l’exécution d’un évènement.
Pour pouvoir suivre le déroulement d’un processus où l’on modifie au fur et à mesure de l’exécution les états et les contenus des objets internes au JFrame, il est nécessaire d’utiliser un « Worker Swing ». Ce processus s’exécute en tâche de fond et va permettre le rafraîchissement à la volée du JFrame le contenant.
L’implémentation du Worker se fait ainsi :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class IhmTest extends JFrame { ... private void initEvenements() { executerLeReste.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>(){ @Override protected Void doInBackground() throws Exception{ ... return null; } }; worker.execute(); } }); } } |
Dans l’ActionListener, le Swing Worker encadre l’ensemble des phases d’exécution du code. A chaque modification d’un objet du JFrame celui-ci se trouve rafraîchi. Il est de fait possible de suivre en temps réel la progression d’exécution du processus développé.
Exemple de code complet :
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 | import javax.swing.*; import java.awt.event.*; class IhmTest extends JFrame { private static final long serialVersionUID = 1L; private JButton phaseExecution1 = new JButton(); private JButton phaseExecution2 = new JButton(); private JButton executerLeReste = new JButton(); public IhmTest() { setTitle("Phases d'exécution"); setSize(800,800); setLayout(null); setResizable(true); initComposants(); initEvenements(); } private void initComposants() { int xb = 10; int y = 10; int h = 20; int lb = 350; int ll = 100; int le = 300; int xl = xb + lb + 10; int xe = xl + ll + 10; String aExecuter = "à exécuter"; phaseExecution1.setBounds(xb,y,lb,h); phaseExecution1.setText("Exécution Phase 1"); add(phaseExecution1); executerLeReste.setBounds(xe,y,le,h); executerLeReste.setText("Tout exécuter à partir de cette séquence"); add(executerLeReste); y += h; phaseExecution2.setBounds(xb,y,lb,h); phaseExecution2.setText("Exécution Phase 2"); phaseExecution2.setEnabled(false); add(phaseExecution2); y += h; } private void initEvenements() { phaseExecution1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { phaseExecution1.setEnabled(false); phaseExecution2.setEnabled(true); executerLeReste.setLocation(executerLeReste.getX(),executerLeReste.getY() + 20); } }); phaseExecution2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { phaseExecution2.setEnabled(false); executerLeReste.setLocation(executerLeReste.getX(),executerLeReste.getY() + 20); executerLeReste.setVisible(false); } }); executerLeReste.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>(){ @Override protected Void doInBackground() throws Exception{ executerLeReste.setVisible(false); executerLeReste.setText("Exécution automatique"); if(phaseExecution1.isEnabled()) { try { Thread.sleep(1000); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } phaseExecution1.setEnabled(false); phaseExecution2.setEnabled(true); } if(phaseExecution2.isEnabled()) { try { Thread.sleep(1000); } catch (InterruptedException e1) { e1.printStackTrace(); } phaseExecution2.setEnabled(false); executerLeReste.setVisible(false); } } return null; } }; |