2016-03-24 5 views
-1

こんにちは単純なarcanoidゲームを作成したかったのですが、なんらかの理由でJPanel.repaint()が呼び出されず、ボールが動きません。 JPanelをJPanelに拡張すると、ユーザーがゲームを開始したいときに呼び出されるリスナーが追加され、その結果スレッドが起動され、このスレッドはボールの位置を変更し、理想的には私のjpanelクラス。私はボールの変更の位置を確認したが、再描画メソッドは呼び出されません。誰かが助けてくれますか?JPanelがreapintを呼び出さない理由

public class test extends JPanel{ 
int x=250; 
int y=470; 
int width=100; 
int height=20; 
Ball b=new Ball(); 
public static void main(String[] args){ 
    test t=new test(); 
    t.draw(); 
} 
public void draw(){ 
    JFrame frame=new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(520, 520); 
    frame.setResizable(false); 
    this.setSize(500,500); 
    frame.add(this); 
    this.addMouseListener(new mouseL()); 
    frame.setVisible(true); 
} 
public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    System.out.println("Yeah I am called"); 

    Graphics2D g2d=(Graphics2D) g; 
    g2d.setColor(Color.blue); 
    g2d.fillRect(x, y, width, height); 
    g2d.setColor(b.getColor()); 
    g2d.fillOval(b.x1, b.y1, b.width1, b.height1); 
} 
class Ball{ 
    Random rand=new Random(); 
    int x1=300; 
    int y1=450; 
    int height1=20; 
    int width1=20; 
    Color c; 
    public Color getColor(){ 
     return new Color(rand.nextInt(255), rand.nextInt(255), rand.nextInt(255)); 
    } 
} 
class mouseL implements MouseListener{ 
    Thread t=new Thread(new MyRun()); 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     // TODO Auto-generated method stub 
     t.run(); 


    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseExited(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

} 
class MyRun implements Runnable{ 

    @Override 
    public void run() { 
     // TODO Auto-generated method stub 
     try{ 
     while(true){ 
      //System.out.println("Yeah I work"); 
      test.this.b.x1=test.this.b.x1-1; 
      test.this.b.y1=test.this.b.y1-1; 
      System.out.println("the values are: "+test.this.b.x1+" and "+test.this.b.y1); 
      Thread.sleep(2000); 
      test.this.repaint(); 
     } 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

    } 

} 

}(あなたのケースでは)

答えて

2

t.run();通話Runnabe#run、それによって永遠にあなたのUIを凍結し、ユーザーインターフェイススレッドのコンテキスト内から実行されます。事前に感謝はここに私のコードです。

あなたはt.start()

を使用している必要がありますスイングがシングルスレッドなので、あなたは競合状態とダーティ・リードのリスクを実行している/変数の間で書き込みます。安全かつ簡単な解決策は、あなたが使用してはならない理由のためにHow can I set in the midst?を見て、それが安全ではまた

からUIを更新すること、EDT内の通知だそのスケジュール、How to use Swing Timersを参照してください、スイングTimerを使用することですJFrame#setSizeの代わりに、JPanelgetPreferredSizeメソッドを無効にして、代わりにJFrame#packを呼び出してください。

+0

ありがとう、私はそれを完全に忘れました!どうもありがとう!!! – user3428496

関連する問題