【问题标题】:jPanel doesn't redraw, waiting for server messagesjPanel 不重绘,等待服务器消息
【发布时间】:2014-10-18 19:49:04
【问题描述】:

我正在使用套接字创建一个连接四游戏:1 个服务器正在运行,两个客户端应该连接以玩游戏。由于套接字而无法更新的 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,并在该构造函数中创建了一个新的 PlayField,并在该 PlayField 中创建了一个带有套接字的新连接。

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

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

我在游戏中遇到了类似的问题。当玩家将硬币放入一列时,此动作会发送到服务器,但不会在 jPanel 上绘制硬币。相反,它挂起/冻结。另一个客户端进行他的移动,然后第一个客户端的 jPanel 会更新第一个移动的硬币和第二个移动的另一个玩家的硬币。因此,似乎只有在其他玩家下手后才会下手。

有人有想法吗?我尝试使用this.revalidate() 之类的东西,但我似乎无法在他执行 startGame 方法之前强制 jPanel 更新。

【问题讨论】:

    标签: java swing sockets


    【解决方案1】:

    您的问题是 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;
      }
    }
    

    【讨论】:

    • 谢谢。我会尝试实现 SwingWorkers!
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 2020-07-02
    相关资源
    最近更新 更多