我正在制作一个小游戏,我已经实现了一个保存游戏的保存功能(通过将信息写入新的XML文件)。保存需要几秒钟,我想做以下事情:当程序保存游戏时,我想改变JPanel的外观,当它完成保存时,我想回到另一个页面(显示另一个JPanel)。 我有以下代码:
confirm.addActionListener(new ActionListener () {
@Override
public void actionPerformed(ActionEvent e){
String fileNaam = saveGame.getText();
//This method changes the look of the panel
changePanel();
//This method saves the game
model.saveGame(fileNaam);
//This method takes the user back to a previous page
controller.viewTeamPage();
}
});
发生的事情是游戏被保存并且用户被带回到了teampage,但面板永远不会被更改。 changePanel()方法确实有效,所以这不是问题,但似乎永远不会执行。我想知道是否有人知道如何解决这个问题。
编辑:
private void changePanel () {
panel.removeAll();
panel.repaint();
panel.revalidate();
}
这是更改面板外观的方法,现在我只需删除面板上的所有内容以保持简单。 此外,保存不是在单独的线程中完成的,我应该看一下吗?
编辑2:我通过使用线程来保存游戏并在保存完成后返回到teampage。请参阅下面的代码。
confirm.addActionListener(new ActionListener () {
@Override
public void actionPerformed(ActionEvent e){
final String fileNaam = saveGame.getText();
changePanel();
Thread t = new Thread (new Runnable () {
@Override
public void run() {
model.saveGame(fileNaam);
controller.viewTeamPage();
}
});
t.start();
}
});
答案 0 :(得分:1)
如果您要更改同一个面板而不是初始化新面板,那么我认为问题是您需要调用panel.revalidate或panel.repaint我认为。我为一个程序生成项目做了一个演示,我必须这样做才能让我的面板发生变化。
答案 1 :(得分:0)
actionPerformed()
内完成; controller.viewTeamPage()
。一种简单的方法是将“controller”对象传递给自定义线程的构造函数,以便在保存游戏后进行调用。在这种情况下,步骤1非常重要,因为您在方法actionPerformed()
中进行的所有调用都是在UI线程中进行的,从而阻止整个UI刷新,直到方法返回为止。即使在repaint()
中单独调用changePanel()
也不够,因为它只是“安排”您面板上的刷新,这只会在actionPerformed()
返回后发生。但是,如果您将最耗时的调用放在一个单独的线程中,actionPerformed()
会快速返回,从而允许在游戏保存线程正在执行其工作时刷新UI。