2015-08-23 87 views
2

当我运行此代码时,除了空白(白色)面板外,我什么都看不到,我想知道为什么。为什么我的while循环在paintComponent中不起作用?

这里是我的代码:

Graph.java

public class Graph extends JPanel { 
    private static final long serialVersionUID = -397959590385297067L; 
    int screen=-1; 
    int x=10; 
    int y=10; 
    int dx=1; 
    int dy=1;  
    boolean shouldrun=true; 
    imageStream imget=new imageStream(); 

     protected void Loader(Graphics g){ 

      g.setColor(Color.black); 
      g.fillRect(0,0,x,y); 
      x=x+1; 
      y=y+2; 

     } 


     @Override 
     protected void paintComponent(Graphics g){ 
      super.paintComponent(g); 
       while(shouldrun){ 
        Loader(g); 
        try { 
         Thread.sleep(200); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        }  
       } 
     } 
} 
+0

看一看[Swing中的并发(http://docs.oracle.com/javase/tutorial/uiswing/concurrency/)和[如何使用Swing定时器(http://docs.oracle.com /javase/tutorial/uiswing/misc/timer.html) – MadProgrammer

回答

10

永远不要叫Thread.sleep()Event Dispatch Thread

这会导致实际重画屏幕并使控件响应停止执行的线程任何东西

For animations, use a Timer。不要担心自己写while循环,只要告知Timer每隔一段时间就会触发一次,并在该定时器内更改xy的值。喜欢的东西:

// this is an **inner** class of Graph 
public class TimerActionListener implements ActionListener { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     x += dx; 
     y += dy; 
    } 
} 

// snip 
private final Timer yourTimer; 

public Graph() { 
    yourTimer = new Timer(2000, new TimerActionListener()); 
    timer.start(); 
} 
所有的
@Override 
protected void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    g.setColor(Color.black); 
    g.fillRect(0,0,x,y); 
} 
+0

是啊,他说什么! 1+ –

+0

它不是一个动画寿,这个想法是在游戏中有一个水平,一个加载屏幕和一个菜单。我想要一个循环来重新运行图形取决于整数屏幕。 –

+1

@DanjahSoftProgrammer事件调度线程会自动为您执行循环的工作。 **你不需要担心重复绘制它,因为Swing对你来说就像魔术一样!**这段代码与你提供的代码很相似,你在你的'Loader'方法中调用'x = x + 1',这是做同样的事情,除了'Timer'而不是while循环。 – durron597

4

你永远不会改变shouldrun州内环路 - 所以它永远不会结束。

而且,从来没有一幅画方法中调用Thread.sleep(...)。这种方法是用于绘画的,永远不能入睡,否则GUI将被放入睡眠状态,将被冻结。

+0

噢,我明白了。是的,它永远不会结束。但我应该如何使它迭代?在主代码中重绘?...忽略此 –

0

首先,你的paintComponent方法应该只处理所有的画,没有别的(如果可能)。你不应该在paintComponent中实现你的程序循环。

空白屏幕可能由多种原因引起。您可以通过评论代码的某些部分并运行它来手动轻松地进行调试。看看它是否仍然是空白的。

至少从我在这里看到的,你的paintComponent会给你的问题。

如果你想要一个动画,您可以:

  1. 使用摆动计时器

  2. 创建一个新的线程(不是事件指派线程)的循环。你的循环将是这个样子:

如下:

while(running){ 
    update(); 
    render(); 
    try(
     Thread.sleep(1000/fps); 
    )catch(InterruptedException ie){ 
     ie.printStackTrace(); 
    } 
} 

注:为了使动画适当的循环,你将需要不止于此。

+0

”它应该只是绘画,否则代码中存在某些重大缺陷。 – Emz

+0

@ durron597看看大学给出的这个样本吗? http://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html – user3437460

+0

@ durron597最简单的方法就是使用计时器,但是如果程序/游戏变得复杂,那将会更好创建一个Thread并在该线程中运行游戏循环,而不是在EDT中做所有事情,不是吗?所以从这个角度来看,并不是绝对的,Java动画必须只用挥杆定时器来完成。 – user3437460

相关问题