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
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