简体   繁体   中英

Java Application : repaint isn't executed in While Loop?

I've got this Thread that is supposed to Update the game's elements, ie repaint, wait for a bit of time then do it again, the problem is that it doesn't repaint. I've tested every other component, they all works, but the paint method is only called once ( Because the components are painted ), even if I call repaint() in the loop. Here's my Code of the Loop:

Thread t = new Thread(){
public void run()
    {
        mouse.init();
        while(true)
        {                                       
         mouse.Refresh();//Adds Dirty Regions in the RepaintManager   
        SwingUtilities.invokeLater(new Runnable() {    
       @Override 
       public void run() {              
          //What here? 
       }
    });


        }            
    }
};

No need to see the thread or anything, it loops.

Here's the Paint Method:

   @Override
public void paint(Graphics g)
{

            EndTime = System.currentTimeMillis();//For the FPS Counter
    Time = EndTime - StartTime;
    FPS = (byte) (1000/Time);   
    TotalFPS += FPS;
    TotalFrame++;   
            JPT.AverageFPs.setText( "" + TotalFPS/TotalFrame);
            JPT.CurrentFPS.setText( "" + FPS);
    StartTime = System.currentTimeMillis();

    g.clearRect(0,0,dim.width,dim.width); 


    for(int x = 0; x < Variables.Width; x++)
    {
        for(int y = 0; y < Variables.Height; y++)
        {
            if(Variables.Map[x][y] == 0)
            { 
                g.setColor(new Color(0x613F37));
                g.drawLine(x, y, x, y);
            }
            else if(Variables.Map[x][y] == 1)
            { 
                g.setColor(Color.black);
                g.drawLine(x, y, x, y);
            }
            else if(Variables.Map[x][y] == 2)
            { 
                g.setColor(new Color(0xDEDEDE));
                g.drawLine(x, y, x, y);
            }

        }
    }

        g.setColor( new Color(0.5f, 0.5f, 0.5f, 0.5f));
        g.fillRect(Variables.CurrentX, Variables.CurrentY, Variables.Zoom, Variables.Zoom);





}

Thanks alot in advance.

Also I want to point out that I made this Game as an Applet before and it was working like a charm, but now I need it as Application.

Try paintImmediately(0, 0, getWidth(), getHeight());

This is because the RepaintManager collapses multiple requests into a single repaint for members of a component tree.

I think your data is not synchronized between threads (there is not enough code to determine if this the case tough).

repaint is called on the Swing EDT and update.UpdateGravity() is called in your main thread. I guess your update changes Variable , but do you ever synchronize this data structure such that the Swing EDT sees the updated value?

EDIT :

here is what you should do:

variables = update.updateGravity();  // runs in your main thread
SwingUtilities.invokeLater(new Runnable() {    
   @Override public void run() {
       yourCustomSwingComponent.update(variables);   // will run on the Swing EDT
   }
}

and yourCustomSwingComponent contains the paint() method you have. There is a rule in Swing that the state of any Swing component can only be modified (or read) from the Swing EDT.

You should read about Swing and multi-threading. Actually, you must read about multi-threading to use Swing.

Not answering the question directly, but it might be very useful to have a look at some of the existing Java2D animation libraries. For example, Trident originally developed by Kirill Grouchnikov . If there is a reason not to use it, at least it could be useful to inspect the source and borrow some ideas.

Also, Swing Timer could be of some interest for implementing time based Swing related actions.

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