2

I am writing a networked game client and having problems when changing between frames when buttons are clicked.

I have written each page of the client in different frames and those frames should be displayed when menu buttons are clicked from home page of client.

Following are the codes that I have done..

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();
       }

     }

This following class is just run GameList frame and it's connection from a main method

   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();
    }

My GameList frame works properly when I just run it from main method. It GUI is displayed, connection is established and data transmission is successful. What I basically want to do is to call the new GameList().start() method from an ActionListener of homepage as I can call from main method, display the GameList and hide the homepage.

When I do this as I have shown in first code, the GUI of GameList is not loaded(just went black), but the connection is established and data transmission is successful. The GUI is displayed only when connection is terminated. I am suspecting the reason is the while loop inside the run() method of GameList ??

But again, the exact same thing works like a charm when I run it from main for GameList class. Can anyone tell me why the gui is not loaded when i call it from homepage eventhough everything i am doing is exactly the same.

Sorry if my question sounds dumb, but any help will be highly appreciated.

mKorbel
  • 109,525
  • 20
  • 134
  • 319
Ken
  • 287
  • 3
  • 5
  • 15

1 Answers1

3

When you call GameList.start() from the ActionListener, you are in the Swing EDT, that is the thread were Swing process every event like mouse or keyboard input, but also component repainting as well. When you are doing a long process in the Swing EDT, you are actually blocking the thread and you prevent any other event to be processed, and amongst them the repaint events. This is why your frame is black and the GUI appears to be not loaded. This was not happening when you called it from the main method because you were not in the EDT thread, but the main thread of the application.

To solve this, you should call the run() method of GameList from another thread using Thread.start() and a Runnable.

A good rule of thumb is that you should not put in events anything more than GUI stuff and some flags, and never do any calculation in it, in order to keep your application responsive.

Another rule is that to avoid problems in general, you should put all you GUI stuff (including the creations of your frames) in the Thread EDT. If you need to do something from another thread (if you are not responding to an event or your are in the main method), use SwingUtilities.invokeLater.

Cyrille Ka
  • 15,328
  • 5
  • 38
  • 58