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

EDT/SwingWorker Java Discussion :

[ProgressBar] comment utiliser swingWokrer avec une classe devant rester indépendante de Swing?


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre habitué
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Points : 129
    Points
    129
    Par défaut [ProgressBar] comment utiliser swingWokrer avec une classe devant rester indépendante de Swing?
    Bonjour,

    je suis en train de développer une application de traitement d'image.
    Jusqu'à présent, j'avais réussi a bien séparé le "coeur" de l'appli qui s'occupe de tout ce qui est traitement de l'image, et l'interface graphique.

    Le traitement pouvant être long, j'utilise SwingWorker pour le lancer à partir de l'interface graphique. L'utilisateur ne doit pas pouvoir interagir avec l'application pendant le traitement, pour ce faire, j'ai utiliser le Glasspane dans lequel j'ai mis une progressBar.
    En suivant le tuto de Romain Vimont, j'ai réussi à faire ce que je voulais, mais pour le faire, j'ai passé l'instance de SwingWorker à la partie qui s'occupe de l'analyse pour pouvoir mettre à jour la progressBar. et ça, je peux pas le laisser comme ça, puisque ça viole le principe d'indépendance du coeur de l'appli par rapport à l'IHM...

    Voici le code qui lance l'analyse :
    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
     
    	@Override
    	public void actionPerformed(ActionEvent e)
    	{
    		//Si la selection est vide : message d'erreur
    		if(fenetre.getListeMammos().isSelectionEmpty())
    		{
    			JOptionPane.showMessageDialog(fenetre, "Aucune mammographie sélectionnée", 
    					"Lancement analyse", JOptionPane.WARNING_MESSAGE);
    		}
    		else 
    		{
    			//Recuperation du nom des mammos selectionnees
    			Object[] mammosSelectionnees = fenetre.getListeMammos().getSelectedValues();
    			nomMammosSelectionnees = new String[mammosSelectionnees.length];
     
    			int i = 0;
    			for(Object obj : mammosSelectionnees)
    			{
    				Mammo mammo = (Mammo) obj;
    				nomMammosSelectionnees[i] = mammo.getNom();
    				i++;
    			}
     
    			if(typeAnalyse.contains("automatique"))
    			{
    				SwingWorkerAnalyse swingWorkerAnalyse = new SwingWorkerAnalyse(fenetre.getProgessBar(),
    						fenetre, nomMammosSelectionnees, "auto");
     
    				fenetre.getGlass().setNeedToRedispatch(false);
    				fenetre.getGlass().setVisible(true);
    				swingWorkerAnalyse.execute();
     
    				//changement de l'etat des mammos dans la liste
    				for(Object obj : fenetre.getListeMammos().getSelectedValues())
    				{
    					Mammo mammo = (Mammo) obj;
    					if(mammo.getEtat().equals("EnAttenteAnalyse"))
    						mammo.setEtat("EnAttenteValidation");
    				}
    			}
    			else if(typeAnalyse.contains("manuelle"))
    			{
    				System.out.println("Lancement analyse manuelle...\nA Developper");
    			}
    		}
    	}
    voici le code du SwingWorker :
    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
     
    /**
     * Projet : LAM
     * Paquetage : fr.statlife.LAM.IHM
     * Fichier : SwingWorkerAnalyse.java
     *
     * @author Mathilde Pellerin
     * @date 18 mai 2010
     */
    package fr.statlife.LAM.IHM;
     
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
     
    import javax.swing.JProgressBar;
    import javax.swing.SwingWorker;
     
    import fr.statlife.LAM.Controleur;
     
    /**
     * 
     * @author Mathilde Pellerin
     */
    public class SwingWorkerAnalyse extends SwingWorker<Integer, String>
    {
    	private static final FacadeIHM ihm = FacadeIHM.getInstance();
    	private JProgressBar progressBar;
    	private Controleur control;
    	private FenetreLAM fenetre;
    	private String[] mammosSelectionnees;
    	private String typeAnalyse;
     
    	public SwingWorkerAnalyse(JProgressBar progressBar, FenetreLAM fenetre,  
    			String[] mammosSelectionnees, String typeAnalyse)
    	{
    		this.progressBar = progressBar;
    		this.control = fenetre.getControl();
    		this.fenetre = fenetre;
    		this.mammosSelectionnees = mammosSelectionnees;
    		this.typeAnalyse = typeAnalyse;
     
    		//Ajout d'un ecouteur de barre de progression
    		addPropertyChangeListener(new PropertyChangeListener() {
     
    			@Override
    			public void propertyChange(PropertyChangeEvent evt)
    			{
    				if("progress".equals(evt.getPropertyName()))
    				{
    					SwingWorkerAnalyse.this.progressBar.setValue((Integer) evt.getNewValue());
    				}
    			}
    		});
    	}
     
    	public void setProgressPublic(int progress)
    	{
    		this.setProgress(progress);
    	}
     
    	/* (non-Javadoc)
    	 * @see javax.swing.SwingWorker#doInBackground()
    	 */
    	@Override
    	protected Integer doInBackground() throws Exception
    	{
    		Integer nbMammosTraitees = 0;
     
    		if(typeAnalyse.equals("auto"))
    		{
    			control.choixModeExecution("auto");
    			nbMammosTraitees = control.lancerAnalyser(mammosSelectionnees, "bmp", this, 0, 100);
    		}
    		else if(typeAnalyse.equals("manuelle"))
    		{
    			//TODO
    			System.out.println("A faire");
    		}
     
    		return nbMammosTraitees;
    	}
     
    	protected void done()
    	{
    		try
    		{
    			//Le traitement est termine
    			setProgress(100);
    			ihm.afficherMessageConsole(String.valueOf(get()) 
    					+ " mammographies analysées avec succès.\n");
    			fenetre.getGlass().setVisible(false);
    		} 
    		catch (Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    }
    et voici la partie du code d'analyse correspondante :
    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
     
    /**
             * lancerAnalyse : lance l'analyse sur les mammos devant etre analysees
             * @param control : controleur
             */
    	@Override
    	protected int lancerAnalyse(Controleur control, FacadeTracabilite tracabilite,
    			Collection<Mammographie> listMammos, String format, SwingWorkerAnalyse swingWorkerAnalyse,
    			double progressStart, double progressEnd)
    	{
    		int nbAnalysees = 0;
    		int nbAAnalyser = listMammos.size();
    		double etape = (progressEnd - progressStart) / nbAAnalyser;
     
    		//Boucle sur l'ensemble des mammos selectionnees
    		Iterator<Mammographie> iterator = listMammos.iterator();
    		while(iterator.hasNext())
    		{
    			progressStart += etape;
     
    			//Transmet la nouvelle progression
    			swingWorkerAnalyse.setProgressPublic((int) progressStart);
     
    			Mammographie mammo = iterator.next();
    			if(mammo.getEtat() == "EnAttenteAnalyse")
    			{
    				//Analyse de la mammo
    				if(!mammo.isChargee())
    				{
    					Image imgNative = control.importerImage(mammo.getId());
    					mammo.chargerMammo(imgNative, null);
    				}
     
    				analyse.nettoyer(mammo);
    				String nomAnalysee = control.enregistrerMammo(mammo.getId(), format);
     
    				mammo.setNomAnalysee(nomAnalysee);
    				//Mise a jour du fichier de conf
    				tracabilite.miseAJour(mammo.getId(), mammo.getEtat(), nomAnalysee, mammo.getDensite());
     
    				//TODO : segmentation et calcul densite
     
    				mammo.allegerMammo();
     
    				nbAnalysees++;
    			}
    		}
     
    		//Passage dans l'etat en attente
    		this.setEtat(control, new ControleurEnAttente());
     
    		return nbAnalysees;
    	}
    Comme vous pouvez le voir, j'ai fait une méthode public setProgressPublic() qui appelle la méthode protégée setProgress() du SwingWorker car les deux classes sont dans des packages différents (une dans l'IHM, et l'autre dans l'Analyse...).

    Bref, c'est un peu bancale comme implémentation, et l'utilisation de l'instance de SwingWorker dans l'analyse me plait pas. Mais je ne trouve pas de parade
    Il doit surement y avoir un moyen de faire ça plus proprement, alors je viens chercher de l'aide auprès de vous

    Merci d'avance pour toute aide ou conseil avisé

  2. #2
    Membre habitué
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Points : 129
    Points
    129
    Par défaut
    mon problème n'a pas l'air d'inspirer grand monde

    En cherchant une autre approche, je me suis dit qu'il était peut être possible de remplacer dans la classe d'analyse l'appel à SwingWorker :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	progressStart += etape;
     
    	//Transmet la nouvelle progression
    	swingWorkerAnalyse.setProgressPublic((int) progressStart);
    par l'envoie de l'événement qui met à jour la barre de progression dans le swingWorker. Je sais pas trop si c'est possible, ni comment envoyer un événement, mais bon, je cherche
    en fait, l'idée m'est venue en lisant la FAQ "Comment créer son propre listener"
    et l'exemple d'implémentation associé. Mais je ne suis pas encore arrivé à l'adapter...
    Par contre, du coup j'ai modifié le SwingWorker pour mieux séparer le SwingWorker et le listener de la barre de progression :
    le constructeur du SwingWorker devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    	public SwingWorkerAnalyse(FenetreLAM fenetre,  
    			String[] mammosSelectionnees, String typeAnalyse)
    	{
    		this.control = fenetre.getControl();
    		this.fenetre = fenetre;
    		this.mammosSelectionnees = mammosSelectionnees;
    		this.typeAnalyse = typeAnalyse;
     
    		//Ajout d'un ecouteur de barre de progression
    		this.addPropertyChangeListener(fenetre.getListenerProgressionAnalyse());
    	}
    et j'ai ajouté une classe ProgressListener :
    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
    /**
     * Projet : LAM
     * Paquetage : fr.statlife.LAM.IHM
     * Fichier : ProgressListener.java
     *
     * @author Mathilde Pellerin
     * @date 19 mai 2010
     */
    package fr.statlife.LAM.IHM;
     
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
     
    import javax.swing.JProgressBar;
    /**
     * 
     * @author Mathilde Pellerin
     */
    public class ProgressListener implements PropertyChangeListener
    {
    	private JProgressBar progressBar;
     
    	//Evite la creation sans progressBar
    	@SuppressWarnings("unused")
    	private ProgressListener() {}
     
    	public ProgressListener(JProgressBar progressBar)
    	{
    		this.progressBar = progressBar;
    		this.progressBar.setValue(0);
    	}
     
    	/* (non-Javadoc)
    	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
    	 */
    	@Override
    	public void propertyChange(PropertyChangeEvent evt)
    	{
    		if("progress".equals(evt.getPropertyName()))
    		{
    			int progress = (Integer)evt.getNewValue();
    		    this.progressBar.setValue(progress);
    		}
    	}
    }
    si vous avez des conseils ou des idées dans cette direction ou si vous pensez que je vais dans le mur en partant par là, faites moi signe

  3. #3
    Membre habitué
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2008
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 39
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 379
    Points : 129
    Points
    129
    Par défaut
    Bon, en fait, la solution est bien plus simple : il faut revoir l'architecture et mettre une partie du traitement dans la classe SwingWorker ou lieu de s'escrimer avec une archi pas tout à fait bien pensée au départ (après tout, je suis apprentie, normal que ça soit pas parfait du premier coup )

    Bref, la solution était dans le titre : il suffit de laisser dans SwingWorker ce qui ne devrait pas en sortir (setProgress() par exemple)

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

Discussions similaires

  1. [Débutant] comment utiliser sharpMap avec une application C#
    Par geoinformation dans le forum C#
    Réponses: 1
    Dernier message: 18/12/2012, 08h24
  2. Réponses: 1
    Dernier message: 27/03/2007, 14h07
  3. template et utilisation avec une classe existante
    Par vartav dans le forum Langage
    Réponses: 6
    Dernier message: 14/03/2007, 10h39
  4. Utilisation iterator avec une classe perso
    Par SteelBox dans le forum C++
    Réponses: 19
    Dernier message: 07/03/2005, 11h30

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