由于鼠标按下事件,正在执行以下线程:
// simulates bouncing ball
class Ball extends JPanel implements Runnable {
int Horz = 200;
int Vert = 200;
int xDim = 10;
int yDim = 10;
private int xPos;
private int yPos;
private int dxPos;
private int dyPos;
// constructor - set initial ball position to where mouse clicked; deltas to random numbers
public Ball(int startx, int starty)
{
xPos = startx;
yPos = starty;
dxPos = (int) (Math.random() * 5 + 2);
dyPos = (int) (Math.random() * 5 + 2);
}
// logic to update position of ball
public void move() {
xPos += dxPos;
yPos += dyPos;
if (xPos < 0) {
xPos = 0;
dxPos = -dxPos;
}
if (xPos + xDim >= Horz) {
xPos = Horz - xDim;
dxPos = -dxPos;
}
if (yPos < 0) {
yPos = 0;
dyPos = -dyPos;
}
if (yPos + yDim >= Vert) {
yPos = Vert - yDim;
dyPos = -dyPos;
}
}
调用Run方法调用repaint
@Override
// run --- paint, sleep, update position - this is being executed
public void run()
{
while (true)
{
System.out.println("I am in RUN");
repaint();
try
{
// sleep thread for 20 milliseconds
Thread.sleep(20);
}
catch (InterruptedException e)
{
// interrupted
System.out.println("Terminated prematurely due to interruption");
}
move();
}
}
但是油漆没有被称为
// draw ball at current position
@Override
public void paint( Graphics g )
{
// THIS IS NOT BEING EXECUTED
System.out.println("I am in paint");
super.paint( g );
g.setColor( Color.BLUE );
g.fillOval( xPos, yPos, 10, 10 );
}
}
为什么?是不是应该重新调用paint方法?
答案 0 :(得分:2)
重绘不会立即调用油漆;它会调度要重新绘制的组件,这会在事件队列到达时立即调用paint。您很可能通过在其上运行计时器循环来阻止event dispatch thread,因此它无法处理绘制事件(或任何其他事件)。在不同的线程上运行循环,或者(更简单,更安全)用Swing Timer替换它:
Timer t = new Timer(20, (ActionEvent e) -> {
move();
repaint();
});
t.start();
答案 1 :(得分:1)
@Boan是对的。 虽然我先看看线程是否已启动:
Thread((Ball)ball);
thread.setDaemon(true);
thread.start();