2

我正在编写一个网络游戏客户端,并且在单击按钮时在帧之间切换时遇到问题。

我已经在不同的框架中编写了客户端的每个页面,当从客户端的主页单击菜单按钮时,应该显示这些框架。

以下是我所做的代码..

public class homePage extends JFrame{
       public homePage () {
       initComponents();
      }

      private void initComponents(){
      // the frame and butttons are here....


      GameListBtn.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            this.setVisible(false); // to hide the current home page
            new GameList().start(); // to start new frame called GameList
            // basically the same thing as following code
            // GameList gl = new GameList();
            // gl.setVisible (true);
            // gl.run();
        }
      }
}

  public class GameList extends JFrame{
       public GameList(){
       //Everything about the frame is here
       }

       // this method is for connection
       public void run(){
             try{
              // open socket and initialize input streams, output streams here

             while (true){
                     //process data to and from server
             }
             }// end of try
       } // end of run

       // this method is to display GameList frame and it's connection
       public static void start(){
         GameList frame = new GameList();
         frame.setVisible(true);
         frame.run();
       }

     }

下面这个类只是运行 GameList 框架,它是从一个 main 方法连接的

   public static void main(String[] args) {
    new GameList().start();
    // basically the same thing as following code
    // GameList gl = new GameList();
    // gl.setVisible (true);
    // gl.run();
    }

当我从 main 方法运行它时,我的 GameList 框架可以正常工作。显示GUI,连接建立,数据传输成功。我基本上想要做的是从主页的 ActionListener 调用新的 GameList().start() 方法,因为我可以从 main 方法调用,显示 GameList 并隐藏主页。

当我按照第一个代码中所示执行此操作时,GameList 的 GUI 没有加载(只是变黑),但建立了连接并且数据传输成功。GUI 仅在连接终止时显示。我怀疑原因是 GameList 的 run() 方法中的 while 循环?

但同样,当我从 GameList 类的 main 运行它时,完全相同的东西就像一个魅力。谁能告诉我为什么当我从主页调用它时没有加载 gui,尽管我所做的一切都完全相同。

对不起,如果我的问题听起来很愚蠢,但任何帮助将不胜感激。

4

1 回答 1

3

当您从 调用GameList.start()ActionListener,您处于Swing EDT中,即 Swing 线程处理每个事件,如鼠标或键盘输入,以及组件重绘。当您在 Swing EDT 中执行长流程时,您实际上是在阻塞线程并阻止处理任何其他事件,其中包括重绘事件。这就是为什么您的框架是黑色的并且 GUI 似乎没有加载的原因。当您从 main 方法调用它时没有发生这种情况,因为您不在 EDT 线程中,而是在应用程序的主线程中。

为了解决这个问题,你应该从另一个线程调用 GameList 的 run() 方法,使用Thread.start()Runnable.

一个好的经验法则是,除了 GUI 的东西和一些标志之外,您不应该在事件中添加任何东西,并且永远不要在其中进行任何计算,以保持您的应用程序响应。

另一个规则是,为了避免一般的问题,你应该把你所有的 GUI 东西(包括你的框架的创建)放在线程 EDT 中。如果您需要从另一个线程执行某些操作(如果您没有响应事件或您在 main 方法中),请使用SwingUtilities.invokeLater.

于 2013-02-19T02:54:30.763 回答