2014-10-18 40 views
0

我正在创建一个连接四个游戏与套接字:1服务器运行和两个客户端,应该连接玩游戏。我对jPanels有些麻烦,因为套接字(我认为)没有更新。jPanel不重绘,等待服务器消息

当游戏(客户端)启动时,您会得到一个带有IP地址输入框和提交按钮的jPanel。如果按下提交按钮,我想显示一条消息,说明游戏正在准备中,并等待第二位玩家加入。

submitButton.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (!input.getText().equals("")) try { 
      prefs.put("SavedIp", input.getText()); 
      errorLabel.setText("Preparing game and waiting for other players..."); 
      parentLayout.startGame(input.getText()); 
     } catch (SocketTimeoutException timeout) { 
      errorLabel.setText("Server timed out."); 
     } catch (IOException ioeException) { 
      errorLabel.setText("Server not found!"); 
     } finally { 
      setTheCursor(Cursor.getDefaultCursor()); 
     } 
     else errorLabel.setText("Enter an IP adress"); 
    } 
});  

然而,在startGame方法中,新的GamePanel被创建,并且在该构造一个新的游戏区域被创建并在该球场一个新的连接与插座创建。

连接后,它会运行方法checkForNextAction以查看它是否从服务器接收到消息。它会一直运行该方法,直到服务器发送消息。

问题:我按提交时看不到消息。相反,它会挂起,直到第二个玩家加入,然后服务器发送一条消息,指出游戏可以开始并显示游戏板。我无法立即将消息更改为我设置的文本吗? jPanel可能不会更新,因为它正在运行一个方法并等待消息到来。

我在游戏中有类似的问题。当玩家将一枚硬币放入一列时,这一举动被发送到服务器,但硬币并未在jPanel上绘制。相反,它会挂起/冻结。另一个客户做出他的举动,然后只有第一个客户的jPanel得到第一步的硬币和第二步的其他玩家的硬币更新。所以看起来这个举动只有在其他球员进行动作之后才会被吸引。

有没有人有想法?我试图使用this.revalidate()等等,但我似乎无法强制jPanel更新,然后执行startGame方法。

回答

3

您的问题是Swing线程问题,因为您的代码等待,暂停Swing事件线程,冻结所有GUI绘画和用户交互。解决方案:使用后台线程(例如SwingWorker)来等待您。请查看Concurrency in Swing


喜欢的东西,

submitButton.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     if (!input.getText().equals("")) { 
      prefs.put("SavedIp", input.getText()); 
      errorLabel.setText("Preparing game and waiting for other players..."); 

      final ParentWorker parentWorker = new ParentWorker(input.getText()); 
      parentWorker.addPropertyChangeListener(new PropertyChangeListener() { 

        @Override 
        public void propertyChange(PropertyChangeEvent evt) { 
         if (SwingWorker.StateValue.DONE == evt.getNewValue()) { 
          setTheCursor(Cursor.getDefaultCursor()); 
          try { 
          parentWorker.get(); 
          } catch (InterruptedException | ExecutionException e) { 
          e.printStackTrace(); 
          // here's where you check for your socket or io exceptions 
          } 
         } 
        } 
       }); 
      parentWorker.execute(); 
      // parentLayout.startGame(input.getText()); 
     } else { 
      errorLabel.setText("Enter an IP adress"); 
     } 
    } 
    }); 

和...

class ParentWorker extends SwingWorker<Void, Void> { 
    private String text; 

    public ParentWorker(String text) { 
    this.text = text; 
    } 

    @Override 
    protected Void doInBackground() throws Exception { 
    parentLayout.startGame(text); 
    return null; 
    } 
} 
+0

感谢。我会尽力实施SwingWorkers! – JSS 2014-10-18 20:20:08

+0

@JSS:祝你好运! – 2014-10-18 20:25:13