JFrame未正确加载

时间:2013-02-19 02:43:59

标签: java swing sockets jframe event-dispatch-thread

我正在编写网络游戏客户端,并且在点击按钮时在帧之间进行更改时会遇到问题。

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

以下是我所做的代码..

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类运行它时,完全相同的东西就像一个魅力。任何人都可以告诉我为什么gui没有加载,当我从主页上调用它时,尽管我所做的一切都完全一样。

很抱歉,如果我的问题听起来很愚蠢,但任何帮助都会受到高度赞赏。

1 个答案:

答案 0 :(得分:3)

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

要解决此问题,您应该使用Thread.start()Runnable从另一个线程调用GameList的run()方法。

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

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