简体   繁体   中英

Using a Timer within a while loop

I want to use a Timer in a while loop. That is, I want to run the body of a while loop multiple times when it includes a timer within it. However, whenever I do this, the body of the while loop seems to execute and increment before the timer has fired the required amount of times. It is supposed to fire 15 times before the while loop increments, but it seems to be running through the while loop immediately before the timer fires the required amount of times, which I do not understand.

I know it isn't a problem with anything else because when I just run the code through once (ie, without a while loop), it runs fine. The idea is that a JLabel is supposed to be removed and replaced every 1300ms until 15 images are displayed. Once it displays the 15 images, it moves onto the next row of the 2D array, of which there are 60 rows in total.

Any help would be appreciated. I have put the code below.

public class Game implements KeyListener, ActionListener{

    private Preparation prep;
    private Window window;
    private JLabel earthLabel;
    private JPanel panel;
    private Timer timer;
    private JLabel[] arrayOfAllSpaceshipsLabels;
    private int[] arrayOfAllSpaceshipsIndexes;
    private JLabel currentShipLabel;
    private int numberOfBlocks;
    private int firings;
    private int[][] blocks = new int[60][15] //the values in this array have been initalized in another class that is too big and not relevant to my problem

    public Game(){
        window = new Window("Space Game"); 
        runBlock();

    }

    private void runBlock() {
        int blocksLength = blocks.length;
        numberOfBlocks = 0;
        while(numberOfBlocks < blocksLength){
            firings = 0;

            timer = new Timer(1333, new ActionListener(){

                @Override
                public void actionPerformed(ActionEvent e) {

                    if (firings == 15){
                        panel.removeAll(); 
                        panel.revalidate();
                        panel.repaint();
                        timer.stop();
                        System.out.println("Block finished");
                        return;
                    }
                    panel.removeAll(); /*(currentShipLabel);*/
                    panel.revalidate();
                    panel.repaint();

                    currentShipLabel = arrayOfAllSpaceshipsLabels[blocks[numberOfBlocks][firings]];
                    panel.add(currentShipLabel);
                    panel.validate();

                    firings++;

                }
            });
            timer.start();
        }
        numberOfBlocks++;
    }
}

public class Window extends JFrame{

    private JPanel panel;

    public Window(String title){
        SwingUtilities.isEventDispatchThread();
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //this.setBackground(Color.BLACK);
        panel = new JPanel();
        this.add(panel);
        this.pack();
        this.setSize(500,500); //my edit
        panel.setBackground(Color.BLACK);
        this.setVisible(true);

    }

    public JPanel getPanel() {
        // TODO Auto-generated method stub
        return panel;
    }

}

As you have noticed, creating and starting a Timer does not prevent your loop from continuing.

To solve your problem you have to "move" your while loop into the timer action:

private void runBlock() {
    int blocksLength = blocks.length;
    numberOfBlocks = 0;
    timer = new Timer(1333, new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {

            if (firings == 15){
                if (numberOfBlocks == blocksLength)
                    panel.removeAll(); 
                    panel.revalidate();
                    panel.repaint();
                    timer.stop();
                    System.out.println("Block finished");
                    return;
                } else {
                   firings = 0;
                   numberOfBlocks++;
                }
            }
            panel.removeAll(); /*(currentShipLabel);*/
            panel.revalidate();
            panel.repaint();

            currentShipLabel = arrayOfAllSpaceshipsLabels[blocks[numberOfBlocks][firings]];
            panel.add(currentShipLabel);
            panel.revalidate();

            firings++;

        }
    });
    timer.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