Results 1 to 6 of 6
  1. #1
    al_Marshy_1981 is offline Senior Member
    Join Date
    Feb 2010
    Location
    Waterford, Ireland
    Posts
    748
    Rep Power
    5

    Default JFrame Hanging When Called From Another Class

    hi I am having trouble with JFrame. I have 3 classes:
    1. ServerGui - This acts as a login gui, when details are entered it then initialises the class TheServer.
    2. TheServer - This class the initiallises the class ServerGuiReal amongst other things.
    3. ServerGuiReal acts as the gui for any information created in TheServer class.

    The problem is that when I initialise the class called ServerGuiReal from the class TheServer, the JFrame i built in ServerGuiReal hangs i.e It just shows the the frame but doesn't display any of its contents and the x button in the top right does not work either even though i have setDefaultCloseOperation(JFrame.Exit_On_Close);

    My wild guess is that alll the resources have not been released from the class ServerGui or something like that. Or maybe it has something to do with the inner class called Listener inside the ServerGui class. But ive really no idea at all to be honest.
    Was wondering if anybody can see any problems in my code. Thanks in advance

    TheServerGui class:

    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.GridLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    
    import javax.swing.*;
    import javax.swing.border.BevelBorder;
    import javax.swing.border.Border;
    
    public class ServerGui {
    	
    	private JFrame servFrame;
    	private ImagePanel servPanel;
    	private JPanel pan1;
    	private JPanel pan2;
    	private JButton myButton;
    	private JButton exit;
    	private JLabel myLabel;
    	private JTextField userName;
    	private JPasswordField password;
    	private JTextField port;
    	private File img;
    	private GridBagConstraints c;
    	public ServerGui()
    	{
    		c=new GridBagConstraints();
    		userName=new JTextField(20);
    		password=new JPasswordField(20);
    		port=new JTextField(20);
    
    		img=new File("images\\backg.gif");
    
    		servFrame=new JFrame("Server Login");
    		servPanel=new ImagePanel(img);
    
    		pan1=new JPanel();
    		pan1.setLayout(new GridLayout(3,2,5,5));
    		pan1.setBackground(new Color(0,0,0,0));
    
    		pan2=new JPanel();
    		pan2.setLayout(new GridLayout(1,3,5,5));
    		pan2.setBackground(new Color(0,0,0,0));
    
    		servPanel.setLayout(new GridBagLayout());
    		servPanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
    		c.insets=new Insets(10,10,10,10);
    		servFrame.getContentPane().add(servPanel,BorderLayout.CENTER);
    
    		myButton=new JButton("Login");
    		exit=new JButton("Exit");
    		pan1.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,Color.GRAY,Color.BLACK));
    		pan1.add(myLabel=new JLabel("Enter Username",JLabel.TRAILING));
    		myLabel.setForeground(Color.WHITE);
    		pan1.add(userName);
    		pan1.add(myLabel=new JLabel("Enter Password",JLabel.TRAILING));
    		myLabel.setForeground(Color.WHITE);
    		pan1.add(password);
    		pan1.add(myLabel=new JLabel("Enter Port",JLabel.TRAILING));
    		myLabel.setForeground(Color.WHITE);
    		pan1.add(port);
    		
    		pan2.add(exit);
    		pan2.add(myButton);
    		c.gridx=0;
    		c.gridy=0;
    		servPanel.add(pan1,c);
    		c.gridy=1;
    		c.gridx=0;
    		c.anchor=GridBagConstraints.FIRST_LINE_END;
    		servPanel.add(pan2,c);
    		servFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		servFrame.setSize(500,300);
    		exit.addActionListener(new Listener());
    		myButton.addActionListener(new Listener());
    		servFrame.setVisible(true);
    	}
    	public void runServer(int port)
    	{
    		servFrame.dispose();
    		new TheServer(port);
    	}
    	
    	private class Listener implements ActionListener
    	{	
    		public void actionPerformed(ActionEvent ae)
    		{
    			if(ae.getActionCommand().equals("Exit"))
    			{
    				servFrame.dispose();
    			}
    			else if(ae.getActionCommand().equals("Login"))
    			{
    				//need to check if password is good before proceeding
    				int newPort=Integer.parseInt(port.getText());
    				runServer(newPort);
    			}
    		}	
    	}
    	
    }
    TheServer class

    Java Code:
    import java.io.*;
    import java.net.*;
    import java.util.ArrayList;
    
    public class TheServer {
    
    	private ArrayList<Socket>list;
    	private ArrayList<String>userNames;
    	private Socket client;
    	private ServerSocket server;
    	private int port;
    	private ServerGuiReal gui;
    	private String info;
    	private String waitMsg;
    	public TheServer(int port)
    	{
    		runGui();
    		list=new ArrayList<Socket>();
    		userNames=new ArrayList<String>();
    		waitMsg="Waiting for Connection on Port: "+port;
    		this.port=port;
    		try{
    		server=new ServerSocket(port);
    		while(true)
    		{
    		client=server.accept();
    		list.add(client);
    		
    		info="Connection made on Port: "+port+"\n"+
    					"Connection made from: "+client.getInetAddress().getHostAddress()+"\n";
    		}
    		}catch(IOException e)
    		{
    			e.printStackTrace();
    		}
    	}
    	
    	public void runGui()
    	{
    		gui=new ServerGuiReal(waitMsg);
    	}
    	
    }
    ServerGuiReal class

    Java Code:
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.GridBagLayout;
    import java.io.File;
    
    import javax.swing.*;
    public class ServerGuiReal {
    
    	private String info;
    	private JFrame frame;
    	private JTextArea area;
    	private JScrollPane scroll;
    	private ImagePanel pan;
    	private File img;
    	
    	public ServerGuiReal(String info)
    	{
    		this.info=info;
    		frame=new JFrame("Server");
    		img=new File("images\\backg.gif");
    		pan=new ImagePanel(img);
    		pan.setLayout(new GridBagLayout());
    		
    		area=new JTextArea();
    		area.setLineWrap(true);
    		area.setEditable(false);
    		
    		scroll=new JScrollPane(area);
    		scroll.setPreferredSize(new Dimension(300,400));
    		
    		pan.add(scroll);
    
    		frame.getContentPane().add(pan);
    		frame.setSize(500,600);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setVisible(true);
    		
    		//append the first server message to area i.e waiting for connection
    		area.append(info+"\n");
    	}
    	
    	public void setDetails(String details)
    	{
    		area.append(details+"\n");
    	}
    
    }

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    You've got a Swing concurrency issue where your program is putting Swing's event dispatch thread on hold and preventing the Swing app from painting or interacting. Read this tutorial for a complete description of the problem and a solution: Concurrency in Swing.

    Much luck.

  3. #3
    al_Marshy_1981 is offline Senior Member
    Join Date
    Feb 2010
    Location
    Waterford, Ireland
    Posts
    748
    Rep Power
    5

    Default

    Where in my code is the concurrency issue happening? :confused: If I could track that down it will help me understand those tutorials a bit better. Thanks for the help so far.

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Please read the while tutorial first and you'll better understand. It's the whole program as you're doing your server processing as the same thread as the EDT. Again, the tutorial will help you not do this.

  5. #5
    al_Marshy_1981 is offline Senior Member
    Join Date
    Feb 2010
    Location
    Waterford, Ireland
    Posts
    748
    Rep Power
    5

    Default

    Thanks a million Fubarable I fixed it.

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Congrats on solving it, and hh shucks, I sort of wasted my time creating an SSCCE. But if it helps anyone else, here's a simplified version of what you were doing initially:
    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    
    public class ServerGui1 {
    
      private JFrame servFrame;
      private JPanel pan2;
      private JButton myButton;
    
      public ServerGui1() {
        servFrame = new JFrame("Server Login");
        pan2 = new JPanel();
        servFrame.getContentPane().add(pan2, BorderLayout.CENTER);
    
        myButton = new JButton("Login");
        pan2.add(myButton);
        servFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        servFrame.setSize(500, 300);
        myButton.addActionListener(new Listener());
        servFrame.setVisible(true);
      }
    
      public void runServer(final int port) {
        servFrame.dispose();
        new TheServer1(port);
      }
    
      private class Listener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
          int newPort = 100;
          runServer(newPort);
        }
      }
    
      public static void main(String[] args) {
        new ServerGui1();
      }
    
    }
    
    class TheServer1 {
    
      private static final int MAX = 40;
      private ServerGuiReal1 gui;
      private String waitMsg;
    
      public TheServer1(int port) {
        waitMsg = "Waiting for Connection on Port: " + port;
        runGui(waitMsg);
    
        // simulate a long-running and blocking task
        for (int i = 0; i < MAX; i++) {
          gui.setDetails("details: " + i);
    
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
    
        }
        gui.setDetails("done");
      }
    
      public void runGui(final String waitMsg) {
        gui = new ServerGuiReal1(waitMsg);
      }
    
    }
    
    class ServerGuiReal1 {
      private JFrame frame;
      private JTextArea area;
      private JScrollPane scroll;
      private JPanel pan;
    
      public ServerGuiReal1(String info) {
        frame = new JFrame("Server");
        pan = new JPanel();
        pan.setLayout(new GridBagLayout());
    
        area = new JTextArea();
        area.setLineWrap(true);
        area.setEditable(false);
    
        scroll = new JScrollPane(area);
        scroll.setPreferredSize(new Dimension(300, 400));
        pan.add(scroll);
    
        frame.getContentPane().add(pan);
        frame.setSize(500, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    
        area.append(info + "\n");
      }
    
      public void setDetails(String details) {
        area.append(details + "\n");
      }
    }


    And here's a version that's more Swing thread-safe. Please see comments:
    Java Code:
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingUtilities;
    
    public class ServerGui2 {
    
      private JFrame servFrame;
      private JPanel pan2;
      private JButton myButton;
    
      public ServerGui2() {
        servFrame = new JFrame("Server Login");
        pan2 = new JPanel();
        servFrame.getContentPane().add(pan2, BorderLayout.CENTER);
    
        myButton = new JButton("Login");
        pan2.add(myButton);
        servFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        servFrame.setSize(500, 300);
        myButton.addActionListener(new Listener());
        servFrame.setVisible(true);
      }
    
      public void runServer(final int port) {
        servFrame.dispose();
        
        // call the background task in a background thread
        new Thread(new Runnable() {
          public void run() {
            new TheServer2(port);
          }
        }).start();
      }
    
      private class Listener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
          int newPort = 100;
          runServer(newPort);
        }
      }
    
      private static void createAndShowUI() {
        new ServerGui2();
      }
    
      public static void main(String[] args) {
        // call the Swing app on the EDT
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            createAndShowUI();
          }
        });
      }
    
    }
    
    class TheServer2 {
    
      private static final int MAX = 40;
      private ServerGuiReal2 gui;
      private String waitMsg;
    
      public TheServer2(int port) {
        waitMsg = "Waiting for Connection on Port: " + port;
        runGui(waitMsg);
    
        // simulate a long-running and blocking task
        for (int i = 0; i < MAX; i++) {
          gui.setDetails("details: " + i);
    
          try {
            Thread.sleep(500);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
    
        }
        gui.setDetails("done");
      }
    
      public void runGui(final String waitMsg) {
        try {
          // create new Swing app on the EDT  
          // need to use invoke and wait as we don't want the background app
          // sending messages to the GUI until the GUI is non-null and ready
          // to receive the messages
          SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
              gui = new ServerGuiReal2(waitMsg);
            }
          });
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    
    }
    
    class ServerGuiReal2 {
      private JFrame frame;
      private JTextArea area;
      private JScrollPane scroll;
      private JPanel pan;
    
      public ServerGuiReal2(String info) {
        frame = new JFrame("Server");
        pan = new JPanel();
        pan.setLayout(new GridBagLayout());
    
        area = new JTextArea();
        area.setLineWrap(true);
        area.setEditable(false);
    
        scroll = new JScrollPane(area);
        scroll.setPreferredSize(new Dimension(300, 400));
        pan.add(scroll);
    
        frame.getContentPane().add(pan);
        frame.setSize(500, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    
        area.append(info + "\n");
      }
    
      public void setDetails(String details) {
        area.append(details + "\n");  // this method is thread safe
      }
    }

Similar Threads

  1. update() gets never called
    By flok in forum AWT / Swing
    Replies: 8
    Last Post: 10-19-2009, 04:45 PM
  2. My constructor not called
    By rdtindsm in forum New To Java
    Replies: 2
    Last Post: 09-20-2009, 01:38 AM
  3. Replies: 8
    Last Post: 03-21-2009, 09:34 AM
  4. Return objects called
    By MV1 in forum New To Java
    Replies: 7
    Last Post: 03-11-2009, 07:16 AM
  5. Replies: 0
    Last Post: 07-03-2008, 08:05 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •