IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

Comment faire pour ne pas bloquer l'EDT?


Sujet :

AWT/Swing Java

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 152
    Points : 81
    Points
    81
    Par défaut Comment faire pour ne pas bloquer l'EDT?
    Bonjour,
    Voilà cela fait quelques jours que je galère. J'ai lu pas mal de tuto sur le swing et je n'ai tjrs pas résolu mon problème.
    Dans mon programme, j'ai une méthode que fait un peu de calcul (un peu long) et je voudrais pendant ce temps que mon IHM ne soit pas bloquée.
    Voilà un schémas simplifié du programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    final JButton button1 = new JButton("Longue opération de calcul");
    	button1.addActionListener(new ActionListener() {
    	public void actionPerformed(ActionEvent e) {
     
    	new Thread(new Runnable() {
    			public void run() {
    				longueOperation();
    				SwingUtilities.invokeLater(new Runnable() {
    					public void run() {
    						button1.setVisible(true);							
    					}
    				});
    			 }
    	}).start();
     
       }
     });
    et puis la méthode qui simule un calcul long est une vulgaire boucle for :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void longueOperation() {
     
    	  for (int i=0;i<500;i++)
    		{
    	 	for (int j=0;j<500;j++)
    		{
    			for (int k=0;k<5000;k++)
    			{
    			}	
    		}
    		Thread.yield();				
    		}	
     
    	}
    S'il vous plait comment je dois faire pour que pendant que je suis dans la méthode calcul mon interface continue à réponde au click de la souris.
    Je vous remercie par avance.

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Février 2005
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 119
    Points : 192
    Points
    192
    Par défaut
    Bonjour,

    Ceci devrait t'aider : http://rom.developpez.com//java-swingworker/.

    Bon courage.

  3. #3
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    salut,

    j'ai du mal à comprendre ton souci: ton code me semble bon : tu créées bien un nouveau thread pour ta longue opération, laissant ainsi l'EDT terminer rapidement l'exécution de actionPerformed pour passer à autre chose ensuite.

    Ca m'a tellement intrigué que j'ai fait un test basique avec un copier/coller de ton code dans une desktop application "toute faite" via NetBeans 6.7 et tout fonctionnait à merveille et la GUI restait parfaitement utilisable.

    Es-tu certain que le souci ne vient pas d'une autre partie de ton code (typiquement le contenu de ta 'longue operation') ?


    PS: Au passage, le thread.yield() serait même un peu superflu : si c'est pour laisser la priorité au reste de ton appli, tu peux également baisser la priorité de ton thread de calcul par rapport aux autres threads.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  4. #4
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 152
    Points : 81
    Points
    81
    Par défaut
    Citation Envoyé par gulain Voir le message
    Bonjour,

    Ceci devrait t'aider : http://rom.developpez.com//java-swingworker/.

    Bon courage.
    Merci pour ta réponse rapide mais je ne peux utiliser swingworker car mon appli tourne 1.4

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 152
    Points : 81
    Points
    81
    Par défaut
    Citation Envoyé par nouknouk Voir le message
    salut,

    j'ai du mal à comprendre ton souci: ton code me semble bon : tu créées bien un nouveau thread pour ta longue opération, laissant ainsi l'EDT terminer rapidement l'exécution de actionPerformed pour passer à autre chose ensuite.

    Ca m'a tellement intrigué que j'ai fait un test basique avec un copier/coller de ton code dans une desktop application "toute faite" via NetBeans 6.7 et tout fonctionnait à merveille et la GUI restait parfaitement utilisable.

    Es-tu certain que le souci ne vient pas d'une autre partie de ton code (typiquement le contenu de ta 'longue operation') ?


    PS: Au passage, le thread.yield() serait même un peu superflu : si c'est pour laisser la priorité au reste de ton appli, tu peux également baisser la priorité de ton thread de calcul par rapport aux autres threads.

    Merci pour ta réponse voilà mon code complet :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
     
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JMenu;
    import javax.swing.JMenuBar;
    import javax.swing.JMenuItem;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.SwingConstants;
    import javax.swing.SwingUtilities;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.WindowConstants;
     
     
    public class DemoSwingWorker extends JFrame implements ActionListener {
     
    private static final long serialVersionUID = 1L;
     
    private final JLabel label = new JLabel(" ");
     
    /**
    * Constructeur par défaut.
    */
    public DemoSwingWorker() {
    super("Demo SwingWorker :: " + System.getProperty("java.vm.name") + " " + System.getProperty("java.vm.version"));
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    setJMenuBar(createMenuBar());
    getContentPane().add(createPanel());
    pack();
    setLocationRelativeTo(null);
    }
     
     
    /**
    * Action associé au menu : on affiche le texte sous l'îcone
    */
    public void actionPerformed(ActionEvent e) {
    this.label.setText(e.getActionCommand());
    }
     
    /**
    * Simulation d'un long calcul
    */
      void longueOperation() {
     
     long start = System.currentTimeMillis();
     
     for (int i=0;i<500;i++)
    {
    for (int j=0;j<500;j++)
    {
    for (int k=0;k<5000;k++)
    {
     
    }
    }
     
    }
      System.out.println("Le temps de calcul : " + (System.currentTimeMillis()- start) + " ms");
    }
     
     
     
    private JComponent createPanel() {
     
    /* Initialisation du label */
    this.label.setIcon(new ImageIcon(getClass().getResource(".//DukeTuxChristmas.gif")));
    this.label.setHorizontalTextPosition(SwingConstants.CENTER);
    this.label.setVerticalTextPosition(SwingConstants.BOTTOM);
     
     
    final JButton button1 = new JButton("Longue opération de calcul");
    button1.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
     
    new Thread(new Runnable() {
    public void run() {
    longueOperation();
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    button1.setVisible(true);
    }
    });
    }
    }).start();
     
    }
    });
     
     
     
    JPanel panel = new JPanel();
    panel.add(label);
    panel.add(button1);
    //panel.add(button2);
    JScrollPane scroll = new JScrollPane(panel);
    scroll.setBorder(null);
    return scroll;
     
    }
     
    public static void main(java.lang.String[] args) {
     
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    try {
     
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
    e.printStackTrace();
    }
     
    Toolkit.getDefaultToolkit().setDynamicLayout(true);
    new DemoSwingWorker().setVisible(true);
    }
    });
     
    }
     
    private JMenuBar createMenuBar() {
    JMenuBar menuBar = new JMenuBar();
     
    for (int i = 1; i < 5; i++) {
    JMenu menu = new JMenu("Menu " + i);
    menuBar.add(menu);
    for (int j = 1; j < 10; j++) {
    JMenu subMenu = new JMenu("Sous-Menu " + i + "-" + j);
    menu.add(subMenu);
    for (int k = 1; k < 10; k++) {
    JMenuItem item = new JMenuItem("Item " + i + "-" + j + "-" + k);
    item.addActionListener(this);
    subMenu.add(item);
    }
    }
    }
    return menuBar;
    }
     
    }

  6. #6
    Modérateur
    Avatar de nouknouk
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    1 655
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 655
    Points : 2 161
    Points
    2 161
    Par défaut
    Hem,

    j'ai fais un copier/coller de ton code, et j'ai commenté une ligne non importante pour que ça fonctionne (le "this.label.setIcon" dans la fonction createPanel, vu que j'ai pas l'image qui va bien).
    J'ai au passage allongé la durée du calcul (valeurs 500 remplacées par 1000) et ajouté un System.out.println dans la première boucle pour vérifier l'avancement.

    et ... ben ... toute marche parfaitement chez moi, la GUI reste parfaitement utilisable

    Une idée comme ça: ta machine de test est-elle un processeur mono ou dual core ? Si c'est un mono core, baisser la priorité du thread de calcul (cf. post précédent) fera peut-être la différence: ça évitera au thread de calcul de manger toutes les ressources et qu'il ne ralentisse trop fortement (même s'il ne le bloque pas) l'exécution de l'EDT.
    Mon projet du moment: BounceBox, un jeu multijoueurs sur Freebox, sur PC et depuis peu sur smartphone/tablette Android.

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 152
    Points : 81
    Points
    81
    Par défaut
    Citation Envoyé par nouknouk Voir le message
    Hem,

    j'ai fais un copier/coller de ton code, et j'ai commenté une ligne non importante pour que ça fonctionne (le "this.label.setIcon" dans la fonction createPanel, vu que j'ai pas l'image qui va bien).
    J'ai au passage allongé la durée du calcul (valeurs 500 remplacées par 1000) et ajouté un System.out.println dans la première boucle pour vérifier l'avancement.

    et ... ben ... toute marche parfaitement chez moi, la GUI reste parfaitement utilisable

    Une idée comme ça: ta machine de test est-elle un processeur mono ou dual core ? Si c'est un mono core, baisser la priorité du thread de calcul (cf. post précédent) fera peut-être la différence: ça évitera au thread de calcul de manger toutes les ressources et qu'il ne ralentisse trop fortement (même s'il ne le bloque pas) l'exécution de l'EDT.
    Merci pour tes réponses.
    Je pense aussi que ça vient du processeur qui est mono.

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2007
    Messages
    152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 152
    Points : 81
    Points
    81
    Par défaut
    Citation Envoyé par allouchi Voir le message
    Merci pour tes réponses.
    Je pense aussi que ça vient du processeur qui est mono.
    Effectivement, j'ai testé sur ma machine perso qui est un dual core et ça marche très bien.
    Merci à tous.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. (background-image) comment faire pour ne pas répéter l'image
    Par chakan dans le forum Mise en page CSS
    Réponses: 7
    Dernier message: 10/04/2008, 11h33
  2. Réponses: 3
    Dernier message: 29/01/2008, 11h32
  3. Réponses: 2
    Dernier message: 12/09/2007, 22h42
  4. comment faire pour ne pas referencer dynamiquement
    Par tarekphp dans le forum AWT/Swing
    Réponses: 4
    Dernier message: 15/05/2007, 12h11
  5. Réponses: 4
    Dernier message: 09/05/2007, 14h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo