从 JButton 调用方法会冻结 JFrame?

我正在为班级做一个基本的乒乓球游戏.我有 Pong 工作,并且在启动时有一个 GUI 显示,不幸的是我似乎无法从开始 JButton 开始游戏.我已经评论了代码的问题所在,并删除了不相关的代码.

 frame.add(GUIPanel);JButton startButton = new JButton("开始!");GUIPanel.add(startButton, BorderLayout.CENTER);startButton.addActionListener(new ActionListener() {公共无效actionPerformed(ActionEvent e){frame.getContentPane().remove(GUIPanel);框架.验证();frame.repaint();绘图板 = 新绘图板();drawPanel.requestFocus();frame.getContentPane().add(BorderLayout.CENTER, drawPanel);//这是冻结它的部分,其他一切正常//除了 playGame 方法没有被调用.如果我删除整个//startButton 和诸如此类的东西我可以调用 playGame 并且它工作得很好.玩游戏();}});}

有什么想法吗?

解决方案

Swing 是一个单线程框架.

也就是说,对 UI 的所有交互和修改都将在事件调度线程的上下文中进行.任何阻塞此线程的东西都会阻止它处理重绘请求和用户输入/交互等.

我的猜测是 playGame 正在使用类似 Thread.sleep 或某种 while(true) 的东西并且阻塞了 EDT,导致你的程序看起来好像被冻结了

阅读Swing 中的并发了解更多详情.p>

一个简单的解决方案是使用 Swing Timer 充当游戏循环.每次它滴答作响时,您都会更新游戏的状态并在游戏组件上调用(类似于)repaint

I'm doing a basic Pong game for a class. I have the Pong working, and I have a GUI display on startup, unfortunately I can't seem to start the game from the start JButton. I've commented where the problem is on the code, and removed irrelevant code.

 frame.add(GUIPanel);
        JButton startButton = new JButton("Start!");     
        GUIPanel.add(startButton, BorderLayout.CENTER);
        startButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
         { 
             frame.getContentPane().remove(GUIPanel);
             frame.validate();
             frame.repaint();

             drawPanel = new DrawPanel();
             drawPanel.requestFocus();
             frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
              //This is the part that freezes it, everything else works fine
              //except that the playGame method isn't called. If I remove the whole
              //startButton and whatnot I can call playGame and it works perfectly.                                                                                    
              playGame();          
           }
         }); 
         }

any ideas?

解决方案

Swing is a single threaded framework.

That is, all interactions and modifications to the UI are to be made from within the context of the Event Dispatching Thread. Anything that blocks this thread will prevent it from processing, amongst other things, repaint requests and user input/interactions.

My guess is that playGame is using something like Thread.sleep or some kind of while(true) and is blocking the EDT, causing your program to appear as if it's frozen

Have a read through Concurrency in Swing for more details.

A simple solution would be to use a Swing Timer to act as you game loop. Each time it ticks, you would update the state of your game and call (something like) repaint on you game's component

相关文章