2017-04-21 15 views
0

Ich versuche, meine eigene Version von Snake zu Lernzwecken zu erstellen. Alles scheint gut zu funktionieren, außer wenn ich möchte, dass mein Frame neu gezeichnet wird, muss ich mein Fenster manuell skalieren. Hier ist mein Code:JFrame wird nur beim Ändern der Größe aktualisiert.

package snake; 

import java.awt.*; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class PlayGame extends JPanel implements Runnable{ 

    public boolean animate = false;   
    public final int FRAME_DELAY = 750; 

    PickupBall b = new PickupBall(); 
    Snake bob = new Snake(); 


    public synchronized void start() { 
     animate = true; 
    } 

    public synchronized void stop() { 
     animate = false; 
    } 
    private synchronized boolean animationEnabled() { 
     return animate; 
    } 

    @Override 
    public void run(){    
     while(true){  
      if (animationEnabled()){      
       repaint();      
      } 
      try { 
       Thread.sleep(FRAME_DELAY); 
      } 
      catch (InterruptedException e) { 
       throw new RuntimeException(e); 
      } 
     } 
    }   

    @Override 
    public void paintComponent(Graphics g){    
     super.paintComponent(g); 

     b.draw(g); 
     bob.draw(g);    
    }   

    public static void main(String[] args) {  
     JFrame jfr = new JFrame("Snake"); 
     jfr.setSize(640,640); 
     jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
     jfr.setResizable(true); 

     PlayGame p = new PlayGame(); 

     jfr.setContentPane(p); 

     p.setBackground(Color.WHITE);    

     p.start();    

     new Thread(p).start();    
     jfr.setVisible(true);  

    } 


} 

Warum wird repaint() nicht ausgelöst, ohne die Rahmengröße zu ändern? Ich bekomme die Korrelation, aber es macht keinen Sinn für mich, warum es einen solchen Trigger braucht, wenn es in einer (echten) Schleife ist.

Was fehlt mir hier?

Edit 1: entfernt Thread-Objekt ersetzt t.start() mit p.start()

Edit 2: Added new Thread(p).start(); und jetzt funktioniert es! Vielen Dank.

Bearbeiten 3: revalidate(); Entfernte

+0

PlayGame p = neues PlayGame(); Faden t = neuer Faden (p); t.start(); –

+1

't.start()', aber niemals 'p.start()', also 'animate' ist immer' false'. – kiheru

+0

In Ordnung, bedeutet dies auch, dass das Thread-Objekt sinnlos ist? –

Antwort

0

Added new Thread(p).start();

haben aber keine Ahnung, wie oder warum dies anders Thread t = new Thread(p); t.start();

Aber es funktionierte.

+0

Sie sind nicht anders, das Problem ist nicht da. Das Problem war, dass Sie "start" von der 'Thread'-Klasse, aber nicht' start' von Ihrer 'PlayGame'-Klasse aufgerufen haben. Sie sind beide völlig unterschiedliche Methoden, und Sie müssen beide anrufen. Der 'Start' in' Playgame' könnte einen beliebigen Namen haben, es war irreführend, dass er den gleichen Namen wie die Methode aus 'Thread' hatte. – Berger

0

Du repaint() in der Arbeiter-Thread ausgeführt wird, und nicht in der Ereignis-Zuteilungs Lauffläche (EDT) die die einzige Zeichnung auf dem Bildschirm tatsächlich ist. mit SwingUtilities statischen Methoden invokeLater() oder invokeAndWait()

Sie zu en haben den Anruf in der EDT repaint() Warteschlange.

+0

Kannst du es mir zeigen? Ich habe keine Ahnung, wo ich das hinstellen soll, und Google hilft nicht. –

+0

'repaint' ist threadsicher, da es das eigentliche Paint-Event auf den zu bearbeitenden EDT posten – MadProgrammer

Verwandte Themen