重绘在 Action Performed 中不起作用

repaint isn't working inside Action Performed

我正在编写一个简单的游戏应用程序,但遇到了这个问题。

"create" 是一个按钮,位于 pmain 面板内,这是单击它时执行的操作:

代码如下:

// ACTION: Create new game
    create.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            if(UA.alreadyOpen()) {
                JOptionPane.showMessageDialog(null,"already open game!");
                return;
            }

            int n = 0;
            String nome = null;

            try {
                n = Integer.parseInt(JOptionPane.showInputDialog(null, "Give the max number of guessers"));
                nome = JOptionPane.showInputDialog(null, "give the name of the game");
                if ( n < 1 || nome == null) System.out.println("mainInterface: input problems"); // TODO ...

                frame.setContentPane(pwait);
                pwait.setVisible(true);
                pmain.setVisible(false);
                frame.pack();
            } catch (NumberFormatException e1) {
                // ???
                e1.printStackTrace();
            } catch (HeadlessException e1) {
                // ???
                e1.printStackTrace();
            } 
                // AND HERE IS THE PROBLEM:
                if(!UA.apriPartita(n, nome)) 
                    System.out.println("ERR creazione partita"); // TODO
                refreshPartite(); 
        }
    });

UA 是此接口class 背后的逻辑-class。被调用的方法 "UA.apripartita(..)" 工作正常,它做了很多事情。 问题是: 我希望界面在单击 "create" 按钮时重新绘制并显示 pwait 面板,但直到返回方法 UA.apripartita(..) 才返回(我猜是 ActionPerformed 函数也被退回了?)。

实际上,我还尝试删除 UA.apripartita(..) 方法调用,它工作正常。 为什么方法在里面就不行了?

提前致谢!

ps。已经尝试放入一些 frame.repaint() 或 frame.invalidate() 但它们似乎什么也没做..

pps。欢迎任何其他关于此代码的好建议!

是的,这是设计使然。在'repaint'的文档中可以清楚的看到。 基本上,它会将一个 "event" 放入 swing 事件队列中 - 与处理点击等的事件队列相同 - 因此 Swing 将依次处理 "action performed",然后是 "repaint",然后是更多代码片段(例如 mouseClicked 或队列中的任何内容)。 这种方法省去了同步的麻烦,尤其是考虑到 swing 组件不是线程安全的。

您可以查找 'paintImmediately',但我真的建议尽可能坚持使用 'repaint'。

这是因为 actionPerformed(...) 方法 运行 在 UI 主事件线程的控制下。因此,当 UA.apripartita() 为 运行ning 时,您的 UI 无法刷新。如果这个方法被设计成运行长时间(比如超过半秒,用户不喜欢动作和效果之间的长时间延迟),你应该考虑使用多线程(如果这个方法必须与UI,想想SwingWorker).