1

Edit: I solved my Problem:

while(!finish.equals("readline")){
    publish(finish);
    finish = Main.in.readLine();
}

has to be changed to:

while(true){
    publish(finish);
    finish = Main.in.readLine();
}

The old Question:

I am writing a chat application in Java, i have made a simple Gui and it is working fine. But now i have rewritten the part of collecting Chat messages to be thread-safe. On login, the server is pushing all messages aready in chat to the client, this works well. After this moment, the GUI keeps responding, i can send commands and they get to the server but the process-method does not get called, so there is nothing returned. What am i doing wrong?

Here is the code i am talking about:

package Client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.List;

import javax.swing.SwingWorker;

public class ChatReceiver extends SwingWorker<Void, String> {
    @Override
    protected Void doInBackground() {
        try {
            Main.echoSocket = new Socket(Main.ip, 4444);
            Main.out = new PrintWriter(Main.echoSocket.getOutputStream(), true);
            Main.in = new BufferedReader(new InputStreamReader(
                    Main.echoSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host.");
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for "
                    + "the connection to: localhost.");
        }
        publish("Sending Login-Request...");
        Main.out.println("login");
        try {
            String text = Main.in.readLine();
            String status = Main.in.readLine();
            publish("Receiving: " + text + " " + status);
            if(status.equals("readline") && text.equals("ready")){
                String finish = "logging in...";
                Main.out.println(Main.name + " SZUTKEY");
                while(!finish.equals("readline")){
                    publish(finish);
                    finish = Main.in.readLine();
                }
            }else{
                throw new RuntimeException("Fuck it login died!");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void process(List<String> chats) {
        Main.printTest("xxx");
        for(String s : chats.toArray(new String[0])){
            Main.printTest("called");
            Main.printTest(s);
        }
        Main.textField.validate();
        Main.textField.repaint();
    }
}

this gets called in my Gui:

    loginAction  = new AbstractAction("Login") {

        /**
         * 
         */
        private static final long serialVersionUID = -3279591081543889275L;

        @Override
        public void actionPerformed( ActionEvent arg0 ) {
            name = JOptionPane.showInputDialog("Please input your Chatname");
            ip = JOptionPane.showInputDialog("Please input the Chatserver-IP", "localhost");
            (chat = new ChatReceiver()).execute();
        }
    };
reggaemuffin
  • 1,188
  • 2
  • 11
  • 26
  • So using debug println statements or a debugger, or (best of all) logging, what exactly gets called and what doesn't? Also an unrelated question: does your Main have several static variables? If so, you'll want to fix that. – Hovercraft Full Of Eels Nov 20 '12 at 22:08
  • And just what is this Main class? Can you explain what this code is trying to do? – Hovercraft Full Of Eels Nov 20 '12 at 22:21
  • Are you certain that those `readLine` calls are non-blocking ? Perhaps your client is waiting for the server to send a newline character, which would block your `doInBackground` method and avoid that updates are pushed to the `process` method – Robin Nov 20 '12 at 23:02

1 Answers1

2
Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Thanks for your comment, actually, i don't want the worker to call anything in done() because it will never be done. But i think, that could be the problem in my code. I will try something and then give you all an update! – reggaemuffin Nov 21 '12 at 15:15
  • then usage of `SwingWorker` is wrong decision, use `Runnable#Thread` instead, there you can control flow e.i., `SwingWorker` is designated to runce one time, hmmm there could be another option, use [Executor & SwingWorker](http://stackoverflow.com/a/6186188/714968), but `Runnable#Thread` is clear, more confortable and managable, output from [Runnable#Thread must be wrapped into invokeLater()](http://stackoverflow.com/a/6060678/714968) – mKorbel Nov 21 '12 at 16:24