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

Java ME Discussion :

JavaME : Timer et thread graphique


Sujet :

Java ME

  1. #1
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut JavaME : Timer et thread graphique
    Salut,

    Je commence le JavaME, et je ne trouve pas comment faire un truc tout simple : un Timer qui génère un évènement toutes les x millisecondes dans le thread graphique (tout comme javax.swing.Timer en JavaSE).

    Il y a bien java.util.Timer, mais il génère les évènements dans un thread séparé.
    Citation Envoyé par javadoc ME
    A facility for threads to schedule tasks for future execution in a background thread.
    Dans ce cas, comment "poster" un évènement dans la file des évènements graphiques? En Swing on ferait comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
             // code
        }
    });
    Comment faire ceci en JavaME svp?

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 137
    Par défaut
    habituellement, on utilise effectivement un objet Timer qui modifie l'etat d'un objet graphique puis déclenche un repaint.

    voir un exemple d'utilisation dans le projet J4ME :

    progressbar.java

    et plus particulièrement le code

    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
     
    /**
             * A task executed at regularly scheduled intervals that forces
             * the spinner animation to advance to the next frame.
             */
    	private final class SpinnerTask
    		extends TimerTask
    	{
    		public void run ()
    		{
    			// Increment the position of the lead spoke.
    			spinnerHour = (spinnerHour + 1) % 12;
     
    			// Repaint the spinner.
    			ProgressBar.this.repaint();
    		}
    	}

    sinon tu as

    ---
    Manitoba

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    137
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 137
    Par défaut Display.callSerially
    Pour être exact, l'équivalent de InvokeLater est Display.callSerially

    public void callSerially(Runnable r)
    Causes the Runnable object r to have its run() method called later, serialized with the event stream, soon after completion of the repaint cycle. As noted in the Event Handling section of the package summary, the methods that deliver event notifications to the application are all called serially. The call to r.run() will be serialized along with the event calls into the application. The run() method will be called exactly once for each call to callSerially(). Calls to run() will occur in the order in which they were requested by calls to callSerially().
    ......
    Mon expérience pratique (partagé par d'autre) est que cela marche assez mal d'un téléphone a l'autre.

    Je conseilles donc de faire autrement (voir mon post précédent)

  4. #4
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Merci beaucoup pour ces réponses

    Pour la première méthode (modifier des valeurs dans le run() et faire un repaint()), c'est ce que je fais actuellement, mais ça ne me convient pas, car il faut synchroniser l'accès à toutes les variables.

    Par exemple:

    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
        private Timer timer = new Timer();
        private Vector list = new Vector();
        ...
        method() {
            Timer.schedule(new TimerTask() {
                public void run() {
                    if(!list.isEmpty()) {
                        list.remove(0);
                    }
                    repaint();
                }
            }
        } 
     
        public void paint(Graphics g) {
            int size = list.size();
            for(int i = 0; i < size; i++) {
                 g.draw...(...);
            }
        }
     
        public void keyPressed(int keyCode) {
            list.add(new Object());
        }
    Deux threads accèdent au Vector list : celui du Timer, celui qui gère l'affichage. Si on ne synchronise pas, il risque d'y avoir des problèmes... Par exemple si pendant le parcours de la liste par la méthode paint, le timer supprime le premier élément, il va y avoir un ArrayIndexOutOfBoundException...

    Petite question en plus : j'ose espérer que les évènements (keyPressed par exemple) sont bien appelés à partir du "thread graphique", dans le même thread que paint?


    En tout cas merci je vais essayer sur différents tél en utilisant callSerially, on verra bien

  5. #5
    Membre Expert
    Avatar de ®om
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    2 815
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 2 815
    Par défaut
    Ah bah en fait tu as raison, ça ne marche pas bien...

    J'ai d'ailleurs fait des appels à Thread.currentThread().getName() à différents endroits, le paint(Graphics) est exécuté dans un Thread-0 la première fois, puis après toujours dans Thread-4 dans le même thread que le run du TimerTask (je fais un repaint() dans le Timer, mais en JavaSE le repaint() poste un évènement dans l'EDT) ... et que celui des évents (donc en fait les actions graphiques sont dans un thread quelconque...)

    Je ne comprends pas tellement le mécanisme de threads en JavaME... mais il m'a pas l'air d'être tip top... Je crois que je vais gérer la synchronisation...

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 44
    Par défaut
    Pour résumer, comme principe de base pour faire une tache répétitive, on a :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MaTache extends TimerTask {
      public void run(){
        // Faire un truc .... 
      }
    }
    et puis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Timer      timer = new Timer();
    timer.schedule( new MaTache(), premiereExecution, delayDeRepetition);
    Comme ton but est de faire un rafraichissement d'un dessin que tu affiches toutes les n secondes, voilà une possibilité, très condensée à rendre plus jolie J'utilise beaucoup les GameCanvas. Attention ce n'est valable que pour les profiles MIDP 2.x

    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
     
    import javax.microedition.lcdui.*;
    import javax.microedition.lcdui.game.GameCanvas;
     
     
    public class Exemple extends GameCanvas	implements Runnable {
     
    	private Graphics        graphics;
    	private Exemple 	exemple;
    	private volatile Thread thread;
     
    	public Exemple(){
    		super( true );
     
    		graphics = getGraphics();
    		graphics.setColor(0x000000);
    		graphics.fillRect( 0, 0, getWidth(), getHeight() );
    	}
     
    	public void run(){
    		int w = getWidth();
    		int h = getHeight() - 1;
     
    		while( thread == Thread.currentThread() ){
     
    			// récupération des evennements touches
    			// avec getKeyStates();
     
    			// Ensuite on dessine un truc
     
    		        graphics.setColor(0x000000);
    		        graphics.fillRect( 0, 0, getWidth(), getHeight() );
    			//.. etc graphics...... tout ce qu'il faut faire pour dessiner
     
     
    			flushGraphics();
     
    			// on fait une pause
    			try {
    				Thread.currentThread().sleep( delayDePause );
    			} catch( InterruptedException e ){
                                ; // Faire qqch en cas  de pb 
    			}
    		}
    	}
     
     
    	// Le canvas est affiché, on lance le thread
    	protected void showNotify(){
    		exemple = new Exemple();
     
    		thread = new Thread( this );
    		thread.start();
    	}
     
    	// Le canvas est caché .... 
    	protected void hideNotify(){
    		thread = null;
    	}
     
    }

Discussions similaires

  1. [TJvTimer] Timer JVCL thread
    Par dvarrel dans le forum Composants VCL
    Réponses: 1
    Dernier message: 14/08/2008, 22h35
  2. Actualisation périodique : timer ou thread ?
    Par Shredder dans le forum Langage
    Réponses: 12
    Dernier message: 02/11/2007, 08h52
  3. Enchainer plusieurs Threads "graphique"
    Par RR instinct dans le forum EDT/SwingWorker
    Réponses: 15
    Dernier message: 17/10/2007, 03h28
  4. Un timer ? Plein de Timer ? un thread de control ?
    Par vincedom dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 12/06/2006, 13h18
  5. [MFC] Cherche Timer avec thread
    Par romeo9423 dans le forum MFC
    Réponses: 17
    Dernier message: 09/03/2005, 10h33

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