重绘在 Action Performed 中不起作用
repaint isn't working inside Action Performed
我正在编写一个简单的游戏应用程序,但遇到了这个问题。
- pwait 和 pmain 是 2 个面板
- frame为主框架
"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
).
我正在编写一个简单的游戏应用程序,但遇到了这个问题。
- pwait 和 pmain 是 2 个面板
- frame为主框架
"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
).