0

I wrote this simple multi threaded chatroom, and I am trying to send the client/server output to GUI to display it in chatroom text area but I get null pointer exception at the following line:

output.write(line + "\n");

here is the full code for GUI:

import java.awt.*;
import javax.swing.*;
import javax.swing.JTextField;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import javax.swing.JButton; 
import java.io.Writer;


public class GUI {

    private JFrame frame;
    private JButton btnSend, btnConnect;
    private JTextArea txtChat;
    private JTextField fldText, fldName;
    private JList clientList;
    private DefaultListModel listModel;
    private JScrollPane sc, scClients;
    private JPanel jpS2All, jpS2Client, jpS2Text;
    private String Name;
    private JLabel lblErr;
    private Writer output;

    public GUI(String Name, Writer output) {
        this.Name = Name;
        this.output = output;
    }

    public GUI() {

    }


    class handler implements ActionListener, MouseListener {

        handler(String Name) {

        }

        handler() {

        }

        @Override
        public void actionPerformed(ActionEvent e) {


            clients();                 //it seems this line made the error because it creates the 
            listModel.addElement(Name);//gui and sends the output to textSend actionlistener
                                       //to display it in gui
                                       //while the output is empty, right?  
                                       //is there any way to handle this?

        }

        @Override
        public void mouseClicked(MouseEvent e) {
            fldName.setText("");
        }

        @Override
        public void mousePressed(MouseEvent e) {
        }

        @Override
        public void mouseReleased(MouseEvent e) {
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }

    } //end of handler

    class textSend implements ActionListener {

        textSend(String Name, Writer output) {

        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String line = fldText.getText();
            try {
                output.write(line + "\n");             // the null exception error shows the
                output.flush();                        // error source at this line!
            } catch (IOException ioe) {
                txtChat.append("Other party hung up!");
            }
            String contenet = Name + ":" + output;
            txtChat.append(contenet);
            fldText.setText("");
        }

    }//end of textSend

    public void creatServer() {

        frame = new JFrame("enter");
        frame.setBounds(50, 50, 300, 200);
        btnConnect = new JButton("connect");
        lblErr = new JLabel();
        lblErr.setText("");
        frame.add(btnConnect, BorderLayout.EAST);
        fldName = new JTextField();
        fldName.setText("enter your name");
        fldName.addMouseListener(new handler());

        btnConnect.addActionListener(new handler(getName()));

        frame.add(fldName, BorderLayout.CENTER);
        frame.setVisible(true);

    }


    public void clients() {    //to create the chatroom GUI
        frame = new JFrame("friends");
        frame.setBounds(100, 100, 400, 400);
        jpS2All = new JPanel();
        txtChat = new JTextArea();
        txtChat.setRows(25);
        txtChat.setColumns(25);
        txtChat.setEditable(false);

        sc = new JScrollPane(txtChat);
        jpS2All.add(sc);
        frame.add(jpS2All, BorderLayout.WEST);
        jpS2Text = new JPanel();

        ////////////////////////
        fldText = new JTextField();
        fldText.setColumns(34);
        fldText.setHorizontalAlignment(JTextField.RIGHT);
        fldText.addActionListener(new textSend(getName(), output));
        jpS2Text.add(fldText);
        frame.add(jpS2Text, BorderLayout.SOUTH);

        /////////
        jpS2Client = new JPanel();

        listModel = new DefaultListModel();
        clientList = new JList(listModel);
        clientList.setFixedCellHeight(14);
        clientList.setFixedCellWidth(100);
        scClients = new JScrollPane(clientList);

        frame.add(jpS2Client.add(scClients), BorderLayout.EAST);
        /////////
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.pack();

    }//end of clients

    public String getName() {
        Name = fldName.getText();
        return Name;
    }

    public void appendText(final String message) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                txtChat.append(message);
            }
        });
    }
}

server code:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class server {

    public void start() throws IOException {
        ServerSocket serverSocket = new ServerSocket(1234);
        while (true) {
            Socket socket = serverSocket.accept();
            ClientThread t = new ClientThread(socket);
            t.start();
        }
    }

    public static void main(String[] args) throws IOException {
        server server = new server();
        server.start();

    }

    class ClientThread extends Thread {

        Socket socket;
        InputStream sInput;
        OutputStream sOutput;
        GUI gui = new GUI();
        String Name;

        ClientThread(Socket socket) {
            this.socket = socket;

        }

        @Override
        public void run() {
            try {
                BufferedReader sInput
                        = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                Writer sOutput = new OutputStreamWriter(socket.getOutputStream());
                Name = gui.getName();
                gui = new GUI(Name, sOutput);

                try {
                    String line;
                    while ((line = sInput.readLine()) != null) {
                        gui.appendText(line);
                    }
                } catch (IOException ex) {
                    Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex);
                }

            } catch (IOException e) {
            }
        }
    }
}

client side:

import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class client {

    private Socket s;
    private String Name;
    private GUI gui;
    private Writer output;
    private BufferedReader input;

    public void start() {

        try {
            s = new Socket("127.0.0.1", 1234);
        } catch (IOException ex) {

        }
        try {
            input = new BufferedReader(new InputStreamReader(s.getInputStream()));
            output = new OutputStreamWriter(s.getOutputStream());
        } catch (IOException eIO) {

        }
        Name = gui.getName();
        new GUI(Name, output);
        new ListenFromServer().start();

    }

    public static void main(String[] args) {
        client cl = new client();
        GUI gui = new GUI();
        gui.creatServer();
    }

    class ListenFromServer extends Thread {

        public void run() {
            try {
                String line;
                while ((line = input.readLine()) != null) {
                    gui.appendText(line);
                }
            } catch (IOException ex) {
                Logger.getLogger(client.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

    }

}

I know my question is a bit cumbersome but I really appreciate to help me handle this issue!

Masoud
  • 25
  • 6
  • In your default constructor `GUI gui = new GUI();` you don't ever initialize `output` and therefore it is always `null` – chancea Dec 26 '14 at 16:56
  • http://stackoverflow.com/questions/218384/what-is-a-null-pointer-exception-and-how-do-i-fix-it – markspace Dec 26 '14 at 16:56
  • also consider using `Anonymous` classes to define your action listeners...it cuts down on a lot of code – chancea Dec 26 '14 at 17:01
  • you mean the gui at the client thread class in the server side? and the gui at the main method in the client side? – Masoud Dec 26 '14 at 17:20

2 Answers2

2

I am looking at your code and it is obvious that output is null when you attempt output.write(line + "\n"); Therefore I went and looked for the possible path of execution that could leave output un-initialized. This is where debugging comes in very handy.

Here is your execution path:

In your main method of client you create a new GUI and then call gui.creatServer();

public static void main(String[] args) {
    client cl = new client();
    GUI gui = new GUI();
    gui.creatServer();
}

output has not been assigned and is still null

in the creatServer(); method you have this line:

    fldName.addMouseListener(new handler());

which the actionPerformed method of handler calls the clients(); method which has the line:

fldText.addActionListener(new textSend(getName(), output));

note output is still null

(now your textSend class doesn't even do anything inside the constructor but that aside even if it did you are still using the output variable from the GUI class)

you have the actionPerformed method in the textSend class that has the line:

output.write(line + "\n");

Without ever initializing output it is still null, which gives you the NullPointer

Please see What is a NullPointerException, and how do I fix it? as @markspace linked in the comments. In addition you should really learn how to debug small programs.

See the following links:

http://ericlippert.com/2014/03/05/how-to-debug-small-programs/ http://blogs.msdn.com/b/smallbasic/archive/2012/10/09/how-to-debug-small-basic-programs.aspx

Again in addition, consider using Anonymous classes to ease up on those lines of code, which also makes the code easier to debug and more readable.

One last thought, remember to use standard Naming Conventions for the language you are using. your code currently has a lot of incorrect lowercase classes and some uppercase methods/properties.

Community
  • 1
  • 1
chancea
  • 5,858
  • 3
  • 29
  • 39
1

the error message shows that one of the variable used in the expression was null. This may be either output or line.

As chancea already mentioned, you are calling the GUI() constructor with no arguments, so the output field is not initialized. You should remove the constructor with no arguments when you have no way to initialize the output field in it and only leave the one with arguments.

P.J.Meisch
  • 18,013
  • 6
  • 50
  • 66