Search code examples
javaswinganimationtimer

How do I make a Timer ActionListener wait for another one to stop before starting


I'm trying to make a Serpents and Ladders java application, and I wanted to animate jLabels moving. I've wanted the player to move horizontally then vertically but when I do they happen at the same time. How do I make the second timer (vertical) wait for the horizontal to stop. Here's simplified code.

private void mover(javax.swing.JLabel label,boolean inv,boolean y){

    ActionListener a = new ActionListener() {
        int timesq = 40;
        int delta = 1;
        int deltax = 0;
            @Override
            public void actionPerformed(ActionEvent e) {
                if (inv){
                    delta = -1;
                }
                if (y){
                    deltax = 1;
                }
                int x = label.getX() + delta;
                int y = label.getY() + deltax;
                label.setLocation(x, y);
                label.setText(String.valueOf(x));
                repaint();
                if (--timesq <= 0){
                    Timer timer = (Timer)e.getSource();
                    timer.stop();
                }
            }
        };
    Timer timer = new Timer(20,a);
    timer.start();

}

and the button that triggers the movement

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        setLayout(null);
        jLabel1.setSize(jLabel1.getPreferredSize());
        //add(jLabel1);
        //Horizontal movement
        int b = 5;
        while(b!=0){
            mover(jLabel1,false,false);
            b--;
        }
        //Vertical movement
        b = 2;
        while(b!=0){
            mover(jLabel1,false,true);
            b--;
        }


}

Solution

  • You need to move at Y direction after X direction move is completed :

    private void mover(JLabel label,boolean inv,boolean y){
    
        final int delta = inv ? -1 :1 , deltax =  y ? 1: 0, timesq = 40;
    
        ActionListener moveX = new ActionListener() {
    
            int counterX = timesq, counterY = timesq;
    
            @Override
            public void actionPerformed(ActionEvent e) {
    
                if(--counterX > 0){ //move at x direction 
                    int x = label.getX() + delta;
                    label.setLocation(x, label.getY());
                    label.setText(String.valueOf(x));
                }else if(--counterY > 0){ //move at y direction
                    int y1 = label.getY() + deltax;
                    label.setLocation(label.getX(), y1);
                    label.setText(String.valueOf(y1));
                }else{
                    Timer timer = (Timer)e.getSource();
                    timer.stop();
                }
                repaint();
            }
        };
    
        Timer timer = new Timer(20,moveX);
        timer.start();
    }
    

    enter image description here

    (Copy-paste-run a complete test code from here)