为什么我的 while 循环在 paintComponent 中不起作用?
Why is my while loop not working in 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();
}
}
}
}
你永远不会在循环中改变 shouldrun 的状态——所以它永远不会结束。
此外,切勿在绘画方法中调用 Thread.sleep(...)
。此方法用于绘画,永远不能休眠,否则GUI将休眠,将被冻结。
永远不要在 Event Dispatch Thread 上调用 Thread.sleep()
!!!
这会导致线程实际重绘屏幕并使控件响应停止执行任何操作。
For animations, use a Timer
。不要担心自己编写 while 循环,只需告诉 Timer
每隔一段时间触发一次,并在该计时器内更改 x
和 y
的值。类似于:
// 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);
}
首先,你的 paintComponent 方法应该只处理所有的绘画,而不是其他的(如果可能的话)。你不应该在 paintComponent 中实现你的程序循环。
黑屏可能由多种原因引起。您可以通过注释掉代码的某些部分并 运行 来轻松地手动调试它。看看是不是还是空白
至少从我在这里看到的情况来看,您的 paintComponent 会给您带来问题。
如果你想要一个动画,你可以:
使用摆动计时器
在新线程(不是事件调度线程)中创建循环。你的循环看起来像这样:
如下:
while(running){
update();
render();
try(
Thread.sleep(1000/fps);
)catch(InterruptedException ie){
ie.printStackTrace();
}
}
注意:要为动画制作适当的循环,您需要的不止这些。
当我 运行 这段代码时,我只看到一个空白(白色)面板,我想知道为什么。
这是我的代码:
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();
}
}
}
}
你永远不会在循环中改变 shouldrun 的状态——所以它永远不会结束。
此外,切勿在绘画方法中调用 Thread.sleep(...)
。此方法用于绘画,永远不能休眠,否则GUI将休眠,将被冻结。
永远不要在 Event Dispatch Thread 上调用 Thread.sleep()
!!!
这会导致线程实际重绘屏幕并使控件响应停止执行任何操作。
For animations, use a Timer
。不要担心自己编写 while 循环,只需告诉 Timer
每隔一段时间触发一次,并在该计时器内更改 x
和 y
的值。类似于:
// 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);
}
首先,你的 paintComponent 方法应该只处理所有的绘画,而不是其他的(如果可能的话)。你不应该在 paintComponent 中实现你的程序循环。
黑屏可能由多种原因引起。您可以通过注释掉代码的某些部分并 运行 来轻松地手动调试它。看看是不是还是空白
至少从我在这里看到的情况来看,您的 paintComponent 会给您带来问题。
如果你想要一个动画,你可以:
使用摆动计时器
在新线程(不是事件调度线程)中创建循环。你的循环看起来像这样:
如下:
while(running){
update();
render();
try(
Thread.sleep(1000/fps);
)catch(InterruptedException ie){
ie.printStackTrace();
}
}
注意:要为动画制作适当的循环,您需要的不止这些。