2011-08-09 3 views
0

Je veux qu'une ficelle soit dessinée à une position aléatoire, puis je saute à une nouvelle position mais je laisse une empreinte de soi derrière.java canvas drawstring

Il ne semble pas y avoir de commande "stamp" dans java.

Comment puis-je le faire? Jusqu'ici je n'ai qu'un caractère aléatoire qui saute mais ne laisse pas de copie de lui-même derrière.

import java.awt.Canvas; 
import java.awt.Graphics; 
import java.util.Random; 

import javax.swing.JFrame; 

@SuppressWarnings("serial") 
public class test extends Canvas { 

private static Random random = new Random(); 

public void paint(Graphics g) { 
    g.drawString("X", random.nextInt(10) * 10, random.nextInt(10) * 10); 

    try { 
     Thread.sleep(250); 
    } catch (Exception e) {} 

    repaint(); 
} 

public static void main(String[] argS) { 
    test canvas = new test(); 
    JFrame frame = new JFrame(); 
    frame.add(canvas); 
    frame.setSize(300, 300); 
    frame.setVisible(true); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 
} 

Répondre

4

Recommandations:

  • Ne pas mélanger avec des composants swing AWT - donc au lieu d'un objet Canvas, utilisez un JPanel. Remplacez la méthode paintComponent de JPanel.
  • Appelez la méthode super.paintComponent en tant que première ligne de paintComponent.
  • Utilisez un minuteur Swing pour réaliser votre animation et ne placez jamais Thread.sleep dans une méthode Paint ou PaintComponent. En fait, vous devriez éviter d'utiliser Thread.sleep n'importe où dans une interface graphique Swing, sauf si vous savez comment gérer la concurrence dans Swing.
  • N'appelez jamais repaint() dans une méthode paint ou paintComponent. Vous avez de la chance que le gestionnaire de peinture soit assez intelligent pour ne pas autoriser cet appel à provoquer une erreur de stackoverflow induite par la récursivité.
+0

'repeindre()' retourne toujours immédiatement, avant que la peinture est effectivement fait - il est juste une façon de dire « cela devra être repeint quelque temps dans le futur ". Bien sûr, l'invoquer depuis 'paint()' n'est pas vraiment sensé - quand vous avez fini de peindre, l'état actuel ne devrait pas avoir besoin d'être repeint. –

1

Lorsque vous utilisez repaint, le système AWT appellera la méthode toile update(), qui effacera les graphiques (en peignant un rectangle dans la couleur d'arrière-plan), puis appelez paint(). (Ceci est pour les composants lourds de poids de AWT comme Canvas - Swing est un peu différent.)

Ainsi, une solution facile sera donnée en remplaçant update de ne pas effacer le composant:

public void update(Graphics g) { 
    this.paint(g); 
} 

Remarque les vieilles cordes peintes peuvent disparaître lorsque le système décide que votre composant doit être invalidé, par ex. après une autre fenêtre l'a couvert.

Rien à voir avec ceci:

Vous ne devriez jamais dormir dans une méthode de peinture (autre peut-être pour le débogage). La peinture sera effectuée dans le fil d'expédition de l'événement, et tant que la méthode paint n'est pas terminée, aucun événement ne sera distribué. Ne fais pas ça.

Au lieu de cela, avoir un thread séparé (ou même le thread principal) faire une boucle qui dort et appelle repaint.

En outre, comme indiqué par Hovercraft, ne pas mélanger AWT avec Swing. Utilisez un AWT Frame au lieu de JFrame de Swing si vous souhaitez utiliser Canvas.

1

Gardez juste en mémoire toutes les positions précédentes et imprimez-les aussi, peut-être dans une autre couleur . Vous ne dites pas non plus si vous voulez que les caractères soient imprimés pour toujours ou juste pour rester visible pour quelques images. Si vous voulez qu'ils disparaissent après un moment, vous pouvez mettre vos positions aléatoires dans une file d'attente et supprimer l'élément queue de la file d'attente (se débarrasser des anciennes positions afin qu'elles ne soient pas peintes) pendant que vous peignez de nouvelles images.

(Les recommandations de Hovercraft et Paulo sont très utiles aussi.)