1

I already have a post related to the multithreading issue but I have some new questions+code. I have a multiball game project and it requires me to parse an XML file to obtain information about the ball(like size, speed, initial position etc). Now, I wanted to create a different thread to parse the XML file, but I cannot figure out a way to do it. Here is my code:

main() starts here:

public class BounceBallApp extends JFrame{

    public BounceBallApp()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("BounceBallApp");          
        setSize(300,300);       
        setVisible(true);
        add(new BallWorld());
        validate();
    }

    public static void main(String[] args) 
    {
        /*Create main GUI in the Event Dispatch Thread*/
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                new BounceBallApp(); //main frame
            }
        });

    }
}

Within the constructor for BallWorld(), I have an inner class BallContainer(), which contains a Start button:

jbtStart.addActionListener(new ActionListener()
            {public void actionPerformed(ActionEvent e)
            {
                //Populate the ballList arraylist
                if(filePathField.getText().equals(" "))
                {
                    JOptionPane.showMessageDialog(null, "Please input the XML file","Information", JOptionPane.INFORMATION_MESSAGE);        
                }
                else
                {
                    XMLFilePath = filePathField.getText();

                    ballList = new BallList(XMLFilePath);//I want to put this in a thread
                    JOptionPane.showMessageDialog(null,"Game started!","Bouncing Balls",JOptionPane.INFORMATION_MESSAGE);
                    for(Ball ball:ballList.ballsArrayList) 
                    {
                        timer.setDelay(1000/ball.getSpeed()); //change the delay of the timer to the ball's speed
                        timer.start(); //start the timer
                        bTimer = true; //timer is now on                    
                    }
                }

            }
            });

        }

Now the problem is that if I put the parsing process in another thread, then I have to wait for the ballsArrayList to fill before I can continue with the application. I was thinking of using invokeAndWait() but I read that that method cannot be called from the Event Dispatch Thread. So, How can I achieve this? Or is it even worthwhile? Also, I wanted to move the calculation for moving the ball (calculating the x,y coords) to a thread, but again, I don't know how to implement it.

for(Ball ball:ballList.ballsArrayList) 
            {
                ball.draw(g);                   
                ball.move(ballContainerWidth,ballContainerHeight,buttonPanel.getHeight());                  
            }

public void move(int ballContainerWidth,int ballContainerHeight,int buttonPanelHeight)
 {

     if((this.getX()+this.getsize()+this.getDx()) > ballContainerWidth) 
        {
            this.setDx(-Math.abs(this.getDx()));
        }

        //the height/depth to which the balls can bounce is the (main ball container height) minus (button panel height)
        if((this.getY()+this.getsize()+this.getDy()) > ballContainerHeight-buttonPanelHeight) 
        {
            this.setDy(-Math.abs(this.getDy()));
        }

        if((this.getX()-this.getsize()) < 0 )
        {
            this.setDx(Math.abs(this.getDx()));
        }

        if((this.getY()-this.getsize()) < 0 )
        {
            this.setDy(Math.abs(this.getDy()));
        }


        int newX = (int)Math.round((this.getX()+this.getDx()));
        int newY = (int)Math.round((this.getY()+this.getDy()));
        this.setX(newX);
        this.setY(newY);
 }

Sorry for the long post, but multithreading is all new to me. I am a bit confused about it.

1 Answers1

2

Initial loading of the files

I personally would opt for one of the following approaches

  • Increase the start-up time of your program by parsing all the files during start-up. For a few XML files this overhead might be very small. If it takes too long, you can consider showing a splash screen
  • Load the XML files when the start button is pressed, but show a progress bar until the loading is done. Start the game afterwards. A SwingWorker can help you with this. Examples can be found in the Swing documentation or here on SO.

Updating of the ball position

If the calculation is as easy as what is shown here, I would simply use a javax.swing.Timer to update the position on regular time intervals, and do the calculation on the Event Dispatch Thread.

If you want to do the calculation on a background thread just for the exercise, I would still opt for a calculation of the position on a background thread. The calculation should be using local variables which are only know to that background thread. Once the new position is calculated, update the position of the ball on the Event Dispatch Thread using SwingUtilities#invokeLater. This allows you to access the position during the paint operation without having to worry about threading issues. Probably easier then messing around with locks.

Community
  • 1
  • 1
Robin
  • 36,233
  • 5
  • 47
  • 99