简体   繁体   English

调用repaint不会导致在线程中调用paint方法

[英]calling repaint does not result in paint method being called in thread

The following thread is being executed as a result of a mouse pressed event: 由于鼠标按下事件,正在执行以下线程:

// 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 method is called which calls repaint 调用Run方法,该方法调用重绘

  @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();               
    }   
  }

But paint is not being called 但是油漆没有被称为

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

why is that ? 这是为什么 ? isn't repaint supposed to call paint method ? 重涂不是应该调用paint方法吗?

Repaint doesn't immediately call paint; 重涂不会立即调用paint; it schedules the component to be repainted, which will cause paint to be called as soon as the event queue can get to it. 它计划要重新绘制的组件,这将导致事件队列到达后立即调用绘制。 Most likely you are blocking the event dispatch thread by running the timer loop on it, so it cannot process paint events (or any other events). 您很可能通过在其上运行计时器循环来阻止事件分发线程 ,因此它无法处理绘画事件(或任何其他事件)。 Run the loop on a different thread, or (easier, safer) replace it with a Swing Timer : 在另一个线程上运行循环,或者(更轻松,更安全)将其替换为Swing Timer

Timer t = new Timer(20, (ActionEvent e) -> {
    move();
    repaint();
});
t.start();

@Boan is right. @Boan是正确的。 Though I would first take a look whether the thread was started: 尽管我首先看一下线程是否已启动:

Thread((Ball)ball);
thread.setDaemon(true);
thread.start();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM