"线程中的异常" AWT-EventQueue-0"显示java.lang.NullPointerException"按下按钮

时间:2016-04-17 20:51:15

标签: java multithreading nullpointerexception actionlistener

我的教授给了我一些示例代码来制作一个基本的聊天程序,其中一个要求就是允许用户通过按下按钮来连接和断开连接。我创建了按钮并为两者添加了动作侦听器,但是当我单击" connect"按钮,我明白了:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Client.actionPerformed(Client.java:64)
    at java.awt.Button.processActionEvent(Unknown Source)
    at java.awt.Button.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

我将错误追溯到此块:

try{
    myOutputStream.reset(); //this is line 64 in the full Java file
    myOutputStream.writeObject(myObject);
    }catch(IOException ioe){
        System.out.println(ioe.getMessage());
    }

我会说我确实对示例代码进行了更改,因此在进行一些编辑之前,上面的部分正在工作,这就是将一个启动连接的代码移动到if语句中检查按钮是否被点击。之前曾经在"客户"构造函数(我的教授为程序做的),并在启动Java程序时立即运行并连接。

完整的客户端类在这里:

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;

//THINGS TO DO:
//1: Add a means to add usernames
//2: Add something that adds a list of users
//3: Button to disconnect/connect
//4: Panel that allows you to draw things


public class Client extends Thread implements ActionListener{

ChatMessage myObject;
boolean sendingdone = false, receivingdone = false;
Scanner scan;
Socket socketToServer;
ObjectOutputStream myOutputStream;
ObjectInputStream myInputStream;
Button connect,disconnect;
Frame f;
TextField tf;
TextArea ta;

public Client(){    

    f = new Frame();
    f.setSize(300,400);
    f.setTitle("Chat Client");
    f.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent we){
            System.exit(0);
        }
    });
    tf = new TextField();
    tf.addActionListener(this);
    f.add(tf, BorderLayout.NORTH);
    ta = new TextArea();
    f.add(ta, BorderLayout.CENTER);

    /////////////////////////
    /*
    try{
    socketToServer = new Socket("127.0.0.1", 4000);

    myOutputStream = new ObjectOutputStream(socketToServer.getOutputStream());

    myInputStream = new ObjectInputStream(socketToServer.getInputStream());
    start();

    }
    catch(Exception e){
        System.out.println(e.getMessage()); 
    }
     */this is the original spot

    Panel b = new Panel();

    connect = new Button("Connect");
    disconnect = new Button("Disconnect");
    connect.addActionListener(this);
    disconnect.addActionListener(this);


    b.add(connect);
    b.add(disconnect);
    f.add(b, BorderLayout.SOUTH);

    f.setVisible(true);
}
public void actionPerformed(ActionEvent ae){
    myObject = new ChatMessage();
    myObject.setMessage(tf.getText());
    tf.setText("");
    try{
        myOutputStream.reset();
        myOutputStream.writeObject(myObject);
    }catch(IOException ioe){
        System.out.println(ioe.getMessage());
    }

    if (ae.getSource() == connect){
        try{
            socketToServer = new Socket("127.0.0.1", 4000);

            myOutputStream =
                new ObjectOutputStream(socketToServer.getOutputStream());

            myInputStream =
                new ObjectInputStream(socketToServer.getInputStream());
            start();


        }
        catch(Exception e){
            System.out.println(e.getMessage()); 
        }
    }
}   



public void run(){
    System.out.println("Listening for messages from server . . . ");
    try{
        while(!receivingdone){
            myObject = (ChatMessage)myInputStream.readObject();
            ta.append(myObject.getMessage() + "\n");
        }
    }catch(IOException ioe){
        System.out.println("IOE: " + ioe.getMessage());
    }catch(ClassNotFoundException cnf){
        System.out.println(cnf.getMessage());
    }
}

public static void main(String[] arg){

    Client c = new Client();

}
}

我认为您还需要这两个Java类,ChatServer,它必须运行,客户端必须连接到ChatMessage,以及客户端用来创建消息的内容:

import java.io.*;
import java.net.*;
import java.util.*;

public class ChatServer{
   public static void main(String[] args ) 
   {  
      ArrayList<ChatHandler> AllHandlers = new ArrayList<ChatHandler>();

      try 
      {  ServerSocket s = new ServerSocket(4000);

         for (;;)
         {  Socket incoming = s.accept( );
            new ChatHandler(incoming, AllHandlers).start();
         }   
      }
      catch (Exception e) 
      {  System.out.println(e);
      } 
   } 
}

class ChatHandler extends Thread
{  public ChatHandler(Socket i, ArrayList<ChatHandler> h) 
   { 
        incoming = i;
        handlers = h;
        handlers.add(this);
        try{
            in = new ObjectInputStream(incoming.getInputStream());
            out = new ObjectOutputStream(incoming.getOutputStream());
        }catch(IOException ioe){
                System.out.println("Could not create streams.");
        }
   }
    public synchronized void broadcast(){

        ChatHandler left = null;
        for(ChatHandler handler : handlers){
            ChatMessage cm = new ChatMessage();
            cm.setMessage(myObject.getMessage());
            try{
                handler.out.writeObject(cm);
                System.out.println("Writing to handler outputstream: " + cm.getMessage());
            }catch(IOException ioe){
                //one of the other handlers hung up
                left = handler; // remove that handler from the arraylist
            }
        }
        handlers.remove(left);

        if(myObject.getMessage().equals("bye")){ // my client wants to leave
            done = true;    
            handlers.remove(this);
            System.out.println("Removed handler. Number of handlers: " + handlers.size());
        }
        System.out.println("Number of handlers: " + handlers.size());
   }

   public void run()
   {  
        try{    
            while(!done){
                myObject = (ChatMessage)in.readObject();
                System.out.println("Message read: " + myObject.getMessage());
                broadcast();
            }               
        } catch (IOException e){  
            if(e.getMessage().equals("Connection reset")){
                System.out.println("A client terminated its connection.");
            }else{
                System.out.println("Problem receiving: " + e.getMessage());
            }
        }catch(ClassNotFoundException cnfe){
            System.out.println(cnfe.getMessage());
        }finally{
            handlers.remove(this);
        }
   }

   ChatMessage myObject = null;
   private Socket incoming;

   boolean done = false;
   ArrayList<ChatHandler> handlers;

   ObjectOutputStream out;
   ObjectInputStream in;
}

(我没有对这两个方面做过任何改动)

import java.io.*;

public class ChatMessage implements Serializable{
    public String name;
    public String message;

    public ChatMessage(){}
    public ChatMessage(String name, String message){
        setName(name);
        setMessage(message);
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    public void setMessage(String message){
        this.message = message;
    }
    public String getMessage(){
        return message;
    }
}

1 个答案:

答案 0 :(得分:1)

永远不会初始化myOutputStream。你评论了它应该发生的部分。