2012-12-28 4 views
4

je me demandais comment j'enfiler le code suivant, ou tout simplement une méthode en général:Threading une méthode de peinture

public void run(){ 

    public void paint(Graphics g) { 
     g.fillRect(20, 20, 20, 20); 
     for (int i = 20; i < 1000; i++) { 
      g.fillRect(20, i, 20, 20); 
      Thread.sleep(10); 
     } 
    } 
} 

Je trouve que je suis incapable de faire un fil de ce code parce que je reçois un illégale début d'erreur d'expression, ce qui est juste mais je ne vois pas un moyen de contourner le problème.

+0

Vous n'êtes pas autorisé à faire de la peinture à l'extérieur du fil interface utilisateur graphique. Vous ne pouvez pas rediriger le dessin vers un thread secondaire. – MTilsted

Répondre

13

Il est difficile de dire ce que vous faites,

mais semble que vous essayez de passer outre paint() d'un Runnable à partir de sa méthode run().

Cela ne peut sûrement pas être fait.

La logique est

  • Prenez un composant
  • remplacer la méthode de peinture pour dessiner ce que nous avons besoin
  • méthode d'appel à mettre à jour les coordonnées du rectangle (ou dans ce temporisateur de cas le fera) Appeler repaint() sur le composant afin que la méthode de peinture puisse être appelée à nouveau et redessiner le rectangle avec ses nouvelles coordonnées (le temporisateur prendrait aussi soin de repeindre après avoir changé les coordonnées du rectangle)
  • répéter 2 dernières étapes autant de fois que nécessaire/wanted

(quand je dis composante je veux dire en fait JPanel, méthode de peinture fait référence à substitution paintComponent(..) de JPanel comme cela est la meilleure pratique.)

Quelques suggestions:

1) Dont override paint utiliser plutôt JPanel et passer outre paintComponent.

2) Ne pas oublier d'honorer la chaîne de peinture et appeler super.XXX de mise en œuvre surchargée paintComponent(Graphics g) (ou toute autre méthode surchargée pour ce fait), à moins de quitter volontairement dehors. à savoir

class MyPanel extends JPanel { 
    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     //do drawings here 
    } 
} 

3) Si le dessin en paintComponent il est généralement nécessaire pour passer outre getPreferredSize() et retourner Dimension s qui correspondent au contenu/dessins de JPanel, à savoir:

class MyPanel extends JPanel { 
    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(300,300); 
    } 
} 

3) Regardez Swing Timer au lieu de Thread.sleep(..) comme sleep va bloquer le thread graphique et le faire sembler être gelé. à savoir

Timer t = new Timer(10, new AbstractAction() { 
    int count = 20; 
    @Override 
    public void actionPerformed(ActionEvent ae) { 
     if (count < 1000) { 
      //increment rectangles y position 
      //now repaint container so we can see changes in co-ordinates (unless you have a timer which repaints for you too) 
      count++; 
     } else {//counter is at 1000 stop the timer 
      ((Timer) ae.getSource()).stop(); 
     } 
    } 
}); 
t.start(); 

4) Une alternative (parce que je vois pour l'instant vous ne déplacez un Rectangle qui n'est pas un composant Swing) Swing minuterie est TimerTask, et cela peut être utilisé aussi longtemps qu'aucun des composants Swing seront créé/manipulé à partir de sa méthode run() (comme TimerTask ne fonctionne pas sur EDT comme Swing Timer).Remarque revalidate() et repaint() sont Thread-safe de sorte qu'il peut être utilisé dans TimerTask.

L'avantage du code ci-dessus est inutile est conservé EDT (i.e. mouvement rectangle AWT en changeant co-ords) i.e.

final TimerTask tt = new TimerTask() { 
     @Override 
     public void run() { 
      if (count < 1000) { 
       //increment rectangles y position 
       //now repaint container so we can see changes in co-ordinates (unless you have a timer which repaints for you too) 
      count++; 
      } else {//counter is at 1000 stop the timer 
       cancel(); 
      } 
     } 
    }; 

    new Timer().scheduleAtFixedRate(tt, 0, 10);//start in 0milis and call run every 10 milis 
+0

@NickHaughton Voir aussi cette réponse similaire qui utilise un seul Swing Timer, pour déplacer une balle et repeindre son contenant après pour refaire les changements: http://stackoverflow.com/questions/14068472/java-mouselistener-action-event-in- paintcomponent/14070147 # 14070147 –

Questions connexes