简体   繁体   中英

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

  @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 ?

Repaint doesn't immediately call 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 :

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

@Boan is right. Though I would first take a look whether the thread was started:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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