【问题标题】:MultiThreading Swing Event Dispatcher Thread多线程 Swing 事件调度程序线程
【发布时间】:2012-11-03 11:21:02
【问题描述】:

我已经有一篇与多线程问题相关的帖子,但我有一些新问题+代码。我有一个多球游戏项目,它需要我解析一个 XML 文件以获取有关球的信息(如大小、速度、初始位置等)。现在,我想创建一个不同的线程来解析 XML 文件,但我想不出办法。这是我的代码:

main() 从这里开始:

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

    }
}

在 BallWorld() 的构造函数中,我有一个内部类 BallContainer(),其中包含一个开始按钮:

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                    
                    }
                }

            }
            });

        }

现在的问题是,如果我将解析过程放在另一个线程中,那么我必须等待 ballsArrayList 填满才能继续应用程序。我正在考虑使用 invokeAndWait() 但我读到无法从事件调度线程调用该方法。那么,我该如何实现呢?或者它甚至值得吗? 另外,我想将移动球的计算(计算 x,y 坐标)移动到一个线程,但同样,我不知道如何实现它。

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

抱歉,这篇文章很长,但多线程对我来说是全新的。我对此有点困惑。

【问题讨论】:

    标签: java multithreading swing event-dispatch-thread


    【解决方案1】:

    文件的初始加载

    我个人会选择以下方法之一

    • 通过在启动期间解析所有文件来增加程序的启动时间。对于一些 XML 文件,此开销可能非常小。如果时间太长,可以考虑显示splash screen
    • 按下开始按钮时加载 XML 文件,但在加载完成之前显示进度条。之后开始游戏。 SwingWorker 可以帮助您解决这个问题。示例可以在Swing documentationhere on SO 中找到。

    更新球位

    如果计算像这里显示的那样简单,我只需使用javax.swing.Timer 定期更新位置,并在事件调度线程上进行计算。

    如果您只是为了练习而想在后台线程上进行计算,我仍然会选择在后台线程上计算位置。计算应该使用只有该后台线程知道的局部变量。计算出新位置后,使用SwingUtilities#invokeLater 在事件调度线程上更新球的位置。这使您可以在paint 操作期间访问该位置,而不必担心线程问题。可能比搞乱锁更容易。

    【讨论】:

      猜你喜欢
      • 2010-10-25
      • 2015-11-06
      • 2014-08-11
      • 2014-01-03
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-11
      相关资源
      最近更新 更多