javaswingpaintcomponentrepaintjlayeredpane

Refreshing JLayeredPane() during a loop


I'm very new to programming a GUI with Java. Swing and AWT are still full of mysteries for me, and I am currently stuck on one of them.

I will try to explain my context without giving all the code: I am using a JFrame which has a JLayeredPane in its content pane. The first Layer contains some buttons arranged in grid and works OK. When I click on some button, I want an image to slide up from the Bottom on the second layer (I thought of using POPUP_LAYER for its fitting name, but I could just use any second layer I suppose). To deal contain the image sliding up, I created a homemade class that extends JPanel. It does some operation on the image itself, and then has an overriden paintComponent method to paint the image at a specific X,Y location in this panel (which takes all screen)

The animation is supposed to be made thanks to a method called when the right button is clicked. This method basically contains a loop which increases the Y component at which the image is painted in the custom JLabel (called popupPanel in my code) of the second layer. I pause the thread at every step to make it possible for the eye to follow the animation.

Thing is, the animation doesn't work at all. The top layer doesn't refresh when it's supposed to. Actually, I see my image popping up only after all the loop is over (It does Nothing for a few sec and then just shows it in the final position, which is definitely not the point). I tried to use repaint() and revalidate() on every thing at each step, from the frame to the popUpPanel. Doesn't work.

I don't know which method to call to refresh this... As it actually works once the loop is done, I suppose it should be possible to have it updated in the middle of the loop...

But how?

I will provide the code for the animation method with the loop. If necessary, I can upload the rest of the code:

public void animpopUp() {
    //getting the initial Y position of the image in the custom panel :
    int y = popUpPanel.getY();
    int ymiddle=y+popUpPanel.getImageSize().height/2;
    //starting a loop to make the image go up gradually
    while(ymiddle>tailleFenetre.height/2) {
        //decreasing Y (going up)
        y--;
        ymiddle=y+popUpPanel.getImageSize().height/2;
        //setting the Y of the popUpPanel, that will be used in the paintComponent to place the image
        popUpPanel.setY(y);
        //revalidating and repainting every fucking thing, just to make sure
        this.revalidate();
        overlayPanel.revalidate();
        popUpPanel.revalidate();
        overlayPanel.repaint();
        popUpPanel.repaint();
        this.repaint();

                    //pausing the loop in order to have a visible animation
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Solution

  • Thanks everyone for your suggestions ! The Thread.sleep(int x) was a terrible idea Indeed. On top of that, I was using a method that I called popupPanel.getY() to get the Y position of the image. But this was actually overriding a built-in method of JPanel, and gave some disastrous results. This is quite dumb, I didn't notice ^^ Solving this and using a Timer did the trick for my animation. Thanks everyone !

    If Sergiy Medvynskyy or MadProgrammer wants to upgrade his comment to an answer so that I can accept it, he's welcome to do so. Otherwise, I'll just accept this answer to mark the problem solved.

    Thanks !