在开发一个C/S端小游戏的时候,页面布局用的是CardLayout,这样就可以在同一个窗口切换页面,但是游戏代码是另一个类,该类需要在JPanle上画N个点,而这个JPanle是在CardLayout切换后,才能显示出来。当点击开始的时候,需要切换页面后,再在JPanle上作画,所以出现了这么一个问题:给START按钮加监听的时候,在切换页面代码下,执行游戏初始化时,是先执行初始化,后执行页面切换。
这个图的START按钮需要执行两个动作:切换页面,初始化游戏代码。最初的代码是这样的:
btnStart.addActionListener(new ActionListener() { public void
actionPerformed(ActionEvent e) { //获取点个数
n=Integer.parseInt(comboBox.getSelectedItem()+""); //切换页面代码 ((CardLayout)
MainJpanel.getLayout()).show(gameMain.getParent(),"game"); //初始化游戏代码
d.reset(n); } });
此时当点击START按钮时,即使切换页面代码执行完毕后,页面仍卡在当前页面,游戏页面需要的JPanle没有显示出来,然后执行了d.reset(n);当执行完毕后,页面还是卡在当前页面,所以当跳到下一个页面的时候,游戏区是空白的。
空空如也。
如何在上一个页面点完START之后,能先切换页面,后初始化游戏区呢?
于是将代码改成了这样:
btnStart.addActionListener(new ActionListener() { public void
actionPerformed(ActionEvent e) { Thread panleListen=new Thread(()->{
while(true){ if(isShow==1){ try { Thread.sleep(100); } catch
(InterruptedException e1) { // TODO 自动生成的 catch 块 e1.printStackTrace(); }
d.reset(n); break; } } }); n=Integer.parseInt(comboBox.getSelectedItem()+"");
//切换页面代码 ((CardLayout)
MainJpanel.getLayout()).show(gameMain.getParent(),"game"); isShow=1;
panleListen.start(); } });
解决原理:每次点击START,当运行到panleListen.start();时,就新建一个线程,该线程会排在图形线程之后再运行,也就是页面切换结束后,再运行d.reset()。
debug的时候就可以看出:
AWT那个线程就是图形界面的线程,只有该线程执行结束后,才能切换页面,而新建的线程将会在AWT线程运行结束后再运行,新线程则负责初始化游戏,所以当执行到新建线程的时候,游戏所需要的JPanle已经切换过来,所以成功解决问题。