OVH Cloud OVH Cloud

multithread et swing

3 réponses
Avatar
Frédéric Carayon
bonjour à tous,

je sais que c'est une question de newbie mais je n'arrive pas à trouver
de réponses satisfaisantes.
Alors voilà, j'utitlise une JList avec un ListDataListener implementé
par mes soins, et il arrive que lors de l'execution, lorsque la liste de
données change, la JList ne se redessine pas correctement (comprenez
qu'elle est vierge), et au changement suivant des valeurs elle redevient
visible.

d'autre part, j'ai lu dans
http://www.usenet-fr.net/fur/comp/lang/faq-java.html
que les swing et le multiThreading ne font pas bon ménage.
Or il n'y a pas plus d'indications dans la FAQ, ou plutot elle fait
référence à une page chez Sun qui n'existe plus.

pour info voilà le code de mon ListDataListener:

class Verbose implements ListDataListener{
JList jli;
VerboseEngine verb;
// verboseengine est une sous classe de AbstractListModel
// elle surcharge les methode add(Object)
// pour quelle appelle fireContentsChanged() qui lance un
// ListDataEvent
// verboseengine est modifié par un thread endépendant de la frame
// un serveur en l'occurence

public Verbose(JList jli, VerboseEngine verbose){
this.jli = jli;
this.verb= verbose;
}
public void intervalAdded(ListDataEvent e){}
public void intervalRemoved(ListDataEvent e){}

// met à jour la JList en question

public void contentsChanged(ListDataEvent e){
this.jli.setModel(verb);

}

}



Toute aide pour trouver plus d'info sur les problèmes d'interraction
entre les swing et le multiThreading est la bienvenue.

3 réponses

Avatar
Bruno Nogent
Toute modification de d'objets (hormis repaint()) de l'interface graphique
doivent se faire dans le thread unique de getsion de l'interface graphique.
Soit par SwingUtilities.invokeAndWait(..) ou par
SwingUtilities.invokeLater(..)

Bruno


"Frédéric Carayon" wrote in message
news:bur5t2$agk$
bonjour à tous,

je sais que c'est une question de newbie mais je n'arrive pas à trouver
de réponses satisfaisantes.
Alors voilà, j'utitlise une JList avec un ListDataListener implementé
par mes soins, et il arrive que lors de l'execution, lorsque la liste de
données change, la JList ne se redessine pas correctement (comprenez
qu'elle est vierge), et au changement suivant des valeurs elle redevient
visible.

d'autre part, j'ai lu dans
http://www.usenet-fr.net/fur/comp/lang/faq-java.html
que les swing et le multiThreading ne font pas bon ménage.
Or il n'y a pas plus d'indications dans la FAQ, ou plutot elle fait
référence à une page chez Sun qui n'existe plus.

pour info voilà le code de mon ListDataListener:

class Verbose implements ListDataListener{
JList jli;
VerboseEngine verb;
// verboseengine est une sous classe de AbstractListModel
// elle surcharge les methode add(Object)
// pour quelle appelle fireContentsChanged() qui lance un
// ListDataEvent
// verboseengine est modifié par un thread endépendant de la frame
// un serveur en l'occurence

public Verbose(JList jli, VerboseEngine verbose){
this.jli = jli;
this.verb= verbose;
}
public void intervalAdded(ListDataEvent e){}
public void intervalRemoved(ListDataEvent e){}

// met à jour la JList en question

public void contentsChanged(ListDataEvent e){
this.jli.setModel(verb);

}

}



Toute aide pour trouver plus d'info sur les problèmes d'interraction
entre les swing et le multiThreading est la bienvenue.



Avatar
Xavier Tarrago
Voir http://java.sun.com/docs/books/tutorial/uiswing/mini/threads.html
Dans ce qui suit, interfaces signifie interface utilisateur, par ex JPanel,
JButton, ... et non interface au sens java.
En gros, Swing n'est pas thread-safe. Cela veut dire que tous les appels
Swing doivent être faits depuis le même thread.
En fait, il y a le thread initial (main) qui crée une interface. Dès lors
que cette interface est visible (setVisible( true)), les seuls appels à des
fonctions Swing doivent être faits depuis les listeners attachés à des
interfaces. Ces appels sont toujours faits dans le cadre du même thread, le
thread Swing aussi appelé "SWT Event dispatching thread".
Les exceptions à cette règle sont documentées. C'est-à-dire que certaines
fonctions Swing sont documentées comme thread-safe. Dans ce cas, on peut les
appeler depuis n'importe quel thread.
Tant que l'on ne crée pas de thread, il n'y a pas de problème, car on est
toujours en callback Swing, et donc dans le thread Swing.
Si on crée un thread, on peut faire tout le boulot que l'on veut dans le
thread, mais pas toucher à Swing. En général, quand on a fini le boulot, on
veut que ela se traduise à l'écran, donc intéragir avec Swing. Il faut à ce
moment-là utiliser SingUtilities.invokeLater(), ou
SwingUtilities.invokeAndWait().
On peut vérifier si on est dans le thread Swing par
SwingUtilities.isEventDispatchThread().

Dans le cas soumis, peut-être que dans VerboseEngine, l'appel à
fireContentsChanged devrait être modifié en:
if( SwingUtilities.isEventDispatchThread()) {
fireContentsChanged(...);
} else {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
fireContentsChanged(...);
}
});
}

Note : Bien entendu, les arguments de fireContentsChanged devront être
déclarés final...

"Frédéric Carayon" a écrit dans le message de
news:bur5t2$agk$
bonjour à tous,

je sais que c'est une question de newbie mais je n'arrive pas à trouver
de réponses satisfaisantes.
Alors voilà, j'utitlise une JList avec un ListDataListener implementé
par mes soins, et il arrive que lors de l'execution, lorsque la liste de
données change, la JList ne se redessine pas correctement (comprenez
qu'elle est vierge), et au changement suivant des valeurs elle redevient
visible.

d'autre part, j'ai lu dans
http://www.usenet-fr.net/fur/comp/lang/faq-java.html
que les swing et le multiThreading ne font pas bon ménage.
Or il n'y a pas plus d'indications dans la FAQ, ou plutot elle fait
référence à une page chez Sun qui n'existe plus.

pour info voilà le code de mon ListDataListener:

class Verbose implements ListDataListener{
JList jli;
VerboseEngine verb;
// verboseengine est une sous classe de AbstractListModel
// elle surcharge les methode add(Object)
// pour quelle appelle fireContentsChanged() qui lance un
// ListDataEvent
// verboseengine est modifié par un thread endépendant de la frame
// un serveur en l'occurence

public Verbose(JList jli, VerboseEngine verbose){
this.jli = jli;
this.verb= verbose;
}
public void intervalAdded(ListDataEvent e){}
public void intervalRemoved(ListDataEvent e){}

// met à jour la JList en question

public void contentsChanged(ListDataEvent e){
this.jli.setModel(verb);

}

}



Toute aide pour trouver plus d'info sur les problèmes d'interraction
entre les swing et le multiThreading est la bienvenue.



Avatar
vclassine
"Bruno Nogent" wrote in message news:<bur6bq$190$...
Toute modification de d'objets (hormis repaint()) de l'interface graphique
doivent se faire dans le thread unique de getsion de l'interface graphique.
Soit par SwingUtilities.invokeAndWait(..) ou par
SwingUtilities.invokeLater(..)
Pour le cas cité ce que tu es exact, mais est-ce qu'il faut aussi

passé par ces fonctions quand les modifications sont éxécuté par un
code d'évenement swing???


Bruno


"Frédéric Carayon" wrote in message
news:bur5t2$agk$
bonjour à tous,

je sais que c'est une question de newbie mais je n'arrive pas à trouver
de réponses satisfaisantes.
Alors voilà, j'utitlise une JList avec un ListDataListener implementé
par mes soins, et il arrive que lors de l'execution, lorsque la liste de
données change, la JList ne se redessine pas correctement (comprenez
qu'elle est vierge), et au changement suivant des valeurs elle redevient
visible.

d'autre part, j'ai lu dans
http://www.usenet-fr.net/fur/comp/lang/faq-java.html
que les swing et le multiThreading ne font pas bon ménage.
Or il n'y a pas plus d'indications dans la FAQ, ou plutot elle fait
référence à une page chez Sun qui n'existe plus.

pour info voilà le code de mon ListDataListener:

class Verbose implements ListDataListener{
JList jli;
VerboseEngine verb;
// verboseengine est une sous classe de AbstractListModel
// elle surcharge les methode add(Object)
// pour quelle appelle fireContentsChanged() qui lance un
// ListDataEvent
// verboseengine est modifié par un thread endépendant de la frame
// un serveur en l'occurence

public Verbose(JList jli, VerboseEngine verbose){
this.jli = jli;
this.verb= verbose;
}
public void intervalAdded(ListDataEvent e){}
public void intervalRemoved(ListDataEvent e){}

// met à jour la JList en question

public void contentsChanged(ListDataEvent e){
this.jli.setModel(verb);

}

}



Toute aide pour trouver plus d'info sur les problèmes d'interraction
entre les swing et le multiThreading est la bienvenue.