tags:

views:

221

answers:

3

Hi, i have asked this question 2 days before but I can not edit that(I don't know why)also i have changed some part of my classes.also I have checked it a lot but really I don't know that why it returns null value(on the console is written :Client says: null ),please help me.

at first i get the text from a text area which get text from client and then i will set it to my text area which is the output(like chat frame in Yahoo Messenger) and then i will send that text to my MainClient class.

my send button action performed in my chat frame:(I have tested the String text in the chat frame and it wasn't null)

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

    submit();
    clear();
} 

  private void submit() {




    String text = jTextArea1.getText();


    jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
    MainClient.setText(client.getCurrentName() + " : " + text + "\n");
}

my MainClient class:(a part of that)

private static String text;

public static String getText() {
    return text;
}

public static void setText(String text) {
    MainClient.text = text;
}

static boolean closed = false;

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    String teXt = getText();
    try {


        os = new PrintWriter(c.getOutputStream(), true);


        is = new BufferedReader(new InputStreamReader(c.getInputStream()));
    } catch (IOException ex) {
        Logger.getLogger(MainClient.class.getName()).log(Level.SEVERE, null, ex);
    }


    if (c != null && is != null && os != null) {

        try {
            os.println(teXt);//send data over socket.
            String line = is.readLine();//recieve text from server.

            System.out.println("Text received: " + line);


            c.close();
        } catch (IOException ex) {
            System.err.println("read Failed");
       }
    }
}}

my MainServer class:(a part of that)

    try {
        BufferedReader streamIn = new BufferedReader(new InputStreamReader(client.getInputStream()));

        boolean done = false;
        String line =null;
        while (!done ) {

            line = streamIn.readLine();
            if (line.equalsIgnoreCase("bye")) {
                done = true;
            } else {
                System.out.println("Client says: " + line);
            }
        }

        streamIn.close();
        client.close();
        server.close();
    } catch (IOException e) {
        System.out.println("IO Error in streams " + e);
    }
}}

At first I will run the MainServer and then I will run the MainClient(which will show the chat frame).

EDIT:please start reading from this part: these are two classes ,one for gui and the other for client.(network) it returns nothing on the console for server so it will return nothing to the client.please help me thanks. my GUI class:(a part of that) (like a chat frame which by clicking on the Send button .I will send something for the server)

my gui class(chat frame) a part of that:

private void SendActionPerformed(java.awt.event.ActionEvent evt) {                                         
setButtonIsSelected(true);
submit();
clear();
} 
 private void submit() {




String text = jTextArea1.getText();


jTextArea2.append(client.getCurrentName() + " : " + text + "\n");
MainClient.setText(client.getCurrentName() + " : " + text + "\n");
}

private static boolean buttonIsSelected = false ;

public static boolean isButtonIsSelected() {
    return buttonIsSelected;
}

public static void setButtonIsSelected(boolean buttonIsSelected) {
    ChatFrame.buttonIsSelected = buttonIsSelected;
}

my MainClient class:(a part of that)

show a chat frame.

if ( ChatFrame.isButtonIsSelected() == true) {

    String teXt = getText();
    System.out.println(teXt);
    os.println(teXt);
    String line;
    line = is.readLine();
    System.out.println("Text received: " + line);

}

at first I will run the client class So the gui class will be run which name is chat Frame.

+1  A: 

It seems your main client is connecting to the server and sending text right on startup, not when someone enters something. So variable text is null.

You should send text over the wire when the user presses the button and receive lines from server always. So you should dedicate a thread (the main thread is ok) to read from server and nothing more.

Of course, if you use the main thread to receive server responses you have to be careful to update your UI because you cannot do it from any thread. In Swing you have to call a special method (SwingUtilities#invokeLater if I remember well) but in AWT I don't know.

Hope it helps. Maybe I'm not getting the correct point after all! :D

helios
Johanna
Or I'm missing something or you are missing something (about how it works). What I'm saying is: your MAIN method, that STARTS when you run your client program is connecting to the server and sending whatever is in MainClient.text field right away. In a matter of miliseconds. So you don't have the change to enter some text, click your button and populate the variable. YOU MUST make your "send text to the server" thing to run when you click the button. So don't put in the main method!!!
helios
Think in your music system. It's like it would want to play a CD right when you press the power button, instead of doing it when you insert the CD and press play.
helios
I have tried what you told and I called the the other method of MainClient in the chat frame (which get text from client and send it to the server),when the client click on the send button,but suddenly my frame will hang(like when i click on the send button nothing will happen!! )
Johanna
Hi, I have edited my post .but now it will return nothing.would you please help me??thanks
Johanna
Sorry, I was unavailable. Do what Adamsky says. Flush force the output stream to send whatever you told it to write (avoids buffering), so then your final "\n" will arrive and the line will be processed.
helios
A: 

A trivial solution could be, that your teXt variable is null or empty at the time you send it to the socket. Please insert a System.out.println(teXt) right before your os.println(teXt) call to double check, that you really send something to the client.

Edit

So at last the tricky client/server part is working as it should. I think helios has the right answer in his comments: When you start the client with something like

java -cp <your classpath> your.pckg.here.MainClient

it will immediatly call getText() which returns null because that's how the text field gets initialized. So you assign that null value to teXt and that's what you send.

This code does not react on anything you do or change in the chat frame.

So the solution is to redesign the flow in the application so that the client really sends something if and only if a button is pressed on the chat frame.

Edit

This is a very simple but working example of a client/server system with a GUI. The code is extremely bad (bad exception handling, client and server won't terminate and have to be 'killed', ugly GUI) but it demonstrates the basics.

Server:

public class Server {

    public static void main(String[] args) throws Exception {
        ServerSocket socket = new ServerSocket(12345);
        while(true) {
            Socket client = socket.accept();
            InputStream in = client.getInputStream();
            int i = in.read();
            while (i != -1) {
                System.out.print((char) i);
                i = in.read();
            }
            System.out.println();
            in.close();
        }
    }

}

The server listens on port 12345 and simply dumps all incoming bytes as characters to the console. It will do this forever (real server can be stopped...)

GUI:

public class GUI extends JFrame {

    public GUI() {
        setSize(100, 100);
        Container contentPane = getContentPane();
        Button button = new Button("Press me");
        button.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                Client.send("Button pressed");          
            }
        });
        contentPane.add(button);
    }

}

Nothing but a titleless frame showing a single button. If you press this button, it will send a text message to the Client class (iaw - call the Client.send method with a static text)

The Client:

public class Client {

    public static void main(String[] args) throws Exception {
        GUI gui = new GUI();
        gui.setVisible(true);
    }

    public static void send(String msg) {
        try {
            Socket socket = new Socket("localhost", 12345);
            OutputStream out = socket.getOutputStream();
            out.write("Hello world".getBytes());
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

The client creates and spawnd the gorgeous GUI. And it contains the send service. Upon request (calling send method) it will establish a connection to the server and send the String as bytes.

So the point is: in order to send something, you have to tell the client to do so. And that's the same on your code: just setting a field on the client class will not trigger the send routine. Implement a send method and call it whenever you have something to send.

(I didn't include packagenames and imports in the examples, but I only used standard java (swing) classes.)

Andreas_D
it will return null.
Johanna
Does it work if you replace os.println(teXt) with os.println("Hello Server")?
Andreas_D
it will return hello server.
Johanna
I get what you mean,but in my client application ,i have two different package ,one is for gui and the other is for network,what should I do now,really I confused.
Johanna
Hi, I have edited my post .but now it will return nothing.would you please help me??thanks
Johanna
@Andreas_D: please read this: http://slash7.com/2006/12/22/vampires/ and stop facilitating such bad behaviour.
Ether
@Ether - *PLONK*
Andreas_D
+1  A: 

Try calling:

os.flush();

on your PrintWriter immediately after calling:

os.println(teXt);

Adamski
it doesn't work.
Johanna