1

I first asked this question, which I figured out how the EDT works and started reading more on swing and worker threads by reading this. I started to get an understanding of how they work and got my code fixed to where it would run. Now I'm trying to get the information from my worker thread (the server) to update my GUI. I run into a problem though I can't seem to work my way around. The problem is I need to keep listening for new client (As the server is suppose to handle multiple clients) but because that is in a while loop I never hit the return of my worker thread. I can't see any other way to set it up either. Could someone take a look at my code and suggest a way I might be able to get this to work?

Main.class

package com.sever.core;

import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;

import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Main { 

private SocketManager network;
private Window window;

public static void main(String[] args){         
    Main main = new Main();
    main.runGUI();
    main.runServer();
}

private void runGUI(){

    //Runs the swing components in the EDT.
    SwingUtilities.invokeLater(new Runnable(){
        @Override
        public void run() {
            window = new Window();
            window.setVisible(true);
        }       
    });
}

private void runServer(){

    //Runs the Server process on a worker thread.
    SwingWorker<String, String> server = new SwingWorker(){
        @Override
        protected Object doInBackground() throws Exception {    
            network = new SocketManager(25595);
            /*
             * Here is the problem. I need to keep running this code so,
             * that I can let multiple clients connect. However,
             * it then never reaches the return.
             */
            while(true){
                try {   
                    network.setSocket(network.getServerSocket().accept());
                    addUser(network.getSocket());
                } catch (Exception e) {
                    System.out.println("Failed to connect.");
                }
            }
            return network.getMessage(); 
        }

        @Override
        protected void done(){
            try {
                window.updateChat(get().toString());
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    };
    server.run();
}

private void addUser(Socket s){
    try {
        Scanner input = new Scanner(s.getInputStream());
        network.addUser(input.nextLine());
    } catch (Exception e) {

    }
}
}
Community
  • 1
  • 1
cgasser
  • 603
  • 2
  • 11
  • 24
  • You don't need to use a SwingWorker for your server because the 'runServer()' method never gets called from the EDT. So its never started on the EDT, therefor you don't have to run it off the EDT. – Jasper Siepkes May 14 '12 at 20:28
  • @JasperSiepkes IN my 'runServer()' method I use the the ServerSocket method accept() which will try and run on the EDT. 'network.setSocket(network.getServerSocket.accept())' – cgasser May 14 '12 at 20:33
  • Why do you run a socket acceptor on the EDT ? Basically the socket acceptor should run on a normal thread and fire events the events (if needed) on the EDT, but the whole thing should run off a normal thread, not the EDT. You can use the 'SwingUtilities.invokeLater()' method from any other thread. You don't need to do it from a SwingWorker. – Jasper Siepkes May 14 '12 at 21:03
  • @JasperSiepkes I was lead to believe the socket accept() method, since it continuously waits, ran on the EDT by default. When I didn't have it in a worker thread my program froze because both swing and the accept() method were on the EDT, so I had to move the accept() method to a worker thread. This is the question I was told to do this on [link here](http://stackoverflow.com/a/10575855/1305463) – cgasser May 14 '12 at 21:09
  • 1
    By defeault nothing runs on the EDT; It runs on a standard thread. You schedule things for execution on the EDT with 'SwingUtilities.invokeLater()'. The EDT is where all the Swing magic MUST happen. SwingWorkers are used to easily get 'off' the EDT. However you could use any Thread for this purposes. SwingWorkers are just really convenient because they have callback methods which are automatically executed on the EDT and some other magic which make them easy to use with Swing. To make all this easier to understand you need to separate your server and client into separate applications. – Jasper Siepkes May 14 '12 at 21:29
  • @JasperSiepkes I am programming my server and client as separate applications. I'm just having a really hard time getting the server to interact with swing. So you are saying, I DONT need to run my servers accept() on a worker thread, I can just run it on a normal thread so I won't have to have a return? – cgasser May 14 '12 at 21:33
  • It is really unusual for servers to have a GUI at all. I'm having a hard time understanding what this question is all about. You have a method that runs forever and you're complaining that it never returns; you think it runs in the EDT when it doesn't, unless you make it; you're 'having a really hard time' with something else. I suggest you start again and ask a question that can be answered. – user207421 May 14 '12 at 22:33
  • I was just confused with the EDT and what I needed to do concerning the accept() method. I understand now though. Thanks. – cgasser May 14 '12 at 22:39

1 Answers1

2

From Java Tutorials

Server

public class Server {

    public static void main(String[] args) {
        ServerSocket server = new ServerSocket(4444);

        while(true) {
            new ServerThread(server.accept()).start();
        }
    }
}

Server Thread

public class ServerThread implements Runnable {

    private InputStream in;
    private OutputStream out;

    public ServerThread(Socket client) {
        in = client.getInputStream();
        out = client.getOutputStream();
    }

    public void run() {
        // do your socket things 
    }
}
mastaH
  • 1,234
  • 3
  • 15
  • 30