2017-04-21 3 views
0

학습 목적으로 자체 버전의 뱀을 만들려고합니다. 내가 프레임을 다시 칠하기 원한다면 수동으로 창 크기를 조정해야한다는 점을 제외하면 모든 것이 잘 작동하는 것 같습니다. 여기 내 코드는 다음과 같습니다.JFrame은 창의 크기를 조정할 때만 업데이트됩니다.

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

    } 


} 

왜 프레임 크기를 변경하지 않고 repaint()가 트리거되지 않습니까? 나는 상관 관계를 얻지 만 어쨌든 while (true) 루프에있을 때 왜 그런 방아쇠가 필요한지 내게는 의미가 없다.

무엇이 여기에 있습니까? p.start와 제거 스레드 객체 대체 t.start()()

편집 : 2 :

편집 한 추가 new Thread(p).start(); 지금 작동! 감사.

편집 3 : 이 revalidate();

+0

PlayGame p = 새로운 PlayGame(); 스레드 t = 새 스레드 (p); t.start(); –

+1

''t.start()''하지만 결코''p.start()''가 아니기 때문에'animate'는 항상'false'입니다. – kiheru

+0

좋아요, 그렇다면 스레드 객체가 무의미하다는 뜻입니까? –

답변

0

아직도 아무 생각이 어떻게, 왜이 Thread t = new Thread(p); t.start();

에 다른 그러나 그것은했다.

+0

그들은 다르지 않습니다. 문제는 없습니다. 문제는 여러분이'Thread' 클래스에서'start'를 호출했지만'PlayGame' 클래스에서'start'를 호출 한 것이 아닙니다. 둘 다 완전히 다른 방법이고 둘 다 호출해야합니다. 'Playgame'의'start'는 원하는 이름을 가질 수 있습니다. 그것은'Thread'의 메소드와 같은 이름을 가졌음을 오도하는 것입니다. – Berger

0

을 제거 당신은 작업자 스레드에서 repaint()을 실행하고 있습니다하지 이벤트 파견 트레드 실제로 화면에 그리기 유일 (EDT)인치 당신은 욕실에 가지고

SwingUtilities 정적 메소드 invokeLater() 또는 invokeAndWait()를 사용하여 EDT에서 repaint()에 대한 호출을 대기. 추가 new Thread(p).start();

+0

나를 보여줄 수 있습니까? 나는 그것을 어디에 넣어야할지 모르지만, 구글은 도움이되지 못한다. –

+0

'repaint'는 실제 페인트 이벤트를 처리 할 EDT에 게시 할 때 스레드로부터 안전합니다. – MadProgrammer

관련 문제